From ef24d59fe79fd57a88ff886afdc3a01be1d49e55 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Tue, 13 Nov 2018 15:34:22 +0800 Subject: vendor: sync to latest core (#16) --- .../dexon-consensus/core/agreement-state.go | 18 ++----- .../dexon-consensus/core/compaction-chain.go | 10 +++- .../dexon-consensus/core/consensus-timestamp.go | 63 +++++++++++++--------- .../dexon-consensus/core/consensus.go | 10 ++-- .../dexon-consensus/core/lattice.go | 2 +- .../dexon-consensus/core/leader-selector.go | 24 +++++++-- .../dexon-consensus/core/types/block.go | 18 +++++-- .../dexon-consensus/core/types/vote.go | 39 ++++++++++---- vendor/vendor.json | 36 ++++++------- 9 files changed, 131 insertions(+), 89 deletions(-) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-state.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-state.go index fe329f832..9023799a3 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-state.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-state.go @@ -72,11 +72,7 @@ func (s *initialState) nextState() (agreementState, error) { hash := s.a.recv.ProposeBlock() s.a.lock.Lock() defer s.a.lock.Unlock() - s.a.recv.ProposeVote(&types.Vote{ - Type: types.VoteInit, - BlockHash: hash, - Period: s.a.period, - }) + s.a.recv.ProposeVote(types.NewVote(types.VoteInit, hash, s.a.period)) return newPreCommitState(s.a), nil } @@ -98,11 +94,7 @@ func (s *preCommitState) nextState() (agreementState, error) { if hash == nullBlockHash { hash = s.a.leader.leaderBlockHash() } - s.a.recv.ProposeVote(&types.Vote{ - Type: types.VotePreCom, - BlockHash: hash, - Period: s.a.period, - }) + s.a.recv.ProposeVote(types.NewVote(types.VotePreCom, hash, s.a.period)) return newCommitState(s.a), nil } @@ -127,11 +119,7 @@ func (s *commitState) nextState() (agreementState, error) { } else { hash = skipBlockHash } - s.a.recv.ProposeVote(&types.Vote{ - Type: types.VoteCom, - BlockHash: hash, - Period: s.a.period, - }) + s.a.recv.ProposeVote(types.NewVote(types.VoteCom, hash, s.a.period)) return newForwardState(s.a), nil } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/compaction-chain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/compaction-chain.go index 8080a2c78..4a5ba3637 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/compaction-chain.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/compaction-chain.go @@ -42,6 +42,7 @@ type compactionChain struct { chainUnsynced uint32 tsigVerifier *TSigVerifierCache blocks map[common.Hash]*types.Block + blockRandomness map[common.Hash][]byte pendingBlocks []*types.Block pendingFinalizedBlocks *finalizedBlockHeap lock sync.RWMutex @@ -55,6 +56,7 @@ func newCompactionChain(gov Governance) *compactionChain { gov: gov, tsigVerifier: NewTSigVerifierCache(gov, 7), blocks: make(map[common.Hash]*types.Block), + blockRandomness: make(map[common.Hash][]byte), pendingFinalizedBlocks: pendingFinalizedBlocks, } } @@ -131,7 +133,7 @@ func (cc *compactionChain) extractBlocks() []*types.Block { defer cc.lock.Unlock() // cc.pendingBlocks[0] will not be popped and will equal to cc.prevBlock. for len(cc.pendingBlocks) > 1 && - (len(cc.pendingBlocks[1].Finalization.Randomness) != 0 || + (len(cc.blockRandomness[cc.pendingBlocks[1].Hash]) != 0 || cc.pendingBlocks[1].Position.Round == 0) { delete(cc.blocks, cc.pendingBlocks[0].Hash) cc.pendingBlocks = cc.pendingBlocks[1:] @@ -139,6 +141,10 @@ func (cc *compactionChain) extractBlocks() []*types.Block { block := cc.pendingBlocks[0] block.Finalization.ParentHash = prevBlock.Hash block.Finalization.Height = prevBlock.Finalization.Height + 1 + if block.Position.Round != 0 { + block.Finalization.Randomness = cc.blockRandomness[block.Hash] + delete(cc.blockRandomness, block.Hash) + } deliveringBlocks = append(deliveringBlocks, block) prevBlock = block } @@ -260,7 +266,7 @@ func (cc *compactionChain) processBlockRandomnessResult( if !cc.blockRegisteredNoLock(rand.BlockHash) { return ErrBlockNotRegistered } - cc.blocks[rand.BlockHash].Finalization.Randomness = rand.Randomness + cc.blockRandomness[rand.BlockHash] = rand.Randomness return nil } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus-timestamp.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus-timestamp.go index 833194bd9..a1ace97f2 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus-timestamp.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus-timestamp.go @@ -24,32 +24,40 @@ import ( "github.com/dexon-foundation/dexon-consensus/core/types" ) -// consensusTimestamp is for Concensus Timestamp Algorithm. +// consensusTimestamp calculates a block's finalization timestamp. Notice that +// the Finalization timestamps are increasing (but not strictly increasing). +// Instance functions: +// - processBlocks(blocks []*types.Block) error +// called with blocks output from total ordering +// - appendConfig(round uint64, config *types.Config) error +// called when a new config is known +// - synced() bool +// called in sync mode type consensusTimestamp struct { - chainTimestamps []time.Time + timestampsOfChains []time.Time - // This part keeps configs for each round. + // Stores number of chains for rounds. numChainsOfRounds []uint32 numChainsBase uint64 // dMoment represents the genesis time. dMoment time.Time - // lastTimestamp represents previous assigned consensus timestamp. + + // lastTimestamp is the previous assigned consensus timestamp. lastTimestamp time.Time } var ( - // ErrTimestampNotIncrease would be reported if the timestamp is not strickly - // increasing on the same chain. + // ErrTimestampNotIncrease for timestamp is not strictly increasing on one + // chain. ErrTimestampNotIncrease = errors.New("timestamp is not increasing") // ErrNoRoundConfig for no round config found. ErrNoRoundConfig = errors.New("no round config found") - // ErrConsensusTimestampRewind would be reported if the generated timestamp - // is rewinded. + // ErrConsensusTimestampRewind for rewinding timestamp. ErrConsensusTimestampRewind = errors.New("consensus timestamp rewind") ) -// newConsensusTimestamp creates timestamper object. +// newConsensusTimestamp creates consensus timestamp instance. func newConsensusTimestamp( dMoment time.Time, round uint64, numChains uint32) *consensusTimestamp { @@ -58,10 +66,10 @@ func newConsensusTimestamp( ts[i] = dMoment } return &consensusTimestamp{ - numChainsOfRounds: []uint32{numChains}, - numChainsBase: round, - dMoment: dMoment, - chainTimestamps: ts, + numChainsOfRounds: []uint32{numChains}, + numChainsBase: round, + dMoment: dMoment, + timestampsOfChains: ts, } } @@ -69,7 +77,6 @@ func newConsensusTimestamp( // a config for round R, next time you can only append the config for round R+1. func (ct *consensusTimestamp) appendConfig( round uint64, config *types.Config) error { - if round != uint64(len(ct.numChainsOfRounds))+ct.numChainsBase { return ErrRoundNotIncreasing } @@ -77,14 +84,14 @@ func (ct *consensusTimestamp) appendConfig( return nil } -func (ct *consensusTimestamp) resizeChainTimetamps(numChain uint32) { - l := uint32(len(ct.chainTimestamps)) +func (ct *consensusTimestamp) resizeTimetamps(numChain uint32) { + l := uint32(len(ct.timestampsOfChains)) if numChain > l { for i := l; i < numChain; i++ { - ct.chainTimestamps = append(ct.chainTimestamps, ct.dMoment) + ct.timestampsOfChains = append(ct.timestampsOfChains, ct.dMoment) } } else if numChain < l { - ct.chainTimestamps = ct.chainTimestamps[:numChain] + ct.timestampsOfChains = ct.timestampsOfChains[:numChain] } } @@ -96,30 +103,36 @@ func (ct *consensusTimestamp) processBlocks(blocks []*types.Block) (err error) { // interleave with r-1 and r+1. round := block.Position.Round if ct.numChainsBase == round || ct.numChainsBase+1 == round { - // Normal case, no need to modify chainTimestamps. + // Normal case, no need to modify timestampsOfChains. } else if ct.numChainsBase+2 == round { + // Resize timestampsOfChains if block from r+2 comes, because the interleave + // of rounds must be less than 1. Resize the size to + // max(numChainsOfRounds[r+1], numChainsOfRounds[r+2]). if len(ct.numChainsOfRounds) < 2 { return ErrNoRoundConfig } ct.numChainsBase++ ct.numChainsOfRounds = ct.numChainsOfRounds[1:] if ct.numChainsOfRounds[0] > ct.numChainsOfRounds[1] { - ct.resizeChainTimetamps(ct.numChainsOfRounds[0]) + ct.resizeTimetamps(ct.numChainsOfRounds[0]) } else { - ct.resizeChainTimetamps(ct.numChainsOfRounds[1]) + ct.resizeTimetamps(ct.numChainsOfRounds[1]) } } else { // Error if round < base or round > base + 2. return ErrInvalidRoundID } - ts := ct.chainTimestamps[:ct.numChainsOfRounds[round-ct.numChainsBase]] + ts := ct.timestampsOfChains[:ct.numChainsOfRounds[round-ct.numChainsBase]] if block.Finalization.Timestamp, err = getMedianTime(ts); err != nil { return } - if block.Timestamp.Before(ct.chainTimestamps[block.Position.ChainID]) { + if block.Timestamp.Before(ct.timestampsOfChains[block.Position.ChainID]) { return ErrTimestampNotIncrease } - ct.chainTimestamps[block.Position.ChainID] = block.Timestamp + ct.timestampsOfChains[block.Position.ChainID] = block.Timestamp + // If the finalization timestamp is before the last timestamp, set it to + // the last one. Notice that the finalization timestamps are increasing but + // not strictly increasing. if block.Finalization.Timestamp.Before(ct.lastTimestamp) { block.Finalization.Timestamp = ct.lastTimestamp } else { @@ -132,7 +145,7 @@ func (ct *consensusTimestamp) processBlocks(blocks []*types.Block) (err error) { func (ct *consensusTimestamp) isSynced() bool { numChain := ct.numChainsOfRounds[0] for i := uint32(0); i < numChain; i++ { - if ct.chainTimestamps[i].Equal(ct.dMoment) { + if ct.timestampsOfChains[i].Equal(ct.dMoment) { return false } } 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 b9da4f0e3..d12d30a6a 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go @@ -660,7 +660,8 @@ func (con *Consensus) initialRound( // 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) + "nodeID", con.ID, + "round", nextRound) time.Sleep(500 * time.Millisecond) } nextDkgSet, err := con.nodeSetCache.GetDKGSet(nextRound) @@ -718,7 +719,6 @@ func (con *Consensus) initialRound( } con.initialRound( startTime.Add(config.RoundInterval), nextRound, nextConfig) - con.round = nextRound }) } @@ -908,9 +908,6 @@ func (con *Consensus) ProcessAgreementResult( if !con.ccModule.blockRegistered(rand.BlockHash) { return nil } - if DiffUint64(con.round, rand.Position.Round) > 1 { - return nil - } // Sanity check done. if !con.cfgModule.touchTSigHash(rand.BlockHash) { return nil @@ -1005,9 +1002,8 @@ func (con *Consensus) preProcessBlock(b *types.Block) (err error) { // deliverBlock deliver a block to application layer. func (con *Consensus) deliverBlock(b *types.Block) { - // TODO(mission): clone types.FinalizationResult con.logger.Debug("Calling Application.BlockDelivered", "block", b) - con.app.BlockDelivered(b.Hash, b.Position, b.Finalization) + con.app.BlockDelivered(b.Hash, b.Position, b.Finalization.Clone()) if b.Position.Round+roundShift == con.roundToNotify { // Only the first block delivered of that round would // trigger this noitification. 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 20e16f264..dcb3368fd 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go @@ -81,7 +81,7 @@ func (l *Lattice) PrepareBlock( if err = l.data.prepareBlock(b); err != nil { return } - l.logger.Debug("Calling Application.PreparePayload", "position", b.Position) + l.logger.Debug("Calling Application.PreparePayload", "position", &b.Position) if b.Payload, err = l.app.PreparePayload(b.Position); 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 247ce8933..a68f8ab66 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 @@ -101,13 +101,17 @@ func (l *leaderSelector) leaderBlockHash() common.Hash { defer l.lock.Unlock() newPendingBlocks := []*types.Block{} for _, b := range l.pendingBlocks { + ok, dist := l.potentialLeader(b) + if !ok { + continue + } ok, err := l.validLeader(b) if err != nil { l.logger.Error("Error checking validLeader", "error", err, "block", b) continue } if ok { - l.updateLeader(b) + l.updateLeader(b, dist) } else { newPendingBlocks = append(newPendingBlocks, b) } @@ -126,6 +130,10 @@ func (l *leaderSelector) processBlock(block *types.Block) error { } l.lock.Lock() defer l.lock.Unlock() + ok, dist := l.potentialLeader(block) + if !ok { + return nil + } ok, err = l.validLeader(block) if err != nil { return err @@ -134,14 +142,20 @@ func (l *leaderSelector) processBlock(block *types.Block) error { l.pendingBlocks = append(l.pendingBlocks, block) return nil } - l.updateLeader(block) + l.updateLeader(block, dist) return nil } -func (l *leaderSelector) updateLeader(block *types.Block) { + +func (l *leaderSelector) potentialLeader(block *types.Block) (bool, *big.Int) { dist := l.distance(block.CRSSignature) cmp := l.minCRSBlock.Cmp(dist) if cmp > 0 || (cmp == 0 && block.Hash.Less(l.minBlockHash)) { - l.minCRSBlock = dist - l.minBlockHash = block.Hash + return true, dist } + return false, dist +} + +func (l *leaderSelector) updateLeader(block *types.Block, dist *big.Int) { + l.minCRSBlock = dist + l.minBlockHash = block.Hash } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go index 27416d8c9..b24e1f715 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go @@ -83,6 +83,18 @@ type FinalizationResult struct { Height uint64 `json:"height"` } +// Clone returns a deep copy of FinalizationResult +func (f FinalizationResult) Clone() FinalizationResult { + frcopy := FinalizationResult{ + ParentHash: f.ParentHash, + Timestamp: f.Timestamp, + Height: f.Height, + } + frcopy.Randomness = make([]byte, len(f.Randomness)) + copy(frcopy.Randomness, f.Randomness) + return frcopy +} + type rlpFinalizationResult struct { ParentHash common.Hash Randomness []byte @@ -223,9 +235,7 @@ func (b *Block) Clone() (bcopy *Block) { bcopy.Position.Height = b.Position.Height bcopy.Signature = b.Signature.Clone() bcopy.CRSSignature = b.CRSSignature.Clone() - bcopy.Finalization.ParentHash = b.Finalization.ParentHash - bcopy.Finalization.Timestamp = b.Finalization.Timestamp - bcopy.Finalization.Height = b.Finalization.Height + bcopy.Finalization = b.Finalization.Clone() bcopy.Witness.Height = b.Witness.Height bcopy.Witness.Data = make([]byte, len(b.Witness.Data)) copy(bcopy.Witness.Data, b.Witness.Data) @@ -235,8 +245,6 @@ func (b *Block) Clone() (bcopy *Block) { bcopy.Payload = make([]byte, len(b.Payload)) copy(bcopy.Payload, b.Payload) bcopy.PayloadHash = b.PayloadHash - bcopy.Finalization.Randomness = make([]byte, len(b.Finalization.Randomness)) - copy(bcopy.Finalization.Randomness, b.Finalization.Randomness) return } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go index 5b99f2253..12c3af892 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go @@ -36,13 +36,18 @@ const ( MaxVoteType ) +// VoteHeader is the header for vote, which can be used as map keys. +type VoteHeader struct { + ProposerID NodeID `json:"proposer_id"` + Type VoteType `json:"type"` + BlockHash common.Hash `json:"block_hash"` + Period uint64 `json:"period"` + Position Position `json:"position"` +} + // Vote is the vote structure defined in Crypto Shuffle Algorithm. type Vote struct { - ProposerID NodeID `json:"proposer_id"` - Type VoteType `json:"type"` - BlockHash common.Hash `json:"block_hash"` - Period uint64 `json:"period"` - Position Position `json:"position"` + VoteHeader `json:"header"` Signature crypto.Signature `json:"signature"` } @@ -51,14 +56,26 @@ func (v *Vote) String() string { &v.Position, v.Period, v.Type, v.BlockHash.String()[:6]) } +// NewVote constructs a Vote instance with header fields. +func NewVote(t VoteType, hash common.Hash, period uint64) *Vote { + return &Vote{ + VoteHeader: VoteHeader{ + Type: t, + BlockHash: hash, + Period: period, + }} +} + // Clone returns a deep copy of a vote. func (v *Vote) Clone() *Vote { return &Vote{ - ProposerID: v.ProposerID, - Type: v.Type, - BlockHash: v.BlockHash, - Period: v.Period, - Position: v.Position, - Signature: v.Signature.Clone(), + VoteHeader: VoteHeader{ + ProposerID: v.ProposerID, + Type: v.Type, + BlockHash: v.BlockHash, + Period: v.Period, + Position: v.Position, + }, + Signature: v.Signature.Clone(), } } diff --git a/vendor/vendor.json b/vendor/vendor.json index 2f4060c17..83d579652 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -105,50 +105,50 @@ { "checksumSHA1": "ev84RyegNbt2Pr/sK26LK9LoQNI=", "path": "github.com/dexon-foundation/dexon-consensus/common", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { - "checksumSHA1": "Tsu1ZfNrsAJHafShtcjaLvzFQWY=", + "checksumSHA1": "9HDUFD7awHgKX5BhFZQAqr5e8Mo=", "path": "github.com/dexon-foundation/dexon-consensus/core", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "vNsaBvsrXJF+W6K5DCLpgy1rUZY=", "path": "github.com/dexon-foundation/dexon-consensus/core/blockdb", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "p2jOAulavUU2xyj018pYPHlj8XA=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "6Pf6caC8LTNCI7IflFmglKYnxYo=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { - "checksumSHA1": "o7RiigeU3kIDbZ96Gh95/h/7yZo=", + "checksumSHA1": "Kzw8b6kQLSApzVHO2WvmxrBfixA=", "path": "github.com/dexon-foundation/dexon-consensus/core/types", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "ovChyW9OfDGnk/7CDAR+A5vJymc=", "path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg", - "revision": "dbe83ea4a324941417d6ff09230e5874d5ba5df5", - "revisionTime": "2018-11-08T07:19:16Z" + "revision": "86838fe70789292de0851f82426e5241c0f0cc96", + "revisionTime": "2018-11-13T07:26:09Z" }, { "checksumSHA1": "TAkwduKZqLyimyTPPWIllZWYFuE=", -- cgit v1.2.3