diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2019-03-26 16:55:16 +0800 |
---|---|---|
committer | Jimmy Hu <jimmy.hu@dexon.org> | 2019-03-27 15:25:10 +0800 |
commit | 495b3737414685d609f7b41355928c699189d6ad (patch) | |
tree | 70e648db3dff486a56a64bb61b7ef53f46ab1372 /core/blockchain_test.go | |
parent | 7783bc4ba52bfc534d5b4d91e78abb2ddad7d078 (diff) | |
download | tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar.gz tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar.bz2 tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar.lz tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar.xz tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.tar.zst tangerine-consensus-495b3737414685d609f7b41355928c699189d6ad.zip |
core: sign block hash for empty block (#517)
* core: sign block hash for empty block
* run force synced empty block at startup
Diffstat (limited to 'core/blockchain_test.go')
-rw-r--r-- | core/blockchain_test.go | 111 |
1 files changed, 109 insertions, 2 deletions
diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 6a615c1..1e3f184 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -18,6 +18,7 @@ package core import ( + "fmt" "testing" "time" @@ -125,6 +126,15 @@ func (s *BlockChainTestSuite) newBlock(parent *types.Block, round uint64, return b } +func (s *BlockChainTestSuite) newRandomnessFromBlock( + b *types.Block) *types.AgreementResult { + return &types.AgreementResult{ + BlockHash: b.Hash, + Position: b.Position, + Randomness: common.GenerateRandomBytes(), + } +} + func (s *BlockChainTestSuite) newBlockChain(initB *types.Block, roundLength uint64) (bc *blockChain) { initRound := uint64(0) @@ -159,6 +169,64 @@ func (s *BlockChainTestSuite) newRoundOneInitBlock() *types.Block { return initBlock } +func (s *BlockChainTestSuite) baseConcurrentAceessTest(initBlock *types.Block, + blocks []*types.Block, rands []*types.AgreementResult) { + var ( + bc = s.newBlockChain(initBlock, uint64(len(blocks)+1)) + start = make(chan struct{}) + newNotif = make(chan struct{}, 1) + delivered []*types.Block + ) + add := func(v interface{}) { + <-start + switch val := v.(type) { + case *types.Block: + if err := bc.addBlock(val); err != nil { + // Never assertion in sub routine when testing. + panic(err) + } + case *types.AgreementResult: + if err := bc.processAgreementResult(val); err != nil { + // Never assertion in sub routine when testing. + panic(err) + } + default: + panic(fmt.Errorf("unknown type: %v", v)) + } + select { + case newNotif <- struct{}{}: + default: + } + } + for _, b := range blocks { + go add(b) + } + for _, r := range rands { + go add(r) + } + close(start) + for { + select { + case <-newNotif: + delivered = append(delivered, bc.extractBlocks()...) + case <-time.After(100 * time.Millisecond): + delivered = append(delivered, bc.extractBlocks()...) + } + if len(delivered) == len(blocks) { + break + } + } + // Check result. + b := delivered[0] + s.Require().Equal(b.Position.Height, uint64(1)) + s.Require().NotEmpty(b.Finalization.Randomness) + for _, bb := range delivered[1:] { + s.Require().Equal(b.Position.Height+1, bb.Position.Height) + s.Require().NotEmpty(b.Finalization.Randomness) + b = bb + } +} + func (s *BlockChainTestSuite) TestBasicUsage() { initBlock := s.newRoundOneInitBlock() bc := s.newBlockChain(initBlock, 10) @@ -185,12 +253,35 @@ func (s *BlockChainTestSuite) TestBasicUsage() { s.Require().NoError(bc.addBlock(b1)) s.Require().NoError(bc.addBlock(b0)) extracted := bc.extractBlocks() - s.Require().Len(extracted, 6) - s.Require().Equal(extracted[4].Hash, b4.Hash) + s.Require().Len(extracted, 4) + bc.pendingRandomnesses[b4.Position] = &types.AgreementResult{ + BlockHash: b4.Hash, + Randomness: common.GenerateRandomBytes(), + } + extracted = bc.extractBlocks() + s.Require().Len(extracted, 2) + s.Require().Equal(extracted[0].Hash, b4.Hash) extracted = bc.extractBlocks() s.Require().Len(extracted, 0) } +func (s *BlockChainTestSuite) TestConcurrentAccess() { + // Raise one go routine for each block and randomness. And let them try to + // add to blockChain at the same time. Make sure we can delivered them all. + var ( + retry = 10 + initBlock = s.newRoundOneInitBlock() + blocks = s.newBlocks(500, initBlock) + rands = []*types.AgreementResult{} + ) + for _, b := range blocks { + rands = append(rands, s.newRandomnessFromBlock(b)) + } + for i := 0; i < retry; i++ { + s.baseConcurrentAceessTest(initBlock, blocks, rands) + } +} + func (s *BlockChainTestSuite) TestSanityCheck() { bc := s.newBlockChain(nil, 4) // Empty block is not allowed. @@ -321,6 +412,22 @@ func (s *BlockChainTestSuite) TestNextBlockAndTipRound() { s.Require().Equal(bc.tipRound(), uint64(1)) } +func (s *BlockChainTestSuite) TestPendingBlocksWithoutRandomness() { + initBlock := s.newRoundOneInitBlock() + bc := s.newBlockChain(initBlock, 10) + b0, err := bc.addEmptyBlock(types.Position{Round: 1, Height: 1}) + s.Require().NoError(err) + b1, err := bc.addEmptyBlock(types.Position{Round: 1, Height: 2}) + s.Require().NoError(err) + b2, err := bc.addEmptyBlock(types.Position{Round: 1, Height: 3}) + s.Require().NoError(err) + s.Require().Equal(bc.pendingBlocksWithoutRandomness(), []*types.Block{ + b0, b1, b2}) + s.Require().NoError(bc.processAgreementResult(s.newRandomnessFromBlock(b0))) + s.Require().Equal(bc.pendingBlocksWithoutRandomness(), []*types.Block{ + b1, b2}) +} + func (s *BlockChainTestSuite) TestLastXBlock() { initBlock := s.newRoundOneInitBlock() bc := s.newBlockChain(initBlock, 10) |