diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-10-08 11:17:23 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-08 11:17:23 +0800 |
commit | 02f8296bf9ec5069ff26e39216c7e7af7c6e9567 (patch) | |
tree | ae2727224e49df9078d8ca2a6c772e0f3b3bc6bf | |
parent | b74b8c092dcc10a7792d92c64c6dc22d94edb295 (diff) | |
download | dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar.gz dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar.bz2 dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar.lz dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar.xz dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.tar.zst dexon-consensus-02f8296bf9ec5069ff26e39216c7e7af7c6e9567.zip |
core: Block randomness generation. (#178)
-rw-r--r-- | core/agreement-state_test.go | 3 | ||||
-rw-r--r-- | core/agreement.go | 5 | ||||
-rw-r--r-- | core/agreement_test.go | 3 | ||||
-rw-r--r-- | core/consensus.go | 69 |
4 files changed, 73 insertions, 7 deletions
diff --git a/core/agreement-state_test.go b/core/agreement-state_test.go index b4619d6..2178b36 100644 --- a/core/agreement-state_test.go +++ b/core/agreement-state_test.go @@ -52,7 +52,8 @@ func (r *agreementStateTestReceiver) ProposeBlock() { r.s.blockChan <- block.Hash } -func (r *agreementStateTestReceiver) ConfirmBlock(block common.Hash) { +func (r *agreementStateTestReceiver) ConfirmBlock(block common.Hash, + _ map[types.NodeID]*types.Vote) { r.s.confirmChan <- block } diff --git a/core/agreement.go b/core/agreement.go index 9a673ad..aa1d1dc 100644 --- a/core/agreement.go +++ b/core/agreement.go @@ -67,7 +67,7 @@ func newVoteListMap() []map[types.NodeID]*types.Vote { type agreementReceiver interface { ProposeVote(vote *types.Vote) ProposeBlock() - ConfirmBlock(common.Hash) + ConfirmBlock(common.Hash, map[types.NodeID]*types.Vote) } type pendingBlock struct { @@ -294,7 +294,8 @@ func (a *agreement) processVote(vote *types.Vote) error { if len(a.data.votes[vote.Period][types.VoteConfirm]) >= a.data.requiredVote { a.hasOutput = true - a.data.recv.ConfirmBlock(vote.BlockHash) + a.data.recv.ConfirmBlock(vote.BlockHash, + a.data.votes[vote.Period][types.VoteConfirm]) } } return true diff --git a/core/agreement_test.go b/core/agreement_test.go index 5a14cda..db5bd42 100644 --- a/core/agreement_test.go +++ b/core/agreement_test.go @@ -41,7 +41,8 @@ func (r *agreementTestReceiver) ProposeBlock() { r.s.blockChan <- block.Hash } -func (r *agreementTestReceiver) ConfirmBlock(block common.Hash) { +func (r *agreementTestReceiver) ConfirmBlock(block common.Hash, + _ map[types.NodeID]*types.Vote) { r.s.confirmChan <- block } diff --git a/core/consensus.go b/core/consensus.go index c53d151..ae30619 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -50,6 +50,8 @@ var ( "not enought votes") ErrIncorrectVoteProposer = fmt.Errorf( "incorrect vote proposer") + ErrIncorrectBlockRandomnessResult = fmt.Errorf( + "incorrect block randomness result") ) // consensusBAReceiver implements agreementReceiver. @@ -59,6 +61,7 @@ type consensusBAReceiver struct { agreementModule *agreement chainID uint32 changeNotaryTime time.Time + round uint64 restartNotary chan bool } @@ -86,17 +89,34 @@ func (recv *consensusBAReceiver) ProposeBlock() { recv.consensus.network.BroadcastBlock(block) } -func (recv *consensusBAReceiver) ConfirmBlock(hash common.Hash) { - block, exist := recv.consensus.baModules[recv.chainID].findCandidateBlock(hash) +func (recv *consensusBAReceiver) ConfirmBlock( + hash common.Hash, votes map[types.NodeID]*types.Vote) { + block, exist := recv.consensus.baModules[recv.chainID]. + findCandidateBlock(hash) if !exist { log.Println(ErrUnknownBlockConfirmed, hash) return } + voteList := make([]types.Vote, 0, len(votes)) + for _, vote := range votes { + voteList = append(voteList, *vote) + } + recv.consensus.network.BroadcastRandomnessRequest(&types.AgreementResult{ + BlockHash: hash, + Round: recv.round, + Position: block.Position, + Votes: voteList, + }) if err := recv.consensus.processBlock(block); err != nil { log.Println(err) return } - recv.restartNotary <- block.Timestamp.After(recv.changeNotaryTime) + if block.Timestamp.After(recv.changeNotaryTime) { + recv.round++ + recv.restartNotary <- true + } else { + recv.restartNotary <- false + } } // consensusDKGReceiver implements dkgReceiver. @@ -554,12 +574,55 @@ func (con *Consensus) ProcessAgreementResult( return ErrIncorrectVoteSignature } } + psig, err := con.cfgModule.preparePartialSignature(rand.Round, rand.BlockHash) + if err != nil { + return err + } + if err = con.authModule.SignDKGPartialSignature(psig); err != nil { + return err + } + if err = con.cfgModule.processPartialSignature(psig); err != nil { + return err + } + con.network.BroadcastDKGPartialSignature(psig) + go func() { + tsig, err := con.cfgModule.runTSig(rand.Round, rand.BlockHash) + if err != nil { + if err != ErrTSigAlreadyRunning { + log.Println(err) + } + return + } + result := &types.BlockRandomnessResult{ + BlockHash: rand.BlockHash, + Round: rand.Round, + Randomness: tsig.Signature, + } + if err := con.ProcessBlockRandomnessResult(result); err != nil { + log.Println(err) + return + } + con.network.BroadcastRandomnessResult(result) + }() return nil } // ProcessBlockRandomnessResult processes the randomness result. func (con *Consensus) ProcessBlockRandomnessResult( rand *types.BlockRandomnessResult) error { + // TODO(jimmy-dexon): reuse the GPK. + round := rand.Round + gpk, err := NewDKGGroupPublicKey(round, + con.gov.DKGMasterPublicKeys(round), + con.gov.DKGComplaints(round), + con.gov.Configuration(round).NumDKGSet/3) + if err != nil { + return err + } + if !gpk.VerifySignature( + rand.BlockHash, crypto.Signature{Signature: rand.Randomness}) { + return ErrIncorrectBlockRandomnessResult + } return nil } |