diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-10-17 17:14:42 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-17 17:14:42 +0800 |
commit | 21ab1ac7be6e88b88f75b10eb83d409bc0322254 (patch) | |
tree | 839134b4cf502b55da5b1707d1279bf58eb368a4 | |
parent | 6f1df59f8b32d30d5a7a0d9449f2dca698a8ac39 (diff) | |
download | dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar.gz dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar.bz2 dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar.lz dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar.xz dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.tar.zst dexon-consensus-21ab1ac7be6e88b88f75b10eb83d409bc0322254.zip |
core: Rebroadcast agreement and randomness result. (#218)
-rw-r--r-- | core/configuration-chain.go | 30 | ||||
-rw-r--r-- | core/consensus.go | 46 | ||||
-rw-r--r-- | core/types/block-randomness.go | 3 |
3 files changed, 49 insertions, 30 deletions
diff --git a/core/configuration-chain.go b/core/configuration-chain.go index 5cedcf4..c40d788 100644 --- a/core/configuration-chain.go +++ b/core/configuration-chain.go @@ -39,16 +39,17 @@ var ( ) type configurationChain struct { - ID types.NodeID - recv dkgReceiver - gov Governance - dkg *dkgProtocol - dkgLock sync.RWMutex - dkgSigner map[uint64]*dkgShareSecret - gpk map[uint64]*DKGGroupPublicKey - dkgResult sync.RWMutex - tsig map[common.Hash]*tsigProtocol - tsigReady *sync.Cond + ID types.NodeID + recv dkgReceiver + gov Governance + dkg *dkgProtocol + dkgLock sync.RWMutex + dkgSigner map[uint64]*dkgShareSecret + gpk map[uint64]*DKGGroupPublicKey + dkgResult sync.RWMutex + tsig map[common.Hash]*tsigProtocol + tsigTouched map[common.Hash]struct{} + tsigReady *sync.Cond // TODO(jimmy-dexon): add timeout to pending psig. pendingPsig map[common.Hash][]*types.DKGPartialSignature prevHash common.Hash @@ -182,6 +183,14 @@ func (cc *configurationChain) preparePartialSignature( }, nil } +func (cc *configurationChain) touchTSigHash(hash common.Hash) (first bool) { + cc.tsigReady.L.Lock() + defer cc.tsigReady.L.Unlock() + _, exist := cc.tsigTouched[hash] + cc.tsigTouched[hash] = struct{}{} + return !exist +} + func (cc *configurationChain) runTSig( round uint64, hash common.Hash) ( crypto.Signature, error) { @@ -218,6 +227,7 @@ func (cc *configurationChain) runTSig( cc.tsigReady.Wait() } delete(cc.tsig, hash) + delete(cc.tsigTouched, hash) if err != nil { return crypto.Signature{}, err } diff --git a/core/consensus.go b/core/consensus.go index 4929d0b..186d769 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -105,7 +105,6 @@ func (recv *consensusBAReceiver) ConfirmBlock( } recv.consensus.network.BroadcastAgreementResult(&types.AgreementResult{ BlockHash: hash, - Round: recv.round, Position: block.Position, Votes: voteList, }) @@ -574,20 +573,13 @@ func (con *Consensus) ProcessVote(vote *types.Vote) (err error) { // ProcessAgreementResult processes the randomness request. func (con *Consensus) ProcessAgreementResult( rand *types.AgreementResult) error { - if rand.Round == 0 { + if rand.Position.Round == 0 { return nil } if !con.ccModule.blockRegistered(rand.BlockHash) { return nil } - if DiffUint64(con.round, rand.Round) > 1 { - return nil - } - dkgSet, err := con.nodeSetCache.GetDKGSet(rand.Round) - if err != nil { - return err - } - if _, exist := dkgSet[con.ID]; !exist { + if DiffUint64(con.round, rand.Position.Round) > 1 { return nil } if len(rand.Votes) <= int(con.currentConfig.NotarySetSize/3*2) { @@ -597,7 +589,7 @@ func (con *Consensus) ProcessAgreementResult( return ErrIncorrectAgreementResultPosition } notarySet, err := con.nodeSetCache.GetNotarySet( - rand.Round, rand.Position.ChainID) + rand.Position.Round, rand.Position.ChainID) if err != nil { return err } @@ -607,13 +599,25 @@ func (con *Consensus) ProcessAgreementResult( } ok, err := verifyVoteSignature(&vote) if err != nil { - return nil + return err } if !ok { return ErrIncorrectVoteSignature } } - psig, err := con.cfgModule.preparePartialSignature(rand.Round, rand.BlockHash) + // Sanity check done. + if !con.cfgModule.touchTSigHash(rand.BlockHash) { + return nil + } + con.network.BroadcastAgreementResult(rand) + dkgSet, err := con.nodeSetCache.GetDKGSet(rand.Position.Round) + if err != nil { + return err + } + if _, exist := dkgSet[con.ID]; !exist { + return nil + } + psig, err := con.cfgModule.preparePartialSignature(rand.Position.Round, rand.BlockHash) if err != nil { return err } @@ -625,7 +629,7 @@ func (con *Consensus) ProcessAgreementResult( } con.network.BroadcastDKGPartialSignature(psig) go func() { - tsig, err := con.cfgModule.runTSig(rand.Round, rand.BlockHash) + tsig, err := con.cfgModule.runTSig(rand.Position.Round, rand.BlockHash) if err != nil { if err != ErrTSigAlreadyRunning { log.Println(err) @@ -634,7 +638,7 @@ func (con *Consensus) ProcessAgreementResult( } result := &types.BlockRandomnessResult{ BlockHash: rand.BlockHash, - Round: rand.Round, + Position: rand.Position, Randomness: tsig.Signature, } if err := con.ProcessBlockRandomnessResult(result); err != nil { @@ -649,14 +653,14 @@ func (con *Consensus) ProcessAgreementResult( // ProcessBlockRandomnessResult processes the randomness result. func (con *Consensus) ProcessBlockRandomnessResult( rand *types.BlockRandomnessResult) error { - if rand.Round == 0 { + if rand.Position.Round == 0 { return nil } if !con.ccModule.blockRegistered(rand.BlockHash) { return nil } // TODO(jimmy-dexon): reuse the GPK. - round := rand.Round + round := rand.Position.Round gpk, err := NewDKGGroupPublicKey(round, con.gov.DKGMasterPublicKeys(round), con.gov.DKGComplaints(round), @@ -668,7 +672,13 @@ func (con *Consensus) ProcessBlockRandomnessResult( rand.BlockHash, crypto.Signature{Signature: rand.Randomness}) { return ErrIncorrectBlockRandomnessResult } - return con.ccModule.processBlockRandomnessResult(rand) + con.network.BroadcastRandomnessResult(rand) + if err := con.ccModule.processBlockRandomnessResult(rand); err != nil { + if err != ErrBlockNotRegistered { + return err + } + } + return nil } // preProcessBlock performs Byzantine Agreement on the block. diff --git a/core/types/block-randomness.go b/core/types/block-randomness.go index 896904a..b101e22 100644 --- a/core/types/block-randomness.go +++ b/core/types/block-randomness.go @@ -24,7 +24,6 @@ import ( // AgreementResult describes an agremeent result. type AgreementResult struct { BlockHash common.Hash `json:"block_hash"` - Round uint64 `json:"round"` Position Position `json:"position"` Votes []Vote `json:"votes"` } @@ -32,6 +31,6 @@ type AgreementResult struct { // BlockRandomnessResult describes a block randomness result type BlockRandomnessResult struct { BlockHash common.Hash `json:"block_hash"` - Round uint64 `json:"round"` + Position Position `json:"position"` Randomness []byte `json:"randomness"` } |