diff options
author | Martin Holst Swende <martin@swende.se> | 2019-02-21 18:36:49 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-02-21 18:36:49 +0800 |
commit | 8577b5b020d963ef9972981bbfc62b8930d3e9c9 (patch) | |
tree | 2cc991813e966eb7755c4f0a27adf68cb766bbd4 /core/blockchain_test.go | |
parent | 628a0bde3f6667a00cd857c4f5143cb31f038615 (diff) | |
download | go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar.gz go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar.bz2 go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar.lz go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar.xz go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.tar.zst go-tangerine-8577b5b020d963ef9972981bbfc62b8930d3e9c9.zip |
core: more tests for sidechain import, fixes #19105 (#19113)
* blockchain: more tests for sidechain import, fixes #19105
* core/blockchain: rework import of pruned canon blocks and canon-prepended sidechains
* core/blockchain: minor clarity change
* core/blockchain: remove unused method
Diffstat (limited to 'core/blockchain_test.go')
-rw-r--r-- | core/blockchain_test.go | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/core/blockchain_test.go b/core/blockchain_test.go index a16b3ba8a..1ac7b03fc 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1521,3 +1521,85 @@ func TestLowDiffLongChain(t *testing.T) { header = chain.GetHeader(header.ParentHash, number-1) } } + +// Tests that importing a sidechain (S), where +// - S is sidechain, containing blocks [Sn...Sm] +// - C is canon chain, containing blocks [G..Cn..Cm] +// - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock +// - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain +func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int) { + + // Generate a canonical chain to act as the main dataset + engine := ethash.NewFaker() + db := ethdb.NewMemDatabase() + genesis := new(Genesis).MustCommit(db) + + // Generate and import the canonical chain + blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, nil) + diskdb := ethdb.NewMemDatabase() + new(Genesis).MustCommit(diskdb) + chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + if n, err := chain.InsertChain(blocks); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + lastPrunedIndex := len(blocks) - triesInMemory - 1 + lastPrunedBlock := blocks[lastPrunedIndex] + firstNonPrunedBlock := blocks[len(blocks)-triesInMemory] + + // Verify pruning of lastPrunedBlock + if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) { + t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64()) + } + // Verify firstNonPrunedBlock is not pruned + if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) { + t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64()) + } + // Generate the sidechain + // First block should be a known block, block after should be a pruned block. So + // canon(pruned), side, side... + + // Generate fork chain, make it longer than canon + parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock + parent := blocks[parentIndex] + fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { + b.SetCoinbase(common.Address{2}) + }) + // Prepend the parent(s) + var sidechain []*types.Block + for i := numCanonBlocksInSidechain; i > 0; i-- { + sidechain = append(sidechain, blocks[parentIndex+1-i]) + } + sidechain = append(sidechain, fork...) + _, err = chain.InsertChain(sidechain) + if err != nil { + t.Errorf("Got error, %v", err) + } + head := chain.CurrentBlock() + if got := fork[len(fork)-1].Hash(); got != head.Hash() { + t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) + } +} + +// Tests that importing a sidechain (S), where +// - S is sidechain, containing blocks [Sn...Sm] +// - C is canon chain, containing blocks [G..Cn..Cm] +// - The common ancestor Cc is pruned +// - The first block in S: Sn, is == Cn +// That is: the sidechain for import contains some blocks already present in canon chain. +// So the blocks are +// [ Cn, Cn+1, Cc, Sn+3 ... Sm] +// ^ ^ ^ pruned +func TestPrunedImportSide(t *testing.T) { + //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) + //glogger.Verbosity(3) + //log.Root().SetHandler(log.Handler(glogger)) + testSideImport(t, 3, 3) + testSideImport(t, 3, -3) + testSideImport(t, 10, 0) + testSideImport(t, 1, 10) + testSideImport(t, 1, -10) +} |