diff options
6 files changed, 98 insertions, 36 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go index 30895f8ec..aacb65de2 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go @@ -63,6 +63,13 @@ func (pb *pendingBlockRecords) insert(p pendingBlockRecord) error { *pb = append(*pb, p) default: if (*pb)[idx].position.Equal(p.position) { + // Allow to overwrite pending block record for empty blocks, we may + // need to pull that block from others when its parent is not found + // locally. + if (*pb)[idx].block == nil && p.block != nil { + (*pb)[idx].block = p.block + return nil + } return ErrDuplicatedPendingBlock } // Insert the value to that index. @@ -275,8 +282,7 @@ func (bc *blockChain) addEmptyBlock(position types.Position) ( } else if position.Height == 0 && position.Round == 0 { return add(), nil } - bc.addPendingBlockRecord(pendingBlockRecord{position, nil}) - return nil, nil + return nil, bc.addPendingBlockRecord(pendingBlockRecord{position, nil}) } // addBlock should be called when the block is confirmed by BA, we won't perform @@ -298,11 +304,10 @@ func (bc *blockChain) addBlock(b *types.Block) error { confirmed = true } if !confirmed { - bc.addPendingBlockRecord(pendingBlockRecord{b.Position, b}) - } else { - bc.confirmBlock(b) - bc.checkIfBlocksConfirmed() + return bc.addPendingBlockRecord(pendingBlockRecord{b.Position, b}) } + bc.confirmBlock(b) + bc.checkIfBlocksConfirmed() return nil } @@ -449,18 +454,19 @@ func (bc *blockChain) findPendingBlock(p types.Position) *types.Block { return pendingRec.block } -func (bc *blockChain) addPendingBlockRecord(p pendingBlockRecord) { +func (bc *blockChain) addPendingBlockRecord(p pendingBlockRecord) error { if err := bc.pendingBlocks.insert(p); err != nil { if err == ErrDuplicatedPendingBlock { - // TODO(mission): panic directly once our BA can confirm blocks - // uniquely and in sequence. - return + // TODO(mission): stop ignoreing this error once our BA can confirm + // blocks uniquely and sequentially. + err = nil } - panic(err) + return err } if p.block != nil { bc.setRandomnessFromPending(p.block) } + return nil } func (bc *blockChain) checkIfBlocksConfirmed() { 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 0f4daa766..050bfe7e5 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go @@ -127,7 +127,15 @@ func (recv *consensusBAReceiver) ConfirmBlock( return } if block == nil { - panic(fmt.Errorf("empty block should be proposed directly: %s", aID)) + // The empty block's parent is not found locally, thus we can't + // propose it at this moment. + // + // We can only rely on block pulling upon receiving + // types.AgreementResult from the next position. + recv.consensus.logger.Warn( + "An empty block is confirmed without its parent", + "position", aID) + return } } else { var exist bool @@ -1075,6 +1083,14 @@ func (con *Consensus) ProcessBlockRandomnessResult( // preProcessBlock performs Byzantine Agreement on the block. func (con *Consensus) preProcessBlock(b *types.Block) (err error) { + var exist bool + exist, err = con.nodeSetCache.Exists(b.Position.Round, b.ProposerID) + if err != nil { + return + } + if !exist { + return ErrProposerNotInNodeSet + } err = con.baMgr.processBlock(b) if err == nil && con.debugApp != nil { con.debugApp.BlockReceived(b.Hash) 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 4f15a74ac..45fe822e1 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 @@ -55,6 +55,12 @@ var ( "cache of round already been purged") ErrTSigNotReady = fmt.Errorf( "tsig not ready") + ErrSelfMPKNotRegister = fmt.Errorf( + "self mpk not registered") + ErrUnableGetSelfPrvShare = fmt.Errorf( + "unable to get self DKG PrivateShare") + ErrSelfPrvShareMismatch = fmt.Errorf( + "self privateShare does not match mpk registered") ) type dkgReceiver interface { @@ -186,6 +192,9 @@ func (d *dkgProtocol) processMasterPublicKeys( ids[i] = mpks[i].DKGID } d.masterPrivateShare.SetParticipants(ids) + if err = d.verifySelfPrvShare(); err != nil { + return + } for _, mpk := range mpks { share, ok := d.masterPrivateShare.Share(mpk.DKGID) if !ok { @@ -201,6 +210,26 @@ func (d *dkgProtocol) processMasterPublicKeys( return } +func (d *dkgProtocol) verifySelfPrvShare() error { + selfMPK, exist := d.mpkMap[d.ID] + if !exist { + return ErrSelfMPKNotRegister + } + share, ok := d.masterPrivateShare.Share(d.idMap[d.ID]) + if !ok { + return ErrUnableGetSelfPrvShare + } + ok, err := selfMPK.VerifyPrvShare( + d.idMap[d.ID], share) + if err != nil { + return err + } + if !ok { + return ErrSelfPrvShareMismatch + } + return nil +} + func (d *dkgProtocol) proposeNackComplaints() { for nID := range d.mpkMap { if _, exist := d.prvSharesReceived[nID]; exist { @@ -218,6 +247,9 @@ func (d *dkgProtocol) proposeNackComplaints() { func (d *dkgProtocol) processNackComplaints(complaints []*typesDKG.Complaint) ( err error) { + if err = d.verifySelfPrvShare(); err != nil { + return + } for _, complaint := range complaints { if !complaint.IsNack() { continue 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 7ba659f27..305339687 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 @@ -85,6 +85,7 @@ type Consensus struct { dummyCancel context.CancelFunc dummyFinished <-chan struct{} dummyMsgBuffer []interface{} + initChainTipHeight uint64 } // NewConsensus creates an instance for Consensus (syncer consensus). @@ -116,6 +117,7 @@ func NewConsensus( randomnessResults: make(map[common.Hash]*types.BlockRandomnessResult), } con.ctx, con.ctxCancel = context.WithCancel(context.Background()) + _, con.initChainTipHeight = db.GetCompactionChainTipInfo() con.agreementModule = newAgreement( con.receiveChan, con.pullChan, con.nodeSetCache, con.logger) con.agreementWaitGroup.Add(1) @@ -466,6 +468,12 @@ func (con *Consensus) startNetwork() { switch v := val.(type) { case *types.Block: case *types.AgreementResult: + // Avoid byzantine nodes attack by broadcasting older + // agreement results. Normal nodes might report 'synced' + // while still fall behind other nodes. + if v.Position.Height <= con.initChainTipHeight { + continue loop + } case *types.BlockRandomnessResult: con.cacheRandomnessResult(v) continue loop diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go index 203f57fc2..220240c5a 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go @@ -98,7 +98,7 @@ func VerifyDKGComplaint( if err != nil { return false, err } - return ok, nil + return !ok, nil } // LaunchDummyReceiver launches a go routine to receive from the receive diff --git a/vendor/vendor.json b/vendor/vendor.json index 902311947..963c8f4fa 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -141,16 +141,16 @@ { "checksumSHA1": "8EuKVkP1v/w5fRuuvUaXX5k/F+I=", "path": "github.com/dexon-foundation/dexon-consensus/common", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { - "checksumSHA1": "r+N+XXh95Zps97hB0mPsJ44eIgI=", + "checksumSHA1": "2zv4HDhSnwpziM4Yk9A7cKIm8yo=", "path": "github.com/dexon-foundation/dexon-consensus/core", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, @@ -165,64 +165,64 @@ { "checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "vTI0nncFqZ052WvofDhFxLw1Bk4=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "zpuCdMT8MGsy4pLgHKpg/Wd4izU=", "path": "github.com/dexon-foundation/dexon-consensus/core/db", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { - "checksumSHA1": "T9TNx0oUpaRdlbCuy7AvkK1eQ18=", + "checksumSHA1": "KC7POL7Km89JIWSvrmGpSakHF+4=", "path": "github.com/dexon-foundation/dexon-consensus/core/syncer", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "id8imcgp3SqYhIx0k3Chd0VZrUQ=", "path": "github.com/dexon-foundation/dexon-consensus/core/types", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { "checksumSHA1": "s28gYj+iji8oT7N7Su6HIFHMuwI=", "path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, { - "checksumSHA1": "GGQv132mkXvrjfhqP7zR65I95P4=", + "checksumSHA1": "ydfH9XlrRroxsWcvKlGeIDDchB0=", "path": "github.com/dexon-foundation/dexon-consensus/core/utils", - "revision": "69c8d0dba506f640af4c5539fa424957cdd35db3", - "revisionTime": "2019-03-07T03:15:15Z", + "revision": "ac3187e706bc11f1b36e32015a6e51a96cc8cfe9", + "revisionTime": "2019-03-09T16:39:54Z", "version": "single-chain", "versionExact": "single-chain" }, |