diff options
-rw-r--r-- | core/consensus-timestamp.go | 9 | ||||
-rw-r--r-- | core/consensus-timestamp_test.go | 12 | ||||
-rw-r--r-- | integration_test/consensus_test.go | 11 |
3 files changed, 29 insertions, 3 deletions
diff --git a/core/consensus-timestamp.go b/core/consensus-timestamp.go index a1ace97..d7ce8e2 100644 --- a/core/consensus-timestamp.go +++ b/core/consensus-timestamp.go @@ -80,6 +80,15 @@ func (ct *consensusTimestamp) appendConfig( if round != uint64(len(ct.numChainsOfRounds))+ct.numChainsBase { return ErrRoundNotIncreasing } + // This segment is to handle the corner case for config checking logic in + // processBlock method. + if len(ct.numChainsOfRounds) == 1 { + if ct.numChainsOfRounds[0] > config.NumChains { + ct.resizeTimetamps(ct.numChainsOfRounds[0]) + } else { + ct.resizeTimetamps(config.NumChains) + } + } ct.numChainsOfRounds = append(ct.numChainsOfRounds, config.NumChains) return nil } diff --git a/core/consensus-timestamp_test.go b/core/consensus-timestamp_test.go index bbc58a2..9d199fe 100644 --- a/core/consensus-timestamp_test.go +++ b/core/consensus-timestamp_test.go @@ -189,6 +189,18 @@ func (s *ConsensusTimestampTest) TestTimestampRoundInterleave() { s.Require().NoError(err) } +func (s *ConsensusTimestampTest) TestNumChainsChangeAtSecondAppendedRound() { + now := time.Now().UTC() + ct := newConsensusTimestamp(now, 1, 4) + s.Require().NoError(ct.appendConfig(2, &types.Config{NumChains: 5})) + // We should be able to handle a block from the second appended round. + s.Require().NoError(ct.processBlocks([]*types.Block{ + &types.Block{ + Position: types.Position{Round: 2}, + Timestamp: now.Add(1 * time.Second), + }})) +} + func (s *ConsensusTimestampTest) TestTimestampSync() { chainNum := 19 sigma := 100 * time.Millisecond diff --git a/integration_test/consensus_test.go b/integration_test/consensus_test.go index 23a4b3c..c68028f 100644 --- a/integration_test/consensus_test.go +++ b/integration_test/consensus_test.go @@ -258,19 +258,24 @@ func (s *ConsensusTestSuite) TestNumChainsChange() { pubKeys, 100*time.Millisecond, &common.NullLogger{}, true), core.ConfigRoundShift) req.NoError(err) - // Setup configuration for round 0 and round 1. req.NoError(seedGov.State().RequestChange( test.StateChangeRoundInterval, 45*time.Second)) + seedGov.CatchUpWithRound(0) + // Setup configuration for round 0 and round 1. + req.NoError(seedGov.State().RequestChange( + test.StateChangeNumChains, uint32(5))) + req.NoError(seedGov.State().RequestChange( + test.StateChangeRoundInterval, 55*time.Second)) seedGov.CatchUpWithRound(1) // Setup configuration for round 2. req.NoError(seedGov.State().RequestChange( - test.StateChangeNumChains, uint32(5))) + test.StateChangeNumChains, uint32(6))) req.NoError(seedGov.State().RequestChange( test.StateChangeRoundInterval, 55*time.Second)) seedGov.CatchUpWithRound(2) // Setup configuration for round 3. req.NoError(seedGov.State().RequestChange( - test.StateChangeNumChains, uint32(6))) + test.StateChangeNumChains, uint32(5))) req.NoError(seedGov.State().RequestChange( test.StateChangeRoundInterval, 75*time.Second)) seedGov.CatchUpWithRound(3) |