diff options
author | Mission Liao <mission.liao@dexon.org> | 2018-12-25 10:06:35 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:55 +0800 |
commit | 6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9 (patch) | |
tree | a8020f5aace2a3f3ac3de3bcbe98bdc8226245a6 /vendor/github.com | |
parent | b39d0be8e1fd2e870fafd2c23e7d5cb220696a60 (diff) | |
download | dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar.gz dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar.bz2 dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar.lz dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar.xz dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.tar.zst dexon-6aee32cd8c3d7f0c7d99bf1fe4951fdf6c534be9.zip |
vendor: sync DEXON core and fix conflicts/missings (#101)
Merging these commits in DEXON consensus core:
- https://github.com/dexon-foundation/dexon-consensus/commit/dce509a13ef5873b9cae3c1cabdb97e219b6fb7d
- https://github.com/dexon-foundation/dexon-consensus/commit/6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6
- https://github.com/dexon-foundation/dexon-consensus/commit/c1ed57c4abaf1f4758e52f082bb7114ad00c8b39
Diffstat (limited to 'vendor/github.com')
13 files changed, 337 insertions, 284 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go index fb6536463..a9fa21df2 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go @@ -86,7 +86,7 @@ type agreementMgr struct { network Network logger common.Logger cache *utils.NodeSetCache - auth *Authenticator + signer *utils.Signer lattice *Lattice ctx context.Context lastEndTime time.Time @@ -119,7 +119,7 @@ func newAgreementMgr(con *Consensus, initRound uint64, network: con.network, logger: con.logger, cache: con.nodeSetCache, - auth: con.authModule, + signer: con.signer, lattice: con.lattice, ctx: con.ctx, initRound: initRound, @@ -181,7 +181,7 @@ func (mgr *agreementMgr) appendConfig( mgr.con.ID, recv, newLeaderSelector(genValidLeader(mgr), mgr.logger), - mgr.auth) + mgr.signer) // Hacky way to make agreement module self contained. recv.agreementModule = agrModule mgr.baModules = append(mgr.baModules, agrModule) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go index 4fb0deaa8..eead4628a 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go @@ -26,6 +26,7 @@ import ( "github.com/dexon-foundation/dexon-consensus/common" "github.com/dexon-foundation/dexon-consensus/core/types" + "github.com/dexon-foundation/dexon-consensus/core/utils" ) // Errors for agreement module. @@ -112,7 +113,7 @@ type agreement struct { pendingVote []pendingVote candidateBlock map[common.Hash]*types.Block fastForward chan uint64 - authModule *Authenticator + signer *utils.Signer } // newAgreement creates a agreement instance. @@ -120,7 +121,7 @@ func newAgreement( ID types.NodeID, recv agreementReceiver, leader *leaderSelector, - authModule *Authenticator) *agreement { + signer *utils.Signer) *agreement { agreement := &agreement{ data: &agreementData{ recv: recv, @@ -130,7 +131,7 @@ func newAgreement( aID: &atomic.Value{}, candidateBlock: make(map[common.Hash]*types.Block), fastForward: make(chan uint64, 1), - authModule: authModule, + signer: signer, } agreement.stop() return agreement @@ -268,7 +269,7 @@ func (a *agreement) sanityCheck(vote *types.Vote) error { if _, exist := a.notarySet[vote.ProposerID]; !exist { return ErrNotInNotarySet } - ok, err := verifyVoteSignature(vote) + ok, err := utils.VerifyVoteSignature(vote) if err != nil { return err } @@ -299,7 +300,7 @@ func (a *agreement) checkForkVote(vote *types.Vote) error { // prepareVote prepares a vote. func (a *agreement) prepareVote(vote *types.Vote) (err error) { vote.Position = a.agreementID() - err = a.authModule.SignVote(vote) + err = a.signer.SignVote(vote) return } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/authenticator.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/authenticator.go deleted file mode 100644 index 8e57f719f..000000000 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/authenticator.go +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2018 The dexon-consensus Authors -// This file is part of the dexon-consensus library. -// -// The dexon-consensus library is free software: you can redistribute it -// and/or modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The dexon-consensus library is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -// General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the dexon-consensus library. If not, see -// <http://www.gnu.org/licenses/>. - -package core - -import ( - "github.com/dexon-foundation/dexon-consensus/common" - "github.com/dexon-foundation/dexon-consensus/core/crypto" - "github.com/dexon-foundation/dexon-consensus/core/types" - typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg" -) - -// Authenticator verify data owner. -type Authenticator struct { - prvKey crypto.PrivateKey - pubKey crypto.PublicKey - proposerID types.NodeID -} - -// NewAuthenticator constructs an Authenticator instance. -func NewAuthenticator(prvKey crypto.PrivateKey) (auth *Authenticator) { - auth = &Authenticator{ - prvKey: prvKey, - pubKey: prvKey.PublicKey(), - } - auth.proposerID = types.NewNodeID(auth.pubKey) - return -} - -// SignBlock signs a types.Block. -func (au *Authenticator) SignBlock(b *types.Block) (err error) { - b.ProposerID = au.proposerID - b.PayloadHash = crypto.Keccak256Hash(b.Payload) - if b.Hash, err = hashBlock(b); err != nil { - return - } - if b.Signature, err = au.prvKey.Sign(b.Hash); err != nil { - return - } - return -} - -// SignVote signs a types.Vote. -func (au *Authenticator) SignVote(v *types.Vote) (err error) { - v.ProposerID = au.proposerID - v.Signature, err = au.prvKey.Sign(hashVote(v)) - return -} - -// SignCRS signs CRS signature of types.Block. -func (au *Authenticator) SignCRS(b *types.Block, crs common.Hash) (err error) { - if b.ProposerID != au.proposerID { - err = ErrInvalidProposerID - return - } - b.CRSSignature, err = au.prvKey.Sign(hashCRS(b, crs)) - return -} - -// SignDKGComplaint signs a DKG complaint. -func (au *Authenticator) SignDKGComplaint( - complaint *typesDKG.Complaint) (err error) { - complaint.ProposerID = au.proposerID - complaint.Signature, err = au.prvKey.Sign(hashDKGComplaint(complaint)) - return -} - -// SignDKGMasterPublicKey signs a DKG master public key. -func (au *Authenticator) SignDKGMasterPublicKey( - mpk *typesDKG.MasterPublicKey) (err error) { - mpk.ProposerID = au.proposerID - mpk.Signature, err = au.prvKey.Sign(hashDKGMasterPublicKey(mpk)) - return -} - -// SignDKGPrivateShare signs a DKG private share. -func (au *Authenticator) SignDKGPrivateShare( - prvShare *typesDKG.PrivateShare) (err error) { - prvShare.ProposerID = au.proposerID - prvShare.Signature, err = au.prvKey.Sign(hashDKGPrivateShare(prvShare)) - return -} - -// SignDKGPartialSignature signs a DKG partial signature. -func (au *Authenticator) SignDKGPartialSignature( - pSig *typesDKG.PartialSignature) (err error) { - pSig.ProposerID = au.proposerID - pSig.Signature, err = au.prvKey.Sign(hashDKGPartialSignature(pSig)) - return -} - -// SignDKGMPKReady signs a DKG ready message. -func (au *Authenticator) SignDKGMPKReady( - ready *typesDKG.MPKReady) (err error) { - ready.ProposerID = au.proposerID - ready.Signature, err = au.prvKey.Sign(hashDKGMPKReady(ready)) - return -} - -// SignDKGFinalize signs a DKG finalize message. -func (au *Authenticator) SignDKGFinalize( - final *typesDKG.Finalize) (err error) { - final.ProposerID = au.proposerID - final.Signature, err = au.prvKey.Sign(hashDKGFinalize(final)) - return -} - -// VerifyBlock verifies the signature of types.Block. -func (au *Authenticator) VerifyBlock(b *types.Block) (err error) { - payloadHash := crypto.Keccak256Hash(b.Payload) - if payloadHash != b.PayloadHash { - err = ErrIncorrectHash - return - } - hash, err := hashBlock(b) - if err != nil { - return - } - if hash != b.Hash { - err = ErrIncorrectHash - return - } - pubKey, err := crypto.SigToPub(b.Hash, b.Signature) - if err != nil { - return - } - if !b.ProposerID.Equal(types.NewNodeID(pubKey)) { - err = ErrIncorrectSignature - return - } - return -} - -// VerifyVote verifies the signature of types.Vote. -func (au *Authenticator) VerifyVote(v *types.Vote) (bool, error) { - return verifyVoteSignature(v) -} - -// VerifyCRS verifies the CRS signature of types.Block. -func (au *Authenticator) VerifyCRS(b *types.Block, crs common.Hash) (bool, error) { - return verifyCRSSignature(b, crs) -} diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go index d341cb524..ad24e446d 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go @@ -417,7 +417,7 @@ func (cc *configurationChain) processPrivateShare( } if !cc.mpkReady { // TODO(jimmy-dexon): remove duplicated signature check in dkg module. - ok, err := verifyDKGPrivateShareSignature(prvShare) + ok, err := utils.VerifyDKGPrivateShareSignature(prvShare) if err != nil { return err } @@ -435,7 +435,7 @@ func (cc *configurationChain) processPartialSignature( cc.tsigReady.L.Lock() defer cc.tsigReady.L.Unlock() if _, exist := cc.tsig[psig.Hash]; !exist { - ok, err := verifyDKGPartialSignatureSignature(psig) + ok, err := utils.VerifyDKGPartialSignatureSignature(psig) if err != nil { return err } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go index e45e4be5a..0d4a38a91 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go @@ -260,7 +260,7 @@ func (recv *consensusBAReceiver) PullBlocks(hashes common.Hashes) { type consensusDKGReceiver struct { ID types.NodeID gov Governance - authModule *Authenticator + signer *utils.Signer nodeSetCache *utils.NodeSetCache cfgModule *configurationChain network Network @@ -270,7 +270,7 @@ type consensusDKGReceiver struct { // ProposeDKGComplaint proposes a DKGComplaint. func (recv *consensusDKGReceiver) ProposeDKGComplaint( complaint *typesDKG.Complaint) { - if err := recv.authModule.SignDKGComplaint(complaint); err != nil { + if err := recv.signer.SignDKGComplaint(complaint); err != nil { recv.logger.Error("Failed to sign DKG complaint", "error", err) return } @@ -282,7 +282,7 @@ func (recv *consensusDKGReceiver) ProposeDKGComplaint( // ProposeDKGMasterPublicKey propose a DKGMasterPublicKey. func (recv *consensusDKGReceiver) ProposeDKGMasterPublicKey( mpk *typesDKG.MasterPublicKey) { - if err := recv.authModule.SignDKGMasterPublicKey(mpk); err != nil { + if err := recv.signer.SignDKGMasterPublicKey(mpk); err != nil { recv.logger.Error("Failed to sign DKG master public key", "error", err) return } @@ -293,7 +293,7 @@ func (recv *consensusDKGReceiver) ProposeDKGMasterPublicKey( // ProposeDKGPrivateShare propose a DKGPrivateShare. func (recv *consensusDKGReceiver) ProposeDKGPrivateShare( prv *typesDKG.PrivateShare) { - if err := recv.authModule.SignDKGPrivateShare(prv); err != nil { + if err := recv.signer.SignDKGPrivateShare(prv); err != nil { recv.logger.Error("Failed to sign DKG private share", "error", err) return } @@ -320,7 +320,7 @@ func (recv *consensusDKGReceiver) ProposeDKGPrivateShare( func (recv *consensusDKGReceiver) ProposeDKGAntiNackComplaint( prv *typesDKG.PrivateShare) { if prv.ProposerID == recv.ID { - if err := recv.authModule.SignDKGPrivateShare(prv); err != nil { + if err := recv.signer.SignDKGPrivateShare(prv); err != nil { recv.logger.Error("Failed sign DKG private share", "error", err) return } @@ -331,7 +331,7 @@ func (recv *consensusDKGReceiver) ProposeDKGAntiNackComplaint( // ProposeDKGMPKReady propose a DKGMPKReady message. func (recv *consensusDKGReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) { - if err := recv.authModule.SignDKGMPKReady(ready); err != nil { + if err := recv.signer.SignDKGMPKReady(ready); err != nil { recv.logger.Error("Failed to sign DKG ready", "error", err) return } @@ -341,7 +341,7 @@ func (recv *consensusDKGReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) { // ProposeDKGFinalize propose a DKGFinalize message. func (recv *consensusDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) { - if err := recv.authModule.SignDKGFinalize(final); err != nil { + if err := recv.signer.SignDKGFinalize(final); err != nil { recv.logger.Error("Failed to sign DKG finalize", "error", err) return } @@ -352,8 +352,8 @@ func (recv *consensusDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) { // Consensus implements DEXON Consensus algorithm. type Consensus struct { // Node Info. - ID types.NodeID - authModule *Authenticator + ID types.NodeID + signer *utils.Signer // BA. baMgr *agreementMgr @@ -399,10 +399,38 @@ func NewConsensus( prv crypto.PrivateKey, logger common.Logger) *Consensus { + return newConsensus(dMoment, app, gov, db, network, prv, logger, true) +} + +// NewConsensusForSimulation creates an instance of Consensus for simulation, +// the only difference with NewConsensus is nonblocking of app. +func NewConsensusForSimulation( + dMoment time.Time, + app Application, + gov Governance, + db db.Database, + network Network, + prv crypto.PrivateKey, + logger common.Logger) *Consensus { + + return newConsensus(dMoment, app, gov, db, network, prv, logger, false) +} + +// newConsensus creates a Consensus instance. +func newConsensus( + dMoment time.Time, + app Application, + gov Governance, + db db.Database, + network Network, + prv crypto.PrivateKey, + logger common.Logger, + usingNonBlocking bool) *Consensus { + // TODO(w): load latest blockHeight from DB, and use config at that height. nodeSetCache := utils.NewNodeSetCache(gov) - // Setup auth module. - authModule := NewAuthenticator(prv) + // Setup signer module. + signer := utils.NewSigner(prv) // Check if the application implement Debug interface. var debugApp Debug if a, ok := app.(Debug); ok { @@ -413,13 +441,13 @@ func NewConsensus( config := utils.GetConfigWithPanic(gov, round, logger) // Init lattice. lattice := NewLattice( - dMoment, round, config, authModule, app, debugApp, db, logger) + dMoment, round, config, signer, app, debugApp, db, logger) // Init configuration chain. ID := types.NewNodeID(prv.PublicKey()) recv := &consensusDKGReceiver{ ID: ID, gov: gov, - authModule: authModule, + signer: signer, nodeSetCache: nodeSetCache, network: network, logger: logger, @@ -432,12 +460,16 @@ func NewConsensus( db, logger) recv.cfgModule = cfgModule + appModule := app + if usingNonBlocking { + appModule = newNonBlocking(app, debugApp) + } // Construct Consensus instance. con := &Consensus{ ID: ID, ccModule: newCompactionChain(gov), lattice: lattice, - app: newNonBlocking(app, debugApp), + app: appModule, debugApp: debugApp, gov: gov, db: db, @@ -447,7 +479,7 @@ func NewConsensus( cfgModule: cfgModule, dMoment: dMoment, nodeSetCache: nodeSetCache, - authModule: authModule, + signer: signer, event: common.NewEvent(), logger: logger, } @@ -479,14 +511,14 @@ func NewConsensusFromSyncer( logger common.Logger) (*Consensus, error) { // Setup the cache for node sets. nodeSetCache := utils.NewNodeSetCache(gov) - // Setup auth module. - authModule := NewAuthenticator(prv) + // Setup signer module. + signer := utils.NewSigner(prv) // Init configuration chain. ID := types.NewNodeID(prv.PublicKey()) recv := &consensusDKGReceiver{ ID: ID, gov: gov, - authModule: authModule, + signer: signer, nodeSetCache: nodeSetCache, network: networkModule, logger: logger, @@ -518,7 +550,7 @@ func NewConsensusFromSyncer( cfgModule: cfgModule, dMoment: initRoundBeginTime, nodeSetCache: nodeSetCache, - authModule: authModule, + signer: signer, event: common.NewEvent(), logger: logger, } @@ -569,7 +601,11 @@ func (con *Consensus) prepare(initBlock *types.Block) error { // Setup lattice module. initPlusOneCfg := utils.GetConfigWithPanic(con.gov, initRound+1, con.logger) if err := con.lattice.AppendConfig(initRound+1, initPlusOneCfg); err != nil { - return err + if err == ErrRoundNotIncreasing { + err = nil + } else { + return err + } } // Register events. dkgSet, err := con.nodeSetCache.GetDKGSet(initRound) @@ -655,7 +691,7 @@ func (con *Consensus) runCRS(round uint64) { round, utils.GetCRSWithPanic(con.gov, round, con.logger)) if err != nil { con.logger.Error("Failed to prepare partial signature", "error", err) - } else if err = con.authModule.SignDKGPartialSignature(psig); err != nil { + } else if err = con.signer.SignDKGPartialSignature(psig); err != nil { con.logger.Error("Failed to sign DKG partial signature", "error", err) } else if err = con.cfgModule.processPartialSignature(psig); err != nil { con.logger.Error("Failed to process partial signature", "error", err) @@ -700,23 +736,37 @@ func (con *Consensus) initialRound( }() }) } + // checkCRS is a generator of checker to check if CRS for that round is + // ready or not. + checkCRS := func(round uint64) func() bool { + return func() bool { + nextCRS := con.gov.CRS(round) + if (nextCRS != common.Hash{}) { + return true + } + con.logger.Info("CRS is not ready yet. Try again later...", + "nodeID", con.ID, + "round", round) + return false + } + } // Initiate BA modules. con.event.RegisterTime( startTime.Add(config.RoundInterval/2+config.LambdaDKG), func(time.Time) { go func(nextRound uint64) { - for (con.gov.CRS(nextRound) == common.Hash{}) { - con.logger.Info("CRS is not ready yet. Try again later...", - "nodeID", con.ID, + if !checkWithCancel( + con.ctx, 500*time.Millisecond, checkCRS(nextRound)) { + con.logger.Info("unable to prepare CRS for baMgr", "round", nextRound) - time.Sleep(500 * time.Millisecond) + return } // Notify BA for new round. nextConfig := utils.GetConfigWithPanic( con.gov, nextRound, con.logger) - con.logger.Debug("Calling Governance.CRS", - "round", nextRound) - nextCRS := utils.GetCRSWithPanic(con.gov, nextRound, con.logger) + nextCRS := utils.GetCRSWithPanic( + con.gov, nextRound, con.logger) + con.logger.Info("appendConfig for baMgr", "round", nextRound) if err := con.baMgr.appendConfig( nextRound, nextConfig, nextCRS); err != nil { panic(err) @@ -729,11 +779,11 @@ func (con *Consensus) initialRound( go func(nextRound uint64) { // Normally, gov.CRS would return non-nil. Use this for in case of // unexpected network fluctuation and ensure the robustness. - for (con.gov.CRS(nextRound) == common.Hash{}) { - con.logger.Info("CRS is not ready yet. Try again later...", - "nodeID", con.ID, + if !checkWithCancel( + con.ctx, 500*time.Millisecond, checkCRS(nextRound)) { + con.logger.Info("unable to prepare CRS for DKG set", "round", nextRound) - time.Sleep(500 * time.Millisecond) + return } nextDkgSet, err := con.nodeSetCache.GetDKGSet(nextRound) if err != nil { @@ -933,7 +983,7 @@ func (con *Consensus) ProcessAgreementResult( if err != nil { return err } - if err = con.authModule.SignDKGPartialSignature(psig); err != nil { + if err = con.signer.SignDKGPartialSignature(psig); err != nil { return err } if err = con.cfgModule.processPartialSignature(psig); err != nil { @@ -1123,7 +1173,7 @@ func (con *Consensus) prepareBlock(b *types.Block, err = ErrCRSNotReady return } - if err = con.authModule.SignCRS(b, crs); err != nil { + if err = con.signer.SignCRS(b, crs); err != nil { return } return diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go index ef12cf992..492271e98 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go @@ -155,7 +155,6 @@ func newDKGProtocol( prvShare, pubShare := dkg.NewPrivateKeyShares(threshold) recv.ProposeDKGMasterPublicKey(&typesDKG.MasterPublicKey{ - ProposerID: ID, Round: round, DKGID: newDKGID(ID), PublicKeyShares: *pubShare, @@ -195,7 +194,6 @@ func (d *dkgProtocol) processMasterPublicKeys( return ErrIDShareNotFound } d.recv.ProposeDKGPrivateShare(&typesDKG.PrivateShare{ - ProposerID: d.ID, ReceiverID: mpk.ProposerID, Round: d.round, PrivateShare: *share, @@ -210,8 +208,7 @@ func (d *dkgProtocol) proposeNackComplaints() { continue } d.recv.ProposeDKGComplaint(&typesDKG.Complaint{ - ProposerID: d.ID, - Round: d.round, + Round: d.round, PrivateShare: typesDKG.PrivateShare{ ProposerID: nID, Round: d.round, @@ -240,7 +237,6 @@ func (d *dkgProtocol) processNackComplaints(complaints []*typesDKG.Complaint) ( continue } d.recv.ProposeDKGAntiNackComplaint(&typesDKG.PrivateShare{ - ProposerID: d.ID, ReceiverID: complaint.ProposerID, Round: d.round, PrivateShare: *share, @@ -267,8 +263,7 @@ func (d *dkgProtocol) enforceNackComplaints(complaints []*typesDKG.Complaint) { if _, exist := d.antiComplaintReceived[from][to]; !exist { d.recv.ProposeDKGComplaint(&typesDKG.Complaint{ - ProposerID: d.ID, - Round: d.round, + Round: d.round, PrivateShare: typesDKG.PrivateShare{ ProposerID: to, Round: d.round, @@ -282,7 +277,7 @@ func (d *dkgProtocol) sanityCheck(prvShare *typesDKG.PrivateShare) error { if _, exist := d.idMap[prvShare.ProposerID]; !exist { return ErrNotDKGParticipant } - ok, err := verifyDKGPrivateShareSignature(prvShare) + ok, err := utils.VerifyDKGPrivateShareSignature(prvShare) if err != nil { return err } @@ -318,7 +313,6 @@ func (d *dkgProtocol) processPrivateShare( return nil } complaint := &typesDKG.Complaint{ - ProposerID: d.ID, Round: d.round, PrivateShare: *prvShare, } @@ -546,7 +540,7 @@ func (tsig *tsigProtocol) sanityCheck(psig *typesDKG.PartialSignature) error { if !exist { return ErrNotQualifyDKGParticipant } - ok, err := verifyDKGPartialSignatureSignature(psig) + ok, err := utils.VerifyDKGPartialSignatureSignature(psig) if err != nil { return err } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go index 8780bbaec..db19cf910 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go @@ -25,6 +25,7 @@ import ( "github.com/dexon-foundation/dexon-consensus/common" "github.com/dexon-foundation/dexon-consensus/core/db" "github.com/dexon-foundation/dexon-consensus/core/types" + "github.com/dexon-foundation/dexon-consensus/core/utils" ) // Errors for sanity check error. @@ -34,15 +35,15 @@ var ( // Lattice represents a unit to produce a global ordering from multiple chains. type Lattice struct { - lock sync.RWMutex - authModule *Authenticator - app Application - debug Debug - pool blockPool - data *latticeData - toModule *totalOrdering - ctModule *consensusTimestamp - logger common.Logger + lock sync.RWMutex + signer *utils.Signer + app Application + debug Debug + pool blockPool + data *latticeData + toModule *totalOrdering + ctModule *consensusTimestamp + logger common.Logger } // NewLattice constructs an Lattice instance. @@ -50,7 +51,7 @@ func NewLattice( dMoment time.Time, round uint64, cfg *types.Config, - authModule *Authenticator, + signer *utils.Signer, app Application, debug Debug, db db.Database, @@ -58,14 +59,14 @@ func NewLattice( // Create genesis latticeDataConfig. return &Lattice{ - authModule: authModule, - app: app, - debug: debug, - pool: newBlockPool(cfg.NumChains), - data: newLatticeData(db, dMoment, round, cfg), - toModule: newTotalOrdering(dMoment, round, cfg), - ctModule: newConsensusTimestamp(dMoment, round, cfg.NumChains), - logger: logger, + signer: signer, + app: app, + debug: debug, + pool: newBlockPool(cfg.NumChains), + data: newLatticeData(db, dMoment, round, cfg), + toModule: newTotalOrdering(dMoment, round, cfg), + ctModule: newConsensusTimestamp(dMoment, round, cfg.NumChains), + logger: logger, } } @@ -89,7 +90,7 @@ func (l *Lattice) PrepareBlock( if b.Witness, err = l.app.PrepareWitness(b.Witness.Height); err != nil { return } - if err = l.authModule.SignBlock(b); err != nil { + if err = l.signer.SignBlock(b); err != nil { return } return @@ -102,7 +103,7 @@ func (l *Lattice) PrepareEmptyBlock(b *types.Block) (err error) { if err = l.data.prepareEmptyBlock(b); err != nil { return } - if b.Hash, err = hashBlock(b); err != nil { + if b.Hash, err = utils.HashBlock(b); err != nil { return } return @@ -116,7 +117,7 @@ func (l *Lattice) SanityCheck(b *types.Block) (err error) { if b.IsEmpty() { // Only need to verify block's hash. var hash common.Hash - if hash, err = hashBlock(b); err != nil { + if hash, err = utils.HashBlock(b); err != nil { return } if b.Hash != hash { @@ -124,7 +125,7 @@ func (l *Lattice) SanityCheck(b *types.Block) (err error) { } } else { // Verify block's signature. - if err = l.authModule.VerifyBlock(b); err != nil { + if err = utils.VerifyBlockSignature(b); err != nil { return } } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/leader-selector.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/leader-selector.go index a68f8ab66..94d28faeb 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/leader-selector.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/leader-selector.go @@ -25,6 +25,7 @@ import ( "github.com/dexon-foundation/dexon-consensus/common" "github.com/dexon-foundation/dexon-consensus/core/crypto" "github.com/dexon-foundation/dexon-consensus/core/types" + "github.com/dexon-foundation/dexon-consensus/core/utils" ) // Errors for leader module. @@ -121,7 +122,7 @@ func (l *leaderSelector) leaderBlockHash() common.Hash { } func (l *leaderSelector) processBlock(block *types.Block) error { - ok, err := verifyCRSSignature(block, l.hashCRS) + ok, err := utils.VerifyCRSSignature(block, l.hashCRS) if err != nil { return err } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go index da9d352f4..32bbab3b2 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go @@ -127,7 +127,7 @@ func (con *Consensus) initConsensusObj(initBlock *types.Block) { con.roundBeginTimes[con.latticeLastRound], con.latticeLastRound, cfg, - core.NewAuthenticator(con.prv), + utils.NewSigner(con.prv), con.app, debugApp, con.db, @@ -446,9 +446,10 @@ func (con *Consensus) SyncBlocks( return false, err } if syncBlock != nil { - con.logger.Info("deliver set found", syncBlock) + con.logger.Info("deliver set found", "block", syncBlock) // New lattice with the round of syncBlock. con.initConsensusObj(syncBlock) + con.setupConfigs(blocks) // Process blocks from syncBlock to blocks' last block. b := blocks[len(blocks)-1] blocksCount := b.Finalization.Height - syncBlock.Finalization.Height + 1 @@ -586,7 +587,7 @@ func (con *Consensus) setupConfigs(blocks []*types.Block) { con.resizeByNumChains(curMaxNumChains) // Notify core.Lattice for new configs. if con.lattice != nil { - for con.latticeLastRound+1 <= maxRound { + for con.latticeLastRound+1 <= untilRound { con.latticeLastRound++ if err := con.lattice.AppendConfig( con.latticeLastRound, @@ -714,14 +715,12 @@ func (con *Consensus) startCRSMonitor() { select { case <-con.ctx.Done(): return - case <-time.After(1 * time.Second): - // Notify agreement modules for the latest round that CRS is - // available if the round is not notified yet. - var crsRound = lastNotifiedRound - for (con.gov.CRS(crsRound+1) != common.Hash{}) { - crsRound++ - } - notifyNewCRS(crsRound) + case <-time.After(500 * time.Millisecond): + } + // Notify agreement modules for the latest round that CRS is + // available if the round is not notified yet. + if (con.gov.CRS(lastNotifiedRound+1) != common.Hash{}) { + notifyNewCRS(lastNotifiedRound + 1) } } }() @@ -732,7 +731,10 @@ func (con *Consensus) stopAgreement() { con.lock.Lock() defer con.lock.Unlock() for _, a := range con.agreements { - close(a.inputChan) + if a.inputChan != nil { + close(a.inputChan) + a.inputChan = nil + } } }() con.agreementWaitGroup.Wait() diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/total-ordering.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/total-ordering.go index 3bf6946ae..744471a84 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/total-ordering.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/total-ordering.go @@ -19,6 +19,7 @@ package core import ( "errors" + "fmt" "math" "sort" "sync" @@ -1017,7 +1018,7 @@ func (to *totalOrdering) generateDeliverSet() ( chainID, otherChainID uint32 info, otherInfo *totalOrderingCandidateInfo precedings = make(map[uint32]struct{}) - cfg = to.configs[to.curRound-to.configs[0].roundID] + cfg = to.getCurrentConfig() ) mode = TotalOrderingModeNormal to.globalVector.updateCandidateInfo(to.dirtyChainIDs, to.objCache) @@ -1162,7 +1163,7 @@ func (to *totalOrdering) flushBlocks( b *types.Block) (flushed []*types.Block, mode uint32, err error) { mode = TotalOrderingModeFlush - cfg := to.configs[to.curRound-to.configs[0].roundID] + cfg := to.getCurrentConfig() if cfg.isLastBlock(b) { to.flushReadyChains[b.Position.ChainID] = struct{}{} } @@ -1216,7 +1217,7 @@ func (to *totalOrdering) flushBlocks( to.globalVector.cachedCandidateInfo = nil to.switchRound() // Force picking new candidates. - numChains := to.configs[to.curRound-to.configs[0].roundID].numChains + numChains := to.getCurrentConfig().numChains to.output(map[common.Hash]struct{}{}, numChains) return } @@ -1226,7 +1227,7 @@ func (to *totalOrdering) deliverBlocks() ( delivered []*types.Block, mode uint32, err error) { hashes, mode := to.generateDeliverSet() - cfg := to.configs[to.curRound-to.configs[0].roundID] + cfg := to.getCurrentConfig() // Output precedings. delivered = to.output(hashes, cfg.numChains) // Check if any block in delivered set is the last block in this round, if @@ -1271,12 +1272,21 @@ func (to *totalOrdering) deliverBlocks() ( return } +func (to *totalOrdering) getCurrentConfig() *totalOrderingConfig { + cfgIdx := to.curRound - to.configs[0].roundID + if cfgIdx >= uint64(len(to.configs)) { + panic(fmt.Errorf("total ordering config is not ready: %v, %v, %v", + to.curRound, to.configs[0].roundID, len(to.configs))) + } + return to.configs[cfgIdx] +} + // processBlock is the entry point of totalOrdering. func (to *totalOrdering) processBlock( b *types.Block) ([]*types.Block, uint32, error) { // NOTE: Block b is assumed to be in topologically sorted, i.e., all its // acking blocks are during or after total ordering stage. - cfg := to.configs[to.curRound-to.configs[0].roundID] + cfg := to.getCurrentConfig() to.pendings[b.Hash] = b to.buildBlockRelation(b) isOldest, err := to.updateVectors(b) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go index 671d68018..0c2d15588 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go @@ -18,6 +18,7 @@ package core import ( + "context" "errors" "fmt" "math/rand" @@ -146,27 +147,6 @@ func HashConfigurationBlock( ) } -// VerifyBlock verifies the signature of types.Block. -func VerifyBlock(b *types.Block) (err error) { - hash, err := hashBlock(b) - if err != nil { - return - } - if hash != b.Hash { - err = ErrIncorrectHash - return - } - pubKey, err := crypto.SigToPub(b.Hash, b.Signature) - if err != nil { - return - } - if !b.ProposerID.Equal(types.NewNodeID(pubKey)) { - err = ErrIncorrectSignature - return - } - return -} - // VerifyAgreementResult perform sanity check against a types.AgreementResult // instance. func VerifyAgreementResult( @@ -201,7 +181,7 @@ func VerifyAgreementResult( if _, exist := notarySet[vote.ProposerID]; !exist { return ErrIncorrectVoteProposer } - ok, err := verifyVoteSignature(&vote) + ok, err := utils.VerifyVoteSignature(&vote) if err != nil { return err } @@ -235,3 +215,22 @@ func isTravisCI() bool { func getDKGThreshold(config *types.Config) int { return int(config.DKGSetSize/3) + 1 } + +// checkWithCancel is a helper to perform periodic checking with cancel. +func checkWithCancel(parentCtx context.Context, interval time.Duration, + checker func() bool) (ret bool) { + ctx, cancel := context.WithCancel(parentCtx) + defer cancel() +Loop: + for { + select { + case <-ctx.Done(): + break Loop + case <-time.After(interval): + } + if ret = checker(); ret { + return + } + } + return +} diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go index d4a7f0ead..60424115e 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/crypto.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go @@ -15,7 +15,7 @@ // along with the dexon-consensus library. If not, see // <http://www.gnu.org/licenses/>. -package core +package utils import ( "encoding/binary" @@ -34,7 +34,8 @@ func hashWitness(witness *types.Witness) (common.Hash, error) { witness.Data), nil } -func hashBlock(block *types.Block) (common.Hash, error) { +// HashBlock generates hash of a types.Block. +func HashBlock(block *types.Block) (common.Hash, error) { hashPosition := hashPosition(block.Position) // Handling Block.Acks. binaryAcks := make([][]byte, len(block.Acks)) @@ -62,13 +63,31 @@ func hashBlock(block *types.Block) (common.Hash, error) { return hash, nil } -func verifyBlockSignature(pubkey crypto.PublicKey, - block *types.Block, sig crypto.Signature) (bool, error) { - hash, err := hashBlock(block) +// VerifyBlockSignature verifies the signature of types.Block. +func VerifyBlockSignature(b *types.Block) (err error) { + payloadHash := crypto.Keccak256Hash(b.Payload) + if payloadHash != b.PayloadHash { + err = ErrIncorrectHash + return + } + hash, err := HashBlock(b) if err != nil { - return false, err + return } - return pubkey.VerifySignature(hash, sig), nil + if hash != b.Hash { + err = ErrIncorrectHash + return + } + pubKey, err := crypto.SigToPub(b.Hash, b.Signature) + if err != nil { + return + } + if !b.ProposerID.Equal(types.NewNodeID(pubKey)) { + err = ErrIncorrectSignature + return + } + return + } func hashVote(vote *types.Vote) common.Hash { @@ -87,7 +106,8 @@ func hashVote(vote *types.Vote) common.Hash { return hash } -func verifyVoteSignature(vote *types.Vote) (bool, error) { +// VerifyVoteSignature verifies the signature of types.Vote. +func VerifyVoteSignature(vote *types.Vote) (bool, error) { hash := hashVote(vote) pubKey, err := crypto.SigToPub(hash, vote.Signature) if err != nil { @@ -104,7 +124,8 @@ func hashCRS(block *types.Block, crs common.Hash) common.Hash { return crypto.Keccak256Hash(crs[:], hashPos[:]) } -func verifyCRSSignature(block *types.Block, crs common.Hash) ( +// VerifyCRSSignature verifies the CRS signature of types.Block. +func VerifyCRSSignature(block *types.Block, crs common.Hash) ( bool, error) { hash := hashCRS(block, crs) pubKey, err := crypto.SigToPub(hash, block.CRSSignature) @@ -146,7 +167,9 @@ func hashDKGPrivateShare(prvShare *typesDKG.PrivateShare) common.Hash { ) } -func verifyDKGPrivateShareSignature( +// VerifyDKGPrivateShareSignature verifies the signature of +// typesDKG.PrivateShare. +func VerifyDKGPrivateShareSignature( prvShare *typesDKG.PrivateShare) (bool, error) { hash := hashDKGPrivateShare(prvShare) pubKey, err := crypto.SigToPub(hash, prvShare.Signature) @@ -213,7 +236,7 @@ func VerifyDKGComplaintSignature( return false, nil } if !complaint.IsNack() { - return verifyDKGPrivateShareSignature(&complaint.PrivateShare) + return VerifyDKGPrivateShareSignature(&complaint.PrivateShare) } return true, nil } @@ -230,7 +253,9 @@ func hashDKGPartialSignature(psig *typesDKG.PartialSignature) common.Hash { ) } -func verifyDKGPartialSignatureSignature( +// VerifyDKGPartialSignatureSignature verifies the signature of +// typesDKG.PartialSignature. +func VerifyDKGPartialSignatureSignature( psig *typesDKG.PartialSignature) (bool, error) { hash := hashDKGPartialSignature(psig) pubKey, err := crypto.SigToPub(hash, psig.Signature) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go new file mode 100644 index 000000000..47bea3f3d --- /dev/null +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go @@ -0,0 +1,126 @@ +// Copyright 2018 The dexon-consensus Authors +// This file is part of the dexon-consensus library. +// +// The dexon-consensus library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus library. If not, see +// <http://www.gnu.org/licenses/>. + +package utils + +import ( + "errors" + + "github.com/dexon-foundation/dexon-consensus/common" + "github.com/dexon-foundation/dexon-consensus/core/crypto" + "github.com/dexon-foundation/dexon-consensus/core/types" + typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg" +) + +// Errors for signer. +var ( + ErrInvalidProposerID = errors.New("invalid proposer id") + ErrIncorrectHash = errors.New("hash of block is incorrect") + ErrIncorrectSignature = errors.New("signature of block is incorrect") +) + +// Signer signs a segment of data. +type Signer struct { + prvKey crypto.PrivateKey + pubKey crypto.PublicKey + proposerID types.NodeID +} + +// NewSigner constructs an Signer instance. +func NewSigner(prvKey crypto.PrivateKey) (s *Signer) { + s = &Signer{ + prvKey: prvKey, + pubKey: prvKey.PublicKey(), + } + s.proposerID = types.NewNodeID(s.pubKey) + return +} + +// SignBlock signs a types.Block. +func (s *Signer) SignBlock(b *types.Block) (err error) { + b.ProposerID = s.proposerID + b.PayloadHash = crypto.Keccak256Hash(b.Payload) + if b.Hash, err = HashBlock(b); err != nil { + return + } + if b.Signature, err = s.prvKey.Sign(b.Hash); err != nil { + return + } + return +} + +// SignVote signs a types.Vote. +func (s *Signer) SignVote(v *types.Vote) (err error) { + v.ProposerID = s.proposerID + v.Signature, err = s.prvKey.Sign(hashVote(v)) + return +} + +// SignCRS signs CRS signature of types.Block. +func (s *Signer) SignCRS(b *types.Block, crs common.Hash) (err error) { + if b.ProposerID != s.proposerID { + err = ErrInvalidProposerID + return + } + b.CRSSignature, err = s.prvKey.Sign(hashCRS(b, crs)) + return +} + +// SignDKGComplaint signs a DKG complaint. +func (s *Signer) SignDKGComplaint(complaint *typesDKG.Complaint) (err error) { + complaint.ProposerID = s.proposerID + complaint.Signature, err = s.prvKey.Sign(hashDKGComplaint(complaint)) + return +} + +// SignDKGMasterPublicKey signs a DKG master public key. +func (s *Signer) SignDKGMasterPublicKey( + mpk *typesDKG.MasterPublicKey) (err error) { + mpk.ProposerID = s.proposerID + mpk.Signature, err = s.prvKey.Sign(hashDKGMasterPublicKey(mpk)) + return +} + +// SignDKGPrivateShare signs a DKG private share. +func (s *Signer) SignDKGPrivateShare( + prvShare *typesDKG.PrivateShare) (err error) { + prvShare.ProposerID = s.proposerID + prvShare.Signature, err = s.prvKey.Sign(hashDKGPrivateShare(prvShare)) + return +} + +// SignDKGPartialSignature signs a DKG partial signature. +func (s *Signer) SignDKGPartialSignature( + pSig *typesDKG.PartialSignature) (err error) { + pSig.ProposerID = s.proposerID + pSig.Signature, err = s.prvKey.Sign(hashDKGPartialSignature(pSig)) + return +} + +// SignDKGMPKReady signs a DKG ready message. +func (s *Signer) SignDKGMPKReady(ready *typesDKG.MPKReady) (err error) { + ready.ProposerID = s.proposerID + ready.Signature, err = s.prvKey.Sign(hashDKGMPKReady(ready)) + return +} + +// SignDKGFinalize signs a DKG finalize message. +func (s *Signer) SignDKGFinalize(final *typesDKG.Finalize) (err error) { + final.ProposerID = s.proposerID + final.Signature, err = s.prvKey.Sign(hashDKGFinalize(final)) + return +} |