diff options
Diffstat (limited to 'core/compaction-chain_test.go')
-rw-r--r-- | core/compaction-chain_test.go | 343 |
1 files changed, 0 insertions, 343 deletions
diff --git a/core/compaction-chain_test.go b/core/compaction-chain_test.go deleted file mode 100644 index ca88734..0000000 --- a/core/compaction-chain_test.go +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright 2018 The dexon-consensus Authors -// This file is part of the dexon-consensus library. -// -// The dexon-consensus library is free software: you can redistribute it -// and/or modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The dexon-consensus library is distributed in the hope that it will be -// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -// General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the dexon-consensus library. If not, see -// <http://www.gnu.org/licenses/>. - -package core - -import ( - "testing" - "time" - - "github.com/dexon-foundation/dexon-consensus/common" - "github.com/dexon-foundation/dexon-consensus/core/crypto" - "github.com/dexon-foundation/dexon-consensus/core/test" - "github.com/dexon-foundation/dexon-consensus/core/types" - "github.com/stretchr/testify/suite" -) - -type CompactionChainTestSuite struct { - suite.Suite -} - -func (s *CompactionChainTestSuite) SetupTest() { -} - -type mockTSigVerifier struct { - defaultRet bool - ret map[common.Hash]bool -} - -func newMockTSigVerifier(defaultRet bool) *mockTSigVerifier { - return &mockTSigVerifier{ - defaultRet: defaultRet, - ret: make(map[common.Hash]bool), - } -} - -func (m *mockTSigVerifier) VerifySignature( - hash common.Hash, _ crypto.Signature) bool { - if ret, exist := m.ret[hash]; exist { - return ret - } - return m.defaultRet -} - -func (s *CompactionChainTestSuite) newCompactionChain() ( - *compactionChain, *mockTSigVerifier) { - _, pubKeys, err := test.NewKeys(4) - s.Require().NoError(err) - gov, err := test.NewGovernance(test.NewState( - pubKeys, 100*time.Millisecond, &common.NullLogger{}, true), ConfigRoundShift) - s.Require().NoError(err) - cc := newCompactionChain(gov) - cc.init(&types.Block{}) - - mock := newMockTSigVerifier(true) - for i := 0; i < cc.tsigVerifier.cacheSize; i++ { - cc.tsigVerifier.verifier[uint64(i)] = mock - } - - return cc, mock -} - -func (s *CompactionChainTestSuite) TestProcessBlock() { - cc, _ := s.newCompactionChain() - now := time.Now().UTC() - blocks := make([]*types.Block, 10) - for idx := range blocks { - blocks[idx] = &types.Block{ - Hash: common.NewRandomHash(), - Finalization: types.FinalizationResult{ - Timestamp: now, - }, - } - now = now.Add(100 * time.Millisecond) - } - for _, block := range blocks { - s.Require().NoError(cc.processBlock(block)) - } - s.Len(cc.pendingBlocks, len(blocks)) -} - -func (s *CompactionChainTestSuite) TestExtractBlocks() { - cc, _ := s.newCompactionChain() - s.Require().Equal(uint32(4), cc.gov.Configuration(uint64(0)).NumChains) - blocks := make([]*types.Block, 10) - for idx := range blocks { - blocks[idx] = &types.Block{ - Hash: common.NewRandomHash(), - Position: types.Position{ - Round: 1, - ChainID: uint32(idx % 4), - }, - } - s.Require().False(cc.blockRegistered(blocks[idx].Hash)) - cc.registerBlock(blocks[idx]) - s.Require().True(cc.blockRegistered(blocks[idx].Hash)) - } - // Randomness is ready for extract. - for i := 0; i < 4; i++ { - s.Require().NoError(cc.processBlock(blocks[i])) - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } - delivered := cc.extractBlocks() - s.Require().Len(delivered, 4) - s.Require().Equal(uint32(0), cc.chainUnsynced) - // Randomness is not yet ready for extract. - for i := 4; i < 6; i++ { - s.Require().NoError(cc.processBlock(blocks[i])) - } - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 4) - // Make some randomness ready. - for i := 4; i < 6; i++ { - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 6) - // Later block's randomness is ready. - for i := 6; i < 10; i++ { - s.Require().NoError(cc.processBlock(blocks[i])) - if i < 8 { - continue - } - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 6) - // Prior block's randomness is ready. - for i := 6; i < 8; i++ { - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 10) - // The delivered order should be the same as processing order. - for i, block := range delivered { - if i > 1 { - s.Equal(delivered[i-1].Finalization.Height+1, - delivered[i].Finalization.Height) - s.Equal(delivered[i-1].Hash, - delivered[i].Finalization.ParentHash) - } - s.Equal(block.Hash, blocks[i].Hash) - } -} - -func (s *CompactionChainTestSuite) TestMissedRandomness() { - // This test case makes sure a block's randomness field can be fulfilled by - // calling: - // - core.compactionChain.processBlockRandomnessResult - // - core.compactionChain.processFinalizedBlock - cc, _ := s.newCompactionChain() - s.Require().Equal(uint32(4), cc.gov.Configuration(uint64(0)).NumChains) - blocks := make([]*types.Block, 10) - for idx := range blocks { - blocks[idx] = &types.Block{ - Hash: common.NewRandomHash(), - Position: types.Position{ - Round: 1, - Height: uint64(idx / 4), - ChainID: uint32(idx % 4), - }, - } - s.Require().False(cc.blockRegistered(blocks[idx].Hash)) - cc.registerBlock(blocks[idx]) - s.Require().True(cc.blockRegistered(blocks[idx].Hash)) - } - noRandBlocks := common.Hashes{} - // Block#4, #5, contains randomness. - for i := range blocks { - s.Require().NoError(cc.processBlock(blocks[i])) - if i >= 4 && i < 6 { - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } else { - noRandBlocks = append(noRandBlocks, blocks[i].Hash) - } - } - s.Equal(noRandBlocks, cc.pendingBlocksWithoutRandomness()) - s.Require().Len(cc.extractBlocks(), 0) - // Give compactionChain module randomnessResult via finalized block - // #0, #1, #2, #3, #4. - for i := range blocks { - if i >= 4 { - break - } - block := blocks[i].Clone() - h := common.NewRandomHash() - block.Finalization.Randomness = h[:] - block.Finalization.Height = uint64(i + 1) - cc.processFinalizedBlock(block) - } - // Block #0-3 has randomness result. - noRandBlocks = noRandBlocks[4:] - s.Equal(noRandBlocks, cc.pendingBlocksWithoutRandomness()) - delivered := cc.extractBlocks() - s.Require().Len(delivered, 6) - // Give compactionChain module randomnessResult#6-9. - for i := 6; i < 10; i++ { - h := common.NewRandomHash() - s.Require().NoError(cc.processBlockRandomnessResult( - &types.BlockRandomnessResult{ - BlockHash: blocks[i].Hash, - Position: blocks[i].Position, - Randomness: h[:], - })) - } - s.Len(cc.pendingBlocksWithoutRandomness(), 0) - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 10) - // The delivered order should be the same as processing order. - for i, block := range delivered { - if i > 1 { - s.Equal(delivered[i-1].Finalization.Height+1, - delivered[i].Finalization.Height) - s.Equal(delivered[i-1].Hash, - delivered[i].Finalization.ParentHash) - } - s.Equal(block.Hash, blocks[i].Hash) - } -} - -func (s *CompactionChainTestSuite) TestExtractBlocksRound0() { - cc, _ := s.newCompactionChain() - s.Require().Equal(uint32(4), cc.gov.Configuration(uint64(0)).NumChains) - blocks := make([]*types.Block, 10) - for idx := range blocks { - blocks[idx] = &types.Block{ - Hash: common.NewRandomHash(), - Position: types.Position{ - Round: 0, - }, - } - s.Require().False(cc.blockRegistered(blocks[idx].Hash)) - cc.registerBlock(blocks[idx]) - s.Require().True(cc.blockRegistered(blocks[idx].Hash)) - } - // Round 0 should be able to be extracted without randomness. - for i := 0; i < 4; i++ { - s.Require().NoError(cc.processBlock(blocks[i])) - } - delivered := cc.extractBlocks() - s.Require().Len(delivered, 4) - // Round 0 should be able to be extracted without randomness. - for i := 4; i < 10; i++ { - s.Require().NoError(cc.processBlock(blocks[i])) - } - delivered = append(delivered, cc.extractBlocks()...) - s.Require().Len(delivered, 10) - // The delivered order should be the same as processing order. - for i, block := range delivered { - s.Equal(block.Hash, blocks[i].Hash) - } -} - -func (s *CompactionChainTestSuite) TestBootstrapSync() { - // This test case make sure compactionChain module would only deliver - // blocks unless tips of each chain are received, when this module is - // initialized with a block with finalizationHeight == 0. - cc, _ := s.newCompactionChain() - numChains := cc.gov.Configuration(uint64(0)).NumChains - s.Require().Equal(uint32(4), numChains) - now := time.Now().UTC() - blocks := make([]*types.Block, 20) - for idx := range blocks { - blocks[idx] = &types.Block{ - Hash: common.NewRandomHash(), - Position: types.Position{ - Height: uint64(idx) / uint64(numChains), - }, - Finalization: types.FinalizationResult{ - Timestamp: now, - Height: uint64(idx + 1), - }, - } - now = now.Add(100 * time.Millisecond) - } - s.Require().NoError(cc.processBlock(blocks[1])) - s.Len(cc.extractBlocks(), 0) - s.Require().NoError(cc.processBlock(blocks[2])) - s.Len(cc.extractBlocks(), 0) - // Although genesis block is received, we can't deliver them until tip blocks - // of each chain is received. - s.Require().NoError(cc.processBlock(blocks[0])) - s.Len(cc.extractBlocks(), 0) - // Once we receive the tip of chain#3 then we can deliver all tips. - s.Require().NoError(cc.processBlock(blocks[3])) - confirmed := cc.extractBlocks() - s.Require().Len(confirmed, 4) - s.Equal(confirmed[0].Hash, blocks[1].Hash) - s.Equal(blocks[1].Finalization.Height, uint64(1)) - s.Equal(confirmed[1].Hash, blocks[2].Hash) - s.Equal(blocks[2].Finalization.Height, uint64(2)) - s.Equal(confirmed[2].Hash, blocks[0].Hash) - s.Equal(blocks[0].Finalization.Height, uint64(3)) - s.Equal(confirmed[3].Hash, blocks[3].Hash) - s.Equal(blocks[3].Finalization.Height, uint64(4)) -} - -func TestCompactionChain(t *testing.T) { - suite.Run(t, new(CompactionChainTestSuite)) -} |