diff options
author | Mission Liao <mission.liao@dexon.org> | 2018-10-17 16:33:51 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-17 16:33:51 +0800 |
commit | 6f1df59f8b32d30d5a7a0d9449f2dca698a8ac39 (patch) | |
tree | 20dbf51d8185f01bfdca924b6c220c63505d2862 /core/consensus-timestamp.go | |
parent | 1fafb0a4b992ff225796d01f2271c2573967abae (diff) | |
download | tangerine-consensus-6f1df59f8b32d30d5a7a0d9449f2dca698a8ac39.tar.gz tangerine-consensus-6f1df59f8b32d30d5a7a0d9449f2dca698a8ac39.tar.zst tangerine-consensus-6f1df59f8b32d30d5a7a0d9449f2dca698a8ac39.zip |
core: genesis consensus timestamp (#217)
* Refine the initial value for empty time slot.
* Fix DATA RACE
netowrkConnection is reset for each test,
however, our Consensus instance is not
stopped after one test is finished, they
might continue use network interface for
a while.
Diffstat (limited to 'core/consensus-timestamp.go')
-rw-r--r-- | core/consensus-timestamp.go | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/core/consensus-timestamp.go b/core/consensus-timestamp.go index e04cd07..9551328 100644 --- a/core/consensus-timestamp.go +++ b/core/consensus-timestamp.go @@ -31,6 +31,9 @@ type consensusTimestamp struct { // This part keeps configs for each round. numChainsForRounds []uint32 numChainsRoundBase uint64 + + // dMoment represents the genesis time. + dMoment time.Time } var ( @@ -40,10 +43,12 @@ var ( ) // newConsensusTimestamp creates timestamper object. -func newConsensusTimestamp(numChains uint32) *consensusTimestamp { +func newConsensusTimestamp( + dMoment time.Time, numChains uint32) *consensusTimestamp { return &consensusTimestamp{ numChainsForRounds: []uint32{numChains}, numChainsRoundBase: uint64(0), + dMoment: dMoment, } } @@ -59,29 +64,31 @@ func (ct *consensusTimestamp) appendConfig( return nil } +func (ct *consensusTimestamp) getNumChains(round uint64) uint32 { + roundIndex := round - ct.numChainsRoundBase + return ct.numChainsForRounds[roundIndex] +} + // ProcessBlocks is the entry function. func (ct *consensusTimestamp) processBlocks(blocks []*types.Block) (err error) { for _, block := range blocks { - if !block.IsGenesis() { - round := block.Position.Round - ct.numChainsRoundBase - ts := ct.chainTimestamps[:ct.numChainsForRounds[round]] - if block.Finalization.Timestamp, err = getMedianTime(ts); err != nil { - return - } - } else { - block.Finalization.Timestamp = time.Time{} + numChains := ct.getNumChains(block.Position.Round) + // Fulfill empty time slots with d-moment. This part also means + // each time we increasing number of chains, we can't increase over + // 49% of previous number of chains. + for uint32(len(ct.chainTimestamps)) < numChains { + ct.chainTimestamps = append(ct.chainTimestamps, ct.dMoment) } - - for uint32(len(ct.chainTimestamps)) <= block.Position.ChainID { - ct.chainTimestamps = append(ct.chainTimestamps, time.Time{}) + ts := ct.chainTimestamps[:numChains] + if block.Finalization.Timestamp, err = getMedianTime(ts); err != nil { + return } - if !block.Timestamp.After(ct.chainTimestamps[block.Position.ChainID]) { return ErrTimestampNotIncrease } - ct.chainTimestamps[block.Position.ChainID] = block.Timestamp - + // Purge configs for older rounds, rounds of blocks from total ordering + // would increase. if block.Position.Round > ct.numChainsRoundBase { ct.numChainsRoundBase++ ct.numChainsForRounds = ct.numChainsForRounds[1:] |