|
|
@@ -54,7 +54,7 @@ func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *B
|
|
|
)
|
|
|
|
|
|
// Initialize a fresh chain with only a genesis block
|
|
|
- blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
|
|
|
// Create and inject the requested chain
|
|
|
if n == 0 {
|
|
|
return db, blockchain, nil
|
|
|
@@ -509,7 +509,7 @@ func testReorgBadHashes(t *testing.T, full bool) {
|
|
|
blockchain.Stop()
|
|
|
|
|
|
// Create a new BlockChain and check that it rolled back the state.
|
|
|
- ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create new chain manager: %v", err)
|
|
|
}
|
|
|
@@ -621,7 +621,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|
|
// Import the chain as an archive node for the comparison baseline
|
|
|
archiveDb := rawdb.NewMemoryDatabase()
|
|
|
gspec.MustCommit(archiveDb)
|
|
|
- archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer archive.Stop()
|
|
|
|
|
|
if n, err := archive.InsertChain(blocks); err != nil {
|
|
|
@@ -630,7 +630,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|
|
// Fast import the chain as a non-archive node to test
|
|
|
fastDb := rawdb.NewMemoryDatabase()
|
|
|
gspec.MustCommit(fastDb)
|
|
|
- fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer fast.Stop()
|
|
|
|
|
|
headers := make([]*types.Header, len(blocks))
|
|
|
@@ -654,7 +654,7 @@ func TestFastVsFullChains(t *testing.T) {
|
|
|
t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
}
|
|
|
gspec.MustCommit(ancientDb)
|
|
|
- ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer ancient.Stop()
|
|
|
|
|
|
if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
|
|
|
@@ -750,7 +750,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|
|
// Import the chain as an archive node and ensure all pointers are updated
|
|
|
archiveDb, delfn := makeDb()
|
|
|
defer delfn()
|
|
|
- archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
if n, err := archive.InsertChain(blocks); err != nil {
|
|
|
t.Fatalf("failed to process block %d: %v", n, err)
|
|
|
}
|
|
|
@@ -763,7 +763,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|
|
// Import the chain as a non-archive node and ensure all pointers are updated
|
|
|
fastDb, delfn := makeDb()
|
|
|
defer delfn()
|
|
|
- fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer fast.Stop()
|
|
|
|
|
|
headers := make([]*types.Header, len(blocks))
|
|
|
@@ -783,7 +783,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|
|
// Import the chain as a ancient-first node and ensure all pointers are updated
|
|
|
ancientDb, delfn := makeDb()
|
|
|
defer delfn()
|
|
|
- ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer ancient.Stop()
|
|
|
|
|
|
if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
|
|
|
@@ -802,7 +802,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
|
|
|
// Import the chain as a light node and ensure all pointers are updated
|
|
|
lightDb, delfn := makeDb()
|
|
|
defer delfn()
|
|
|
- light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
|
|
|
t.Fatalf("failed to insert header %d: %v", n, err)
|
|
|
}
|
|
|
@@ -871,7 +871,7 @@ func TestChainTxReorgs(t *testing.T) {
|
|
|
}
|
|
|
})
|
|
|
// Import the chain. This runs all block validation rules.
|
|
|
- blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
if i, err := blockchain.InsertChain(chain); err != nil {
|
|
|
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
|
|
|
}
|
|
|
@@ -941,7 +941,7 @@ func TestLogReorgs(t *testing.T) {
|
|
|
signer = types.NewEIP155Signer(gspec.Config.ChainID)
|
|
|
)
|
|
|
|
|
|
- blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
rmLogsCh := make(chan RemovedLogsEvent)
|
|
|
@@ -996,6 +996,7 @@ func TestLogRebirth(t *testing.T) {
|
|
|
engine = ethash.NewFaker()
|
|
|
blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil)
|
|
|
)
|
|
|
+
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
// The event channels.
|
|
|
@@ -1058,6 +1059,7 @@ func TestSideLogRebirth(t *testing.T) {
|
|
|
signer = types.NewEIP155Signer(gspec.Config.ChainID)
|
|
|
blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
)
|
|
|
+
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
newLogCh := make(chan []*types.Log, 10)
|
|
|
@@ -1130,7 +1132,7 @@ func TestReorgSideEvent(t *testing.T) {
|
|
|
signer = types.NewEIP155Signer(gspec.Config.ChainID)
|
|
|
)
|
|
|
|
|
|
- blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
|
|
|
@@ -1262,7 +1264,7 @@ func TestEIP155Transition(t *testing.T) {
|
|
|
genesis = gspec.MustCommit(db)
|
|
|
)
|
|
|
|
|
|
- blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
|
|
|
@@ -1370,7 +1372,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
|
|
|
}
|
|
|
genesis = gspec.MustCommit(db)
|
|
|
)
|
|
|
- blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer blockchain.Stop()
|
|
|
|
|
|
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
|
|
|
@@ -1445,7 +1447,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1489,7 +1491,7 @@ func TestTrieForkGC(t *testing.T) {
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1528,7 +1530,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1588,7 +1590,7 @@ func TestBlockchainRecovery(t *testing.T) {
|
|
|
t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
}
|
|
|
gspec.MustCommit(ancientDb)
|
|
|
- ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
|
|
|
headers := make([]*types.Header, len(blocks))
|
|
|
for i, block := range blocks {
|
|
|
@@ -1607,7 +1609,7 @@ func TestBlockchainRecovery(t *testing.T) {
|
|
|
rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
|
|
|
|
|
|
// Reopen broken blockchain again
|
|
|
- ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer ancient.Stop()
|
|
|
if num := ancient.CurrentBlock().NumberU64(); num != 0 {
|
|
|
t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
|
|
|
@@ -1644,7 +1646,7 @@ func TestIncompleteAncientReceiptChainInsertion(t *testing.T) {
|
|
|
t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
}
|
|
|
gspec.MustCommit(ancientDb)
|
|
|
- ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
|
|
|
+ ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
|
|
|
defer ancient.Stop()
|
|
|
|
|
|
headers := make([]*types.Header, len(blocks))
|
|
|
@@ -1701,7 +1703,7 @@ func TestLowDiffLongChain(t *testing.T) {
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1748,7 +1750,7 @@ func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommon
|
|
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1845,7 +1847,7 @@ func testInsertKnownChainData(t *testing.T, typ string) {
|
|
|
new(Genesis).MustCommit(chaindb)
|
|
|
defer os.RemoveAll(dir)
|
|
|
|
|
|
- chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -1961,7 +1963,7 @@ func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, error
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -2065,6 +2067,219 @@ func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func TestTransactionIndices(t *testing.T) {
|
|
|
+ // Configure and generate a sample block chain
|
|
|
+ var (
|
|
|
+ gendb = rawdb.NewMemoryDatabase()
|
|
|
+ key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
|
|
+ address = crypto.PubkeyToAddress(key.PublicKey)
|
|
|
+ funds = big.NewInt(1000000000)
|
|
|
+ gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
|
|
|
+ genesis = gspec.MustCommit(gendb)
|
|
|
+ signer = types.NewEIP155Signer(gspec.Config.ChainID)
|
|
|
+ )
|
|
|
+ height := uint64(128)
|
|
|
+ blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
|
|
|
+ tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ block.AddTx(tx)
|
|
|
+ })
|
|
|
+ blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], ethash.NewFaker(), gendb, 10, nil)
|
|
|
+
|
|
|
+ check := func(tail *uint64, chain *BlockChain) {
|
|
|
+ stored := rawdb.ReadTxIndexTail(chain.db)
|
|
|
+ if tail == nil && stored != nil {
|
|
|
+ t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
|
|
|
+ }
|
|
|
+ if tail != nil && *stored != *tail {
|
|
|
+ t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
|
|
|
+ }
|
|
|
+ if tail != nil {
|
|
|
+ for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
|
|
|
+ block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
|
|
|
+ if block.Transactions().Len() == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, tx := range block.Transactions() {
|
|
|
+ if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
|
|
|
+ t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for i := uint64(0); i < *tail; i++ {
|
|
|
+ block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
|
|
|
+ if block.Transactions().Len() == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, tx := range block.Transactions() {
|
|
|
+ if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
|
|
|
+ t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ frdir, err := ioutil.TempDir("", "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer dir: %v", err)
|
|
|
+ }
|
|
|
+ defer os.Remove(frdir)
|
|
|
+ ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
+ }
|
|
|
+ gspec.MustCommit(ancientDb)
|
|
|
+
|
|
|
+ // Import all blocks into ancient db
|
|
|
+ l := uint64(0)
|
|
|
+ chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create tester chain: %v", err)
|
|
|
+ }
|
|
|
+ headers := make([]*types.Header, len(blocks))
|
|
|
+ for i, block := range blocks {
|
|
|
+ headers[i] = block.Header()
|
|
|
+ }
|
|
|
+ if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
|
|
|
+ t.Fatalf("failed to insert header %d: %v", n, err)
|
|
|
+ }
|
|
|
+ if n, err := chain.InsertReceiptChain(blocks, receipts, 128); err != nil {
|
|
|
+ t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
|
|
+ }
|
|
|
+ chain.Stop()
|
|
|
+ ancientDb.Close()
|
|
|
+
|
|
|
+ // Init block chain with external ancients, check all needed indices has been indexed.
|
|
|
+ limit := []uint64{0, 32, 64, 128}
|
|
|
+ for _, l := range limit {
|
|
|
+ ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
+ }
|
|
|
+ gspec.MustCommit(ancientDb)
|
|
|
+ chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create tester chain: %v", err)
|
|
|
+ }
|
|
|
+ time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
|
|
|
+ var tail uint64
|
|
|
+ if l != 0 {
|
|
|
+ tail = uint64(128) - l + 1
|
|
|
+ }
|
|
|
+ check(&tail, chain)
|
|
|
+ chain.Stop()
|
|
|
+ ancientDb.Close()
|
|
|
+ }
|
|
|
+
|
|
|
+ // Reconstruct a block chain which only reserves HEAD-64 tx indices
|
|
|
+ ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
+ }
|
|
|
+ gspec.MustCommit(ancientDb)
|
|
|
+
|
|
|
+ limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
|
|
|
+ tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
|
|
|
+ for i, l := range limit {
|
|
|
+ chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create tester chain: %v", err)
|
|
|
+ }
|
|
|
+ chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
|
|
|
+ time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
|
|
|
+ check(&tails[i], chain)
|
|
|
+ chain.Stop()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func TestSkipStaleTxIndicesInFastSync(t *testing.T) {
|
|
|
+ // Configure and generate a sample block chain
|
|
|
+ var (
|
|
|
+ gendb = rawdb.NewMemoryDatabase()
|
|
|
+ key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
|
|
+ address = crypto.PubkeyToAddress(key.PublicKey)
|
|
|
+ funds = big.NewInt(1000000000)
|
|
|
+ gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
|
|
|
+ genesis = gspec.MustCommit(gendb)
|
|
|
+ signer = types.NewEIP155Signer(gspec.Config.ChainID)
|
|
|
+ )
|
|
|
+ height := uint64(128)
|
|
|
+ blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
|
|
|
+ tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
|
|
|
+ if err != nil {
|
|
|
+ panic(err)
|
|
|
+ }
|
|
|
+ block.AddTx(tx)
|
|
|
+ })
|
|
|
+
|
|
|
+ check := func(tail *uint64, chain *BlockChain) {
|
|
|
+ stored := rawdb.ReadTxIndexTail(chain.db)
|
|
|
+ if tail == nil && stored != nil {
|
|
|
+ t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
|
|
|
+ }
|
|
|
+ if tail != nil && *stored != *tail {
|
|
|
+ t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
|
|
|
+ }
|
|
|
+ if tail != nil {
|
|
|
+ for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
|
|
|
+ block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
|
|
|
+ if block.Transactions().Len() == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, tx := range block.Transactions() {
|
|
|
+ if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
|
|
|
+ t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for i := uint64(0); i < *tail; i++ {
|
|
|
+ block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
|
|
|
+ if block.Transactions().Len() == 0 {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ for _, tx := range block.Transactions() {
|
|
|
+ if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
|
|
|
+ t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ frdir, err := ioutil.TempDir("", "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer dir: %v", err)
|
|
|
+ }
|
|
|
+ defer os.Remove(frdir)
|
|
|
+ ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "")
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create temp freezer db: %v", err)
|
|
|
+ }
|
|
|
+ gspec.MustCommit(ancientDb)
|
|
|
+
|
|
|
+ // Import all blocks into ancient db, only HEAD-32 indices are kept.
|
|
|
+ l := uint64(32)
|
|
|
+ chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create tester chain: %v", err)
|
|
|
+ }
|
|
|
+ headers := make([]*types.Header, len(blocks))
|
|
|
+ for i, block := range blocks {
|
|
|
+ headers[i] = block.Header()
|
|
|
+ }
|
|
|
+ if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
|
|
|
+ t.Fatalf("failed to insert header %d: %v", n, err)
|
|
|
+ }
|
|
|
+ // The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
|
|
|
+ if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
|
|
|
+ t.Fatalf("block %d: failed to insert into chain: %v", n, err)
|
|
|
+ }
|
|
|
+ tail := uint64(32)
|
|
|
+ check(&tail, chain)
|
|
|
+}
|
|
|
+
|
|
|
// Benchmarks large blocks with value transfers to non-existing accounts
|
|
|
func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
|
|
|
var (
|
|
|
@@ -2110,7 +2325,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
gspec.MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
b.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -2192,7 +2407,7 @@ func TestSideImportPrunedBlocks(t *testing.T) {
|
|
|
blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
new(Genesis).MustCommit(diskdb)
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|
|
|
@@ -2286,7 +2501,7 @@ func TestDeleteCreateRevert(t *testing.T) {
|
|
|
diskdb := rawdb.NewMemoryDatabase()
|
|
|
gspec.MustCommit(diskdb)
|
|
|
|
|
|
- chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
|
|
|
+ chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to create tester chain: %v", err)
|
|
|
}
|