diff options
author | haoping-ku <haoping.ku@dexon.org> | 2018-11-09 10:50:49 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-09 10:50:49 +0800 |
commit | 71a1dd9c072fb64da026ebe56acd2d187ec272c8 (patch) | |
tree | 31d5a8678bcbff5a3c395e968aae5d966e3f8ec2 | |
parent | 1ee5863fd4a295d34c3a2d602d5603e8746e3f7b (diff) | |
download | dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar.gz dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar.bz2 dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar.lz dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar.xz dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.tar.zst dexon-consensus-71a1dd9c072fb64da026ebe56acd2d187ec272c8.zip |
core: consensus-timestamp: add comments (#312)
-rw-r--r-- | core/consensus-timestamp.go | 63 | ||||
-rw-r--r-- | core/consensus-timestamp_test.go | 2 |
2 files changed, 39 insertions, 26 deletions
diff --git a/core/consensus-timestamp.go b/core/consensus-timestamp.go index 833194b..a1ace97 100644 --- a/core/consensus-timestamp.go +++ b/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/core/consensus-timestamp_test.go b/core/consensus-timestamp_test.go index a093c12..bbc58a2 100644 --- a/core/consensus-timestamp_test.go +++ b/core/consensus-timestamp_test.go @@ -170,7 +170,7 @@ func (s *ConsensusTimestampTest) TestTimestampConfigChange() { s.Require().NoError(err) } -func (s *ConsensusTimestampTest) TestRoundInterleave() { +func (s *ConsensusTimestampTest) TestTimestampRoundInterleave() { chainNum := 9 sigma := 100 * time.Millisecond now := time.Now().UTC() |