1// Copyright 2014 The go-ethereum Authors
2// This file is part of the go-ethereum library.
3//
4// The go-ethereum library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU Lesser General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// The go-ethereum library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public License
15// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16
17package core
18
19import (
20	"errors"
21	"fmt"
22	"io/ioutil"
23	"math/big"
24	"math/rand"
25	"os"
26	"sync"
27	"testing"
28	"time"
29
30	"github.com/ethereum/go-ethereum/common"
31	"github.com/ethereum/go-ethereum/common/math"
32	"github.com/ethereum/go-ethereum/consensus"
33	"github.com/ethereum/go-ethereum/consensus/beacon"
34	"github.com/ethereum/go-ethereum/consensus/ethash"
35	"github.com/ethereum/go-ethereum/core/rawdb"
36	"github.com/ethereum/go-ethereum/core/state"
37	"github.com/ethereum/go-ethereum/core/types"
38	"github.com/ethereum/go-ethereum/core/vm"
39	"github.com/ethereum/go-ethereum/crypto"
40	"github.com/ethereum/go-ethereum/eth/tracers/logger"
41	"github.com/ethereum/go-ethereum/ethdb"
42	"github.com/ethereum/go-ethereum/params"
43	"github.com/ethereum/go-ethereum/trie"
44)
45
46// So we can deterministically seed different blockchains
47var (
48	canonicalSeed = 1
49	forkSeed      = 2
50)
51
52// newCanonical creates a chain database, and injects a deterministic canonical
53// chain. Depending on the full flag, if creates either a full block chain or a
54// header only chain.
55func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
56	var (
57		db      = rawdb.NewMemoryDatabase()
58		genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
59	)
60
61	// Initialize a fresh chain with only a genesis block
62	blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
63	// Create and inject the requested chain
64	if n == 0 {
65		return db, blockchain, nil
66	}
67	if full {
68		// Full block-chain requested
69		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
70		_, err := blockchain.InsertChain(blocks)
71		return db, blockchain, err
72	}
73	// Header-only chain requested
74	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
75	_, err := blockchain.InsertHeaderChain(headers, 1)
76	return db, blockchain, err
77}
78
79func newGwei(n int64) *big.Int {
80	return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei))
81}
82
83// Test fork of length N starting from block i
84func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
85	// Copy old chain up to #i into a new db
86	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
87	if err != nil {
88		t.Fatal("could not make new canonical in testFork", err)
89	}
90	defer blockchain2.Stop()
91
92	// Assert the chains have the same header/block at #i
93	var hash1, hash2 common.Hash
94	if full {
95		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
96		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
97	} else {
98		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
99		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
100	}
101	if hash1 != hash2 {
102		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
103	}
104	// Extend the newly created chain
105	var (
106		blockChainB  []*types.Block
107		headerChainB []*types.Header
108	)
109	if full {
110		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
111		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
112			t.Fatalf("failed to insert forking chain: %v", err)
113		}
114	} else {
115		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
116		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
117			t.Fatalf("failed to insert forking chain: %v", err)
118		}
119	}
120	// Sanity check that the forked chain can be imported into the original
121	var tdPre, tdPost *big.Int
122
123	if full {
124		cur := blockchain.CurrentBlock()
125		tdPre = blockchain.GetTd(cur.Hash(), cur.NumberU64())
126		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
127			t.Fatalf("failed to import forked block chain: %v", err)
128		}
129		last := blockChainB[len(blockChainB)-1]
130		tdPost = blockchain.GetTd(last.Hash(), last.NumberU64())
131	} else {
132		cur := blockchain.CurrentHeader()
133		tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64())
134		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
135			t.Fatalf("failed to import forked header chain: %v", err)
136		}
137		last := headerChainB[len(headerChainB)-1]
138		tdPost = blockchain.GetTd(last.Hash(), last.Number.Uint64())
139	}
140	// Compare the total difficulties of the chains
141	comparator(tdPre, tdPost)
142}
143
144// testBlockChainImport tries to process a chain of blocks, writing them into
145// the database if successful.
146func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
147	for _, block := range chain {
148		// Try and process the block
149		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
150		if err == nil {
151			err = blockchain.validator.ValidateBody(block)
152		}
153		if err != nil {
154			if err == ErrKnownBlock {
155				continue
156			}
157			return err
158		}
159		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
160		if err != nil {
161			return err
162		}
163		receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{})
164		if err != nil {
165			blockchain.reportBlock(block, receipts, err)
166			return err
167		}
168		err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
169		if err != nil {
170			blockchain.reportBlock(block, receipts, err)
171			return err
172		}
173
174		blockchain.chainmu.MustLock()
175		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash(), block.NumberU64()-1)))
176		rawdb.WriteBlock(blockchain.db, block)
177		statedb.Commit(false)
178		blockchain.chainmu.Unlock()
179	}
180	return nil
181}
182
183// testHeaderChainImport tries to process a chain of header, writing them into
184// the database if successful.
185func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
186	for _, header := range chain {
187		// Try and validate the header
188		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
189			return err
190		}
191		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
192		blockchain.chainmu.MustLock()
193		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTd(header.ParentHash, header.Number.Uint64()-1)))
194		rawdb.WriteHeader(blockchain.db, header)
195		blockchain.chainmu.Unlock()
196	}
197	return nil
198}
199
200func TestLastBlock(t *testing.T) {
201	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
202	if err != nil {
203		t.Fatalf("failed to create pristine chain: %v", err)
204	}
205	defer blockchain.Stop()
206
207	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
208	if _, err := blockchain.InsertChain(blocks); err != nil {
209		t.Fatalf("Failed to insert block: %v", err)
210	}
211	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
212		t.Fatalf("Write/Get HeadBlockHash failed")
213	}
214}
215
216// Test inserts the blocks/headers after the fork choice rule is changed.
217// The chain is reorged to whatever specified.
218func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full bool) {
219	// Copy old chain up to #i into a new db
220	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
221	if err != nil {
222		t.Fatal("could not make new canonical in testFork", err)
223	}
224	defer blockchain2.Stop()
225
226	// Assert the chains have the same header/block at #i
227	var hash1, hash2 common.Hash
228	if full {
229		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
230		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
231	} else {
232		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
233		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
234	}
235	if hash1 != hash2 {
236		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
237	}
238
239	// Extend the newly created chain
240	if full {
241		blockChainB := makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
242		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
243			t.Fatalf("failed to insert forking chain: %v", err)
244		}
245		if blockchain2.CurrentBlock().NumberU64() != blockChainB[len(blockChainB)-1].NumberU64() {
246			t.Fatalf("failed to reorg to the given chain")
247		}
248		if blockchain2.CurrentBlock().Hash() != blockChainB[len(blockChainB)-1].Hash() {
249			t.Fatalf("failed to reorg to the given chain")
250		}
251	} else {
252		headerChainB := makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
253		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
254			t.Fatalf("failed to insert forking chain: %v", err)
255		}
256		if blockchain2.CurrentHeader().Number.Uint64() != headerChainB[len(headerChainB)-1].Number.Uint64() {
257			t.Fatalf("failed to reorg to the given chain")
258		}
259		if blockchain2.CurrentHeader().Hash() != headerChainB[len(headerChainB)-1].Hash() {
260			t.Fatalf("failed to reorg to the given chain")
261		}
262	}
263}
264
265// Tests that given a starting canonical chain of a given size, it can be extended
266// with various length chains.
267func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
268func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
269
270func testExtendCanonical(t *testing.T, full bool) {
271	length := 5
272
273	// Make first chain starting from genesis
274	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
275	if err != nil {
276		t.Fatalf("failed to make new canonical chain: %v", err)
277	}
278	defer processor.Stop()
279
280	// Define the difficulty comparator
281	better := func(td1, td2 *big.Int) {
282		if td2.Cmp(td1) <= 0 {
283			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
284		}
285	}
286	// Start fork from current height
287	testFork(t, processor, length, 1, full, better)
288	testFork(t, processor, length, 2, full, better)
289	testFork(t, processor, length, 5, full, better)
290	testFork(t, processor, length, 10, full, better)
291}
292
293// Tests that given a starting canonical chain of a given size, it can be extended
294// with various length chains.
295func TestExtendCanonicalHeadersAfterMerge(t *testing.T) { testExtendCanonicalAfterMerge(t, false) }
296func TestExtendCanonicalBlocksAfterMerge(t *testing.T)  { testExtendCanonicalAfterMerge(t, true) }
297
298func testExtendCanonicalAfterMerge(t *testing.T, full bool) {
299	length := 5
300
301	// Make first chain starting from genesis
302	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
303	if err != nil {
304		t.Fatalf("failed to make new canonical chain: %v", err)
305	}
306	defer processor.Stop()
307
308	testInsertAfterMerge(t, processor, length, 1, full)
309	testInsertAfterMerge(t, processor, length, 10, full)
310}
311
312// Tests that given a starting canonical chain of a given size, creating shorter
313// forks do not take canonical ownership.
314func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
315func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
316
317func testShorterFork(t *testing.T, full bool) {
318	length := 10
319
320	// Make first chain starting from genesis
321	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
322	if err != nil {
323		t.Fatalf("failed to make new canonical chain: %v", err)
324	}
325	defer processor.Stop()
326
327	// Define the difficulty comparator
328	worse := func(td1, td2 *big.Int) {
329		if td2.Cmp(td1) >= 0 {
330			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
331		}
332	}
333	// Sum of numbers must be less than `length` for this to be a shorter fork
334	testFork(t, processor, 0, 3, full, worse)
335	testFork(t, processor, 0, 7, full, worse)
336	testFork(t, processor, 1, 1, full, worse)
337	testFork(t, processor, 1, 7, full, worse)
338	testFork(t, processor, 5, 3, full, worse)
339	testFork(t, processor, 5, 4, full, worse)
340}
341
342// Tests that given a starting canonical chain of a given size, creating shorter
343// forks do not take canonical ownership.
344func TestShorterForkHeadersAfterMerge(t *testing.T) { testShorterForkAfterMerge(t, false) }
345func TestShorterForkBlocksAfterMerge(t *testing.T)  { testShorterForkAfterMerge(t, true) }
346
347func testShorterForkAfterMerge(t *testing.T, full bool) {
348	length := 10
349
350	// Make first chain starting from genesis
351	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
352	if err != nil {
353		t.Fatalf("failed to make new canonical chain: %v", err)
354	}
355	defer processor.Stop()
356
357	testInsertAfterMerge(t, processor, 0, 3, full)
358	testInsertAfterMerge(t, processor, 0, 7, full)
359	testInsertAfterMerge(t, processor, 1, 1, full)
360	testInsertAfterMerge(t, processor, 1, 7, full)
361	testInsertAfterMerge(t, processor, 5, 3, full)
362	testInsertAfterMerge(t, processor, 5, 4, full)
363}
364
365// Tests that given a starting canonical chain of a given size, creating longer
366// forks do take canonical ownership.
367func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
368func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
369
370func testLongerFork(t *testing.T, full bool) {
371	length := 10
372
373	// Make first chain starting from genesis
374	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
375	if err != nil {
376		t.Fatalf("failed to make new canonical chain: %v", err)
377	}
378	defer processor.Stop()
379
380	testInsertAfterMerge(t, processor, 0, 11, full)
381	testInsertAfterMerge(t, processor, 0, 15, full)
382	testInsertAfterMerge(t, processor, 1, 10, full)
383	testInsertAfterMerge(t, processor, 1, 12, full)
384	testInsertAfterMerge(t, processor, 5, 6, full)
385	testInsertAfterMerge(t, processor, 5, 8, full)
386}
387
388// Tests that given a starting canonical chain of a given size, creating longer
389// forks do take canonical ownership.
390func TestLongerForkHeadersAfterMerge(t *testing.T) { testLongerForkAfterMerge(t, false) }
391func TestLongerForkBlocksAfterMerge(t *testing.T)  { testLongerForkAfterMerge(t, true) }
392
393func testLongerForkAfterMerge(t *testing.T, full bool) {
394	length := 10
395
396	// Make first chain starting from genesis
397	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
398	if err != nil {
399		t.Fatalf("failed to make new canonical chain: %v", err)
400	}
401	defer processor.Stop()
402
403	testInsertAfterMerge(t, processor, 0, 11, full)
404	testInsertAfterMerge(t, processor, 0, 15, full)
405	testInsertAfterMerge(t, processor, 1, 10, full)
406	testInsertAfterMerge(t, processor, 1, 12, full)
407	testInsertAfterMerge(t, processor, 5, 6, full)
408	testInsertAfterMerge(t, processor, 5, 8, full)
409}
410
411// Tests that given a starting canonical chain of a given size, creating equal
412// forks do take canonical ownership.
413func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
414func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
415
416func testEqualFork(t *testing.T, full bool) {
417	length := 10
418
419	// Make first chain starting from genesis
420	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
421	if err != nil {
422		t.Fatalf("failed to make new canonical chain: %v", err)
423	}
424	defer processor.Stop()
425
426	// Define the difficulty comparator
427	equal := func(td1, td2 *big.Int) {
428		if td2.Cmp(td1) != 0 {
429			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
430		}
431	}
432	// Sum of numbers must be equal to `length` for this to be an equal fork
433	testFork(t, processor, 0, 10, full, equal)
434	testFork(t, processor, 1, 9, full, equal)
435	testFork(t, processor, 2, 8, full, equal)
436	testFork(t, processor, 5, 5, full, equal)
437	testFork(t, processor, 6, 4, full, equal)
438	testFork(t, processor, 9, 1, full, equal)
439}
440
441// Tests that given a starting canonical chain of a given size, creating equal
442// forks do take canonical ownership.
443func TestEqualForkHeadersAfterMerge(t *testing.T) { testEqualForkAfterMerge(t, false) }
444func TestEqualForkBlocksAfterMerge(t *testing.T)  { testEqualForkAfterMerge(t, true) }
445
446func testEqualForkAfterMerge(t *testing.T, full bool) {
447	length := 10
448
449	// Make first chain starting from genesis
450	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
451	if err != nil {
452		t.Fatalf("failed to make new canonical chain: %v", err)
453	}
454	defer processor.Stop()
455
456	testInsertAfterMerge(t, processor, 0, 10, full)
457	testInsertAfterMerge(t, processor, 1, 9, full)
458	testInsertAfterMerge(t, processor, 2, 8, full)
459	testInsertAfterMerge(t, processor, 5, 5, full)
460	testInsertAfterMerge(t, processor, 6, 4, full)
461	testInsertAfterMerge(t, processor, 9, 1, full)
462}
463
464// Tests that chains missing links do not get accepted by the processor.
465func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
466func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
467
468func testBrokenChain(t *testing.T, full bool) {
469	// Make chain starting from genesis
470	db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full)
471	if err != nil {
472		t.Fatalf("failed to make new canonical chain: %v", err)
473	}
474	defer blockchain.Stop()
475
476	// Create a forked chain, and try to insert with a missing link
477	if full {
478		chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
479		if err := testBlockChainImport(chain, blockchain); err == nil {
480			t.Errorf("broken block chain not reported")
481		}
482	} else {
483		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:]
484		if err := testHeaderChainImport(chain, blockchain); err == nil {
485			t.Errorf("broken header chain not reported")
486		}
487	}
488}
489
490// Tests that reorganising a long difficult chain after a short easy one
491// overwrites the canonical numbers and links in the database.
492func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
493func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
494
495func testReorgLong(t *testing.T, full bool) {
496	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280+params.GenesisDifficulty.Int64(), full)
497}
498
499// Tests that reorganising a short difficult chain after a long easy one
500// overwrites the canonical numbers and links in the database.
501func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
502func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
503
504func testReorgShort(t *testing.T, full bool) {
505	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
506	// we need a fairly long chain of blocks with different difficulties for a short
507	// one to become heavyer than a long one. The 96 is an empirical value.
508	easy := make([]int64, 96)
509	for i := 0; i < len(easy); i++ {
510		easy[i] = 60
511	}
512	diff := make([]int64, len(easy)-1)
513	for i := 0; i < len(diff); i++ {
514		diff[i] = -9
515	}
516	testReorg(t, easy, diff, 12615120+params.GenesisDifficulty.Int64(), full)
517}
518
519func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
520	// Create a pristine chain and database
521	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
522	if err != nil {
523		t.Fatalf("failed to create pristine chain: %v", err)
524	}
525	defer blockchain.Stop()
526
527	// Insert an easy and a difficult chain afterwards
528	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
529		b.OffsetTime(first[i])
530	})
531	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
532		b.OffsetTime(second[i])
533	})
534	if full {
535		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
536			t.Fatalf("failed to insert easy chain: %v", err)
537		}
538		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
539			t.Fatalf("failed to insert difficult chain: %v", err)
540		}
541	} else {
542		easyHeaders := make([]*types.Header, len(easyBlocks))
543		for i, block := range easyBlocks {
544			easyHeaders[i] = block.Header()
545		}
546		diffHeaders := make([]*types.Header, len(diffBlocks))
547		for i, block := range diffBlocks {
548			diffHeaders[i] = block.Header()
549		}
550		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
551			t.Fatalf("failed to insert easy chain: %v", err)
552		}
553		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
554			t.Fatalf("failed to insert difficult chain: %v", err)
555		}
556	}
557	// Check that the chain is valid number and link wise
558	if full {
559		prev := blockchain.CurrentBlock()
560		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
561			if prev.ParentHash() != block.Hash() {
562				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
563			}
564		}
565	} else {
566		prev := blockchain.CurrentHeader()
567		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
568			if prev.ParentHash != header.Hash() {
569				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
570			}
571		}
572	}
573	// Make sure the chain total difficulty is the correct one
574	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
575	if full {
576		cur := blockchain.CurrentBlock()
577		if have := blockchain.GetTd(cur.Hash(), cur.NumberU64()); have.Cmp(want) != 0 {
578			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
579		}
580	} else {
581		cur := blockchain.CurrentHeader()
582		if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 {
583			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
584		}
585	}
586}
587
588// Tests that the insertion functions detect banned hashes.
589func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
590func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
591
592func testBadHashes(t *testing.T, full bool) {
593	// Create a pristine chain and database
594	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
595	if err != nil {
596		t.Fatalf("failed to create pristine chain: %v", err)
597	}
598	defer blockchain.Stop()
599
600	// Create a chain, ban a hash and try to import
601	if full {
602		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
603
604		BadHashes[blocks[2].Header().Hash()] = true
605		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
606
607		_, err = blockchain.InsertChain(blocks)
608	} else {
609		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10)
610
611		BadHashes[headers[2].Hash()] = true
612		defer func() { delete(BadHashes, headers[2].Hash()) }()
613
614		_, err = blockchain.InsertHeaderChain(headers, 1)
615	}
616	if !errors.Is(err, ErrBannedHash) {
617		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBannedHash)
618	}
619}
620
621// Tests that bad hashes are detected on boot, and the chain rolled back to a
622// good state prior to the bad hash.
623func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
624func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
625
626func testReorgBadHashes(t *testing.T, full bool) {
627	// Create a pristine chain and database
628	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
629	if err != nil {
630		t.Fatalf("failed to create pristine chain: %v", err)
631	}
632	// Create a chain, import and ban afterwards
633	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
634	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
635
636	if full {
637		if _, err = blockchain.InsertChain(blocks); err != nil {
638			t.Errorf("failed to import blocks: %v", err)
639		}
640		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
641			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
642		}
643		BadHashes[blocks[3].Header().Hash()] = true
644		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
645	} else {
646		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
647			t.Errorf("failed to import headers: %v", err)
648		}
649		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
650			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
651		}
652		BadHashes[headers[3].Hash()] = true
653		defer func() { delete(BadHashes, headers[3].Hash()) }()
654	}
655	blockchain.Stop()
656
657	// Create a new BlockChain and check that it rolled back the state.
658	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
659	if err != nil {
660		t.Fatalf("failed to create new chain manager: %v", err)
661	}
662	if full {
663		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
664			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
665		}
666		if blocks[2].Header().GasLimit != ncm.GasLimit() {
667			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
668		}
669	} else {
670		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
671			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
672		}
673	}
674	ncm.Stop()
675}
676
677// Tests chain insertions in the face of one entity containing an invalid nonce.
678func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
679func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
680
681func testInsertNonceError(t *testing.T, full bool) {
682	for i := 1; i < 25 && !t.Failed(); i++ {
683		// Create a pristine chain and database
684		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
685		if err != nil {
686			t.Fatalf("failed to create pristine chain: %v", err)
687		}
688		defer blockchain.Stop()
689
690		// Create and insert a chain with a failing nonce
691		var (
692			failAt  int
693			failRes int
694			failNum uint64
695		)
696		if full {
697			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
698
699			failAt = rand.Int() % len(blocks)
700			failNum = blocks[failAt].NumberU64()
701
702			blockchain.engine = ethash.NewFakeFailer(failNum)
703			failRes, err = blockchain.InsertChain(blocks)
704		} else {
705			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
706
707			failAt = rand.Int() % len(headers)
708			failNum = headers[failAt].Number.Uint64()
709
710			blockchain.engine = ethash.NewFakeFailer(failNum)
711			blockchain.hc.engine = blockchain.engine
712			failRes, err = blockchain.InsertHeaderChain(headers, 1)
713		}
714		// Check that the returned error indicates the failure
715		if failRes != failAt {
716			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
717		}
718		// Check that all blocks after the failing block have been inserted
719		for j := 0; j < i-failAt; j++ {
720			if full {
721				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
722					t.Errorf("test %d: invalid block in chain: %v", i, block)
723				}
724			} else {
725				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
726					t.Errorf("test %d: invalid header in chain: %v", i, header)
727				}
728			}
729		}
730	}
731}
732
733// Tests that fast importing a block chain produces the same chain data as the
734// classical full block processing.
735func TestFastVsFullChains(t *testing.T) {
736	// Configure and generate a sample block chain
737	var (
738		gendb   = rawdb.NewMemoryDatabase()
739		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
740		address = crypto.PubkeyToAddress(key.PublicKey)
741		funds   = big.NewInt(1000000000000000)
742		gspec   = &Genesis{
743			Config:  params.TestChainConfig,
744			Alloc:   GenesisAlloc{address: {Balance: funds}},
745			BaseFee: big.NewInt(params.InitialBaseFee),
746		}
747		genesis = gspec.MustCommit(gendb)
748		signer  = types.LatestSigner(gspec.Config)
749	)
750	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
751		block.SetCoinbase(common.Address{0x00})
752
753		// If the block number is multiple of 3, send a few bonus transactions to the miner
754		if i%3 == 2 {
755			for j := 0; j < i%4+1; j++ {
756				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
757				if err != nil {
758					panic(err)
759				}
760				block.AddTx(tx)
761			}
762		}
763		// If the block number is a multiple of 5, add a few bonus uncles to the block
764		if i%5 == 5 {
765			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
766		}
767	})
768	// Import the chain as an archive node for the comparison baseline
769	archiveDb := rawdb.NewMemoryDatabase()
770	gspec.MustCommit(archiveDb)
771	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
772	defer archive.Stop()
773
774	if n, err := archive.InsertChain(blocks); err != nil {
775		t.Fatalf("failed to process block %d: %v", n, err)
776	}
777	// Fast import the chain as a non-archive node to test
778	fastDb := rawdb.NewMemoryDatabase()
779	gspec.MustCommit(fastDb)
780	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
781	defer fast.Stop()
782
783	headers := make([]*types.Header, len(blocks))
784	for i, block := range blocks {
785		headers[i] = block.Header()
786	}
787	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
788		t.Fatalf("failed to insert header %d: %v", n, err)
789	}
790	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
791		t.Fatalf("failed to insert receipt %d: %v", n, err)
792	}
793	// Freezer style fast import the chain.
794	frdir, err := ioutil.TempDir("", "")
795	if err != nil {
796		t.Fatalf("failed to create temp freezer dir: %v", err)
797	}
798	defer os.Remove(frdir)
799	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
800	if err != nil {
801		t.Fatalf("failed to create temp freezer db: %v", err)
802	}
803	gspec.MustCommit(ancientDb)
804	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
805	defer ancient.Stop()
806
807	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
808		t.Fatalf("failed to insert header %d: %v", n, err)
809	}
810	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil {
811		t.Fatalf("failed to insert receipt %d: %v", n, err)
812	}
813
814	// Iterate over all chain data components, and cross reference
815	for i := 0; i < len(blocks); i++ {
816		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
817
818		if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 {
819			t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd)
820		}
821		if antd, artd := ancient.GetTd(hash, num), archive.GetTd(hash, num); antd.Cmp(artd) != 0 {
822			t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd)
823		}
824		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
825			t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader)
826		}
827		if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() {
828			t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader)
829		}
830		if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() {
831			t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock)
832		} else if types.DeriveSha(fblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) || types.DeriveSha(anblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) {
833			t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions())
834		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) {
835			t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles())
836		}
837
838		// Check receipts.
839		freceipts := rawdb.ReadReceipts(fastDb, hash, num, fast.Config())
840		anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, fast.Config())
841		areceipts := rawdb.ReadReceipts(archiveDb, hash, num, fast.Config())
842		if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
843			t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
844		}
845
846		// Check that hash-to-number mappings are present in all databases.
847		if m := rawdb.ReadHeaderNumber(fastDb, hash); m == nil || *m != num {
848			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m)
849		}
850		if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == nil || *m != num {
851			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m)
852		}
853		if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == nil || *m != num {
854			t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m)
855		}
856	}
857
858	// Check that the canonical chains are the same between the databases
859	for i := 0; i < len(blocks)+1; i++ {
860		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
861			t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash)
862		}
863		if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash {
864			t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash)
865		}
866	}
867}
868
869// Tests that various import methods move the chain head pointers to the correct
870// positions.
871func TestLightVsFastVsFullChainHeads(t *testing.T) {
872	// Configure and generate a sample block chain
873	var (
874		gendb   = rawdb.NewMemoryDatabase()
875		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
876		address = crypto.PubkeyToAddress(key.PublicKey)
877		funds   = big.NewInt(1000000000000000)
878		gspec   = &Genesis{
879			Config:  params.TestChainConfig,
880			Alloc:   GenesisAlloc{address: {Balance: funds}},
881			BaseFee: big.NewInt(params.InitialBaseFee),
882		}
883		genesis = gspec.MustCommit(gendb)
884	)
885	height := uint64(1024)
886	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
887
888	// makeDb creates a db instance for testing.
889	makeDb := func() (ethdb.Database, func()) {
890		dir, err := ioutil.TempDir("", "")
891		if err != nil {
892			t.Fatalf("failed to create temp freezer dir: %v", err)
893		}
894		defer os.Remove(dir)
895		db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false)
896		if err != nil {
897			t.Fatalf("failed to create temp freezer db: %v", err)
898		}
899		gspec.MustCommit(db)
900		return db, func() { os.RemoveAll(dir) }
901	}
902	// Configure a subchain to roll back
903	remove := blocks[height/2].NumberU64()
904
905	// Create a small assertion method to check the three heads
906	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
907		t.Helper()
908
909		if num := chain.CurrentBlock().NumberU64(); num != block {
910			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
911		}
912		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
913			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
914		}
915		if num := chain.CurrentHeader().Number.Uint64(); num != header {
916			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
917		}
918	}
919	// Import the chain as an archive node and ensure all pointers are updated
920	archiveDb, delfn := makeDb()
921	defer delfn()
922
923	archiveCaching := *defaultCacheConfig
924	archiveCaching.TrieDirtyDisabled = true
925
926	archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
927	if n, err := archive.InsertChain(blocks); err != nil {
928		t.Fatalf("failed to process block %d: %v", n, err)
929	}
930	defer archive.Stop()
931
932	assert(t, "archive", archive, height, height, height)
933	archive.SetHead(remove - 1)
934	assert(t, "archive", archive, height/2, height/2, height/2)
935
936	// Import the chain as a non-archive node and ensure all pointers are updated
937	fastDb, delfn := makeDb()
938	defer delfn()
939	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
940	defer fast.Stop()
941
942	headers := make([]*types.Header, len(blocks))
943	for i, block := range blocks {
944		headers[i] = block.Header()
945	}
946	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
947		t.Fatalf("failed to insert header %d: %v", n, err)
948	}
949	if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil {
950		t.Fatalf("failed to insert receipt %d: %v", n, err)
951	}
952	assert(t, "fast", fast, height, height, 0)
953	fast.SetHead(remove - 1)
954	assert(t, "fast", fast, height/2, height/2, 0)
955
956	// Import the chain as a ancient-first node and ensure all pointers are updated
957	ancientDb, delfn := makeDb()
958	defer delfn()
959	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
960	defer ancient.Stop()
961
962	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
963		t.Fatalf("failed to insert header %d: %v", n, err)
964	}
965	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
966		t.Fatalf("failed to insert receipt %d: %v", n, err)
967	}
968	assert(t, "ancient", ancient, height, height, 0)
969	ancient.SetHead(remove - 1)
970	assert(t, "ancient", ancient, 0, 0, 0)
971
972	if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 {
973		t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen)
974	}
975	// Import the chain as a light node and ensure all pointers are updated
976	lightDb, delfn := makeDb()
977	defer delfn()
978	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
979	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
980		t.Fatalf("failed to insert header %d: %v", n, err)
981	}
982	defer light.Stop()
983
984	assert(t, "light", light, height, 0, 0)
985	light.SetHead(remove - 1)
986	assert(t, "light", light, height/2, 0, 0)
987}
988
989// Tests that chain reorganisations handle transaction removals and reinsertions.
990func TestChainTxReorgs(t *testing.T) {
991	var (
992		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
993		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
994		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
995		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
996		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
997		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
998		db      = rawdb.NewMemoryDatabase()
999		gspec   = &Genesis{
1000			Config:   params.TestChainConfig,
1001			GasLimit: 3141592,
1002			Alloc: GenesisAlloc{
1003				addr1: {Balance: big.NewInt(1000000000000000)},
1004				addr2: {Balance: big.NewInt(1000000000000000)},
1005				addr3: {Balance: big.NewInt(1000000000000000)},
1006			},
1007		}
1008		genesis = gspec.MustCommit(db)
1009		signer  = types.LatestSigner(gspec.Config)
1010	)
1011
1012	// Create two transactions shared between the chains:
1013	//  - postponed: transaction included at a later block in the forked chain
1014	//  - swapped: transaction included at the same block number in the forked chain
1015	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
1016	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1)
1017
1018	// Create two transactions that will be dropped by the forked chain:
1019	//  - pastDrop: transaction dropped retroactively from a past block
1020	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
1021	var pastDrop, freshDrop *types.Transaction
1022
1023	// Create three transactions that will be added in the forked chain:
1024	//  - pastAdd:   transaction added before the reorganization is detected
1025	//  - freshAdd:  transaction added at the exact block the reorg is detected
1026	//  - futureAdd: transaction added after the reorg has already finished
1027	var pastAdd, freshAdd, futureAdd *types.Transaction
1028
1029	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
1030		switch i {
1031		case 0:
1032			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
1033
1034			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
1035			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
1036
1037		case 2:
1038			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2)
1039
1040			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
1041			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
1042
1043			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
1044		}
1045	})
1046	// Import the chain. This runs all block validation rules.
1047	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1048	if i, err := blockchain.InsertChain(chain); err != nil {
1049		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
1050	}
1051	defer blockchain.Stop()
1052
1053	// overwrite the old chain
1054	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
1055		switch i {
1056		case 0:
1057			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
1058			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
1059
1060		case 2:
1061			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
1062			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
1063
1064			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
1065			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
1066
1067		case 3:
1068			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3)
1069			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
1070		}
1071	})
1072	if _, err := blockchain.InsertChain(chain); err != nil {
1073		t.Fatalf("failed to insert forked chain: %v", err)
1074	}
1075
1076	// removed tx
1077	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
1078		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
1079			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
1080		}
1081		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
1082			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
1083		}
1084	}
1085	// added tx
1086	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
1087		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
1088			t.Errorf("add %d: expected tx to be found", i)
1089		}
1090		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
1091			t.Errorf("add %d: expected receipt to be found", i)
1092		}
1093	}
1094	// shared tx
1095	for i, tx := range (types.Transactions{postponed, swapped}) {
1096		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
1097			t.Errorf("share %d: expected tx to be found", i)
1098		}
1099		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
1100			t.Errorf("share %d: expected receipt to be found", i)
1101		}
1102	}
1103}
1104
1105func TestLogReorgs(t *testing.T) {
1106	var (
1107		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1108		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
1109		db      = rawdb.NewMemoryDatabase()
1110		// this code generates a log
1111		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
1112		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
1113		genesis = gspec.MustCommit(db)
1114		signer  = types.LatestSigner(gspec.Config)
1115	)
1116
1117	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1118	defer blockchain.Stop()
1119
1120	rmLogsCh := make(chan RemovedLogsEvent)
1121	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
1122	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
1123		if i == 1 {
1124			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1)
1125			if err != nil {
1126				t.Fatalf("failed to create tx: %v", err)
1127			}
1128			gen.AddTx(tx)
1129		}
1130	})
1131	if _, err := blockchain.InsertChain(chain); err != nil {
1132		t.Fatalf("failed to insert chain: %v", err)
1133	}
1134
1135	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
1136	done := make(chan struct{})
1137	go func() {
1138		ev := <-rmLogsCh
1139		if len(ev.Logs) == 0 {
1140			t.Error("expected logs")
1141		}
1142		close(done)
1143	}()
1144	if _, err := blockchain.InsertChain(chain); err != nil {
1145		t.Fatalf("failed to insert forked chain: %v", err)
1146	}
1147	timeout := time.NewTimer(1 * time.Second)
1148	defer timeout.Stop()
1149	select {
1150	case <-done:
1151	case <-timeout.C:
1152		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
1153	}
1154}
1155
1156// This EVM code generates a log when the contract is created.
1157var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
1158
1159// This test checks that log events and RemovedLogsEvent are sent
1160// when the chain reorganizes.
1161func TestLogRebirth(t *testing.T) {
1162	var (
1163		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1164		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
1165		db            = rawdb.NewMemoryDatabase()
1166		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
1167		genesis       = gspec.MustCommit(db)
1168		signer        = types.LatestSigner(gspec.Config)
1169		engine        = ethash.NewFaker()
1170		blockchain, _ = NewBlockChain(db, nil, gspec.Config, engine, vm.Config{}, nil, nil)
1171	)
1172
1173	defer blockchain.Stop()
1174
1175	// The event channels.
1176	newLogCh := make(chan []*types.Log, 10)
1177	rmLogsCh := make(chan RemovedLogsEvent, 10)
1178	blockchain.SubscribeLogsEvent(newLogCh)
1179	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
1180
1181	// This chain contains a single log.
1182	chain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
1183		if i == 1 {
1184			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
1185			if err != nil {
1186				t.Fatalf("failed to create tx: %v", err)
1187			}
1188			gen.AddTx(tx)
1189		}
1190	})
1191	if _, err := blockchain.InsertChain(chain); err != nil {
1192		t.Fatalf("failed to insert chain: %v", err)
1193	}
1194	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
1195
1196	// Generate long reorg chain containing another log. Inserting the
1197	// chain removes one log and adds one.
1198	forkChain, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2, func(i int, gen *BlockGen) {
1199		if i == 1 {
1200			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
1201			if err != nil {
1202				t.Fatalf("failed to create tx: %v", err)
1203			}
1204			gen.AddTx(tx)
1205			gen.OffsetTime(-9) // higher block difficulty
1206		}
1207	})
1208	if _, err := blockchain.InsertChain(forkChain); err != nil {
1209		t.Fatalf("failed to insert forked chain: %v", err)
1210	}
1211	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
1212
1213	// This chain segment is rooted in the original chain, but doesn't contain any logs.
1214	// When inserting it, the canonical chain switches away from forkChain and re-emits
1215	// the log event for the old chain, as well as a RemovedLogsEvent for forkChain.
1216	newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], engine, db, 1, func(i int, gen *BlockGen) {})
1217	if _, err := blockchain.InsertChain(newBlocks); err != nil {
1218		t.Fatalf("failed to insert forked chain: %v", err)
1219	}
1220	checkLogEvents(t, newLogCh, rmLogsCh, 1, 1)
1221}
1222
1223// This test is a variation of TestLogRebirth. It verifies that log events are emitted
1224// when a side chain containing log events overtakes the canonical chain.
1225func TestSideLogRebirth(t *testing.T) {
1226	var (
1227		key1, _       = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1228		addr1         = crypto.PubkeyToAddress(key1.PublicKey)
1229		db            = rawdb.NewMemoryDatabase()
1230		gspec         = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}}
1231		genesis       = gspec.MustCommit(db)
1232		signer        = types.LatestSigner(gspec.Config)
1233		blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1234	)
1235
1236	defer blockchain.Stop()
1237
1238	newLogCh := make(chan []*types.Log, 10)
1239	rmLogsCh := make(chan RemovedLogsEvent, 10)
1240	blockchain.SubscribeLogsEvent(newLogCh)
1241	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
1242
1243	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
1244		if i == 1 {
1245			gen.OffsetTime(-9) // higher block difficulty
1246
1247		}
1248	})
1249	if _, err := blockchain.InsertChain(chain); err != nil {
1250		t.Fatalf("failed to insert forked chain: %v", err)
1251	}
1252	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
1253
1254	// Generate side chain with lower difficulty
1255	sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
1256		if i == 1 {
1257			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1)
1258			if err != nil {
1259				t.Fatalf("failed to create tx: %v", err)
1260			}
1261			gen.AddTx(tx)
1262		}
1263	})
1264	if _, err := blockchain.InsertChain(sideChain); err != nil {
1265		t.Fatalf("failed to insert forked chain: %v", err)
1266	}
1267	checkLogEvents(t, newLogCh, rmLogsCh, 0, 0)
1268
1269	// Generate a new block based on side chain.
1270	newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {})
1271	if _, err := blockchain.InsertChain(newBlocks); err != nil {
1272		t.Fatalf("failed to insert forked chain: %v", err)
1273	}
1274	checkLogEvents(t, newLogCh, rmLogsCh, 1, 0)
1275}
1276
1277func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) {
1278	t.Helper()
1279
1280	if len(logsCh) != wantNew {
1281		t.Fatalf("wrong number of log events: got %d, want %d", len(logsCh), wantNew)
1282	}
1283	if len(rmLogsCh) != wantRemoved {
1284		t.Fatalf("wrong number of removed log events: got %d, want %d", len(rmLogsCh), wantRemoved)
1285	}
1286	// Drain events.
1287	for i := 0; i < len(logsCh); i++ {
1288		<-logsCh
1289	}
1290	for i := 0; i < len(rmLogsCh); i++ {
1291		<-rmLogsCh
1292	}
1293}
1294
1295func TestReorgSideEvent(t *testing.T) {
1296	var (
1297		db      = rawdb.NewMemoryDatabase()
1298		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1299		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
1300		gspec   = &Genesis{
1301			Config: params.TestChainConfig,
1302			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
1303		}
1304		genesis = gspec.MustCommit(db)
1305		signer  = types.LatestSigner(gspec.Config)
1306	)
1307
1308	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1309	defer blockchain.Stop()
1310
1311	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
1312	if _, err := blockchain.InsertChain(chain); err != nil {
1313		t.Fatalf("failed to insert chain: %v", err)
1314	}
1315
1316	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
1317		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1)
1318		if i == 2 {
1319			gen.OffsetTime(-9)
1320		}
1321		if err != nil {
1322			t.Fatalf("failed to create tx: %v", err)
1323		}
1324		gen.AddTx(tx)
1325	})
1326	chainSideCh := make(chan ChainSideEvent, 64)
1327	blockchain.SubscribeChainSideEvent(chainSideCh)
1328	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
1329		t.Fatalf("failed to insert chain: %v", err)
1330	}
1331
1332	// first two block of the secondary chain are for a brief moment considered
1333	// side chains because up to that point the first one is considered the
1334	// heavier chain.
1335	expectedSideHashes := map[common.Hash]bool{
1336		replacementBlocks[0].Hash(): true,
1337		replacementBlocks[1].Hash(): true,
1338		chain[0].Hash():             true,
1339		chain[1].Hash():             true,
1340		chain[2].Hash():             true,
1341	}
1342
1343	i := 0
1344
1345	const timeoutDura = 10 * time.Second
1346	timeout := time.NewTimer(timeoutDura)
1347done:
1348	for {
1349		select {
1350		case ev := <-chainSideCh:
1351			block := ev.Block
1352			if _, ok := expectedSideHashes[block.Hash()]; !ok {
1353				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
1354			}
1355			i++
1356
1357			if i == len(expectedSideHashes) {
1358				timeout.Stop()
1359
1360				break done
1361			}
1362			timeout.Reset(timeoutDura)
1363
1364		case <-timeout.C:
1365			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
1366		}
1367	}
1368
1369	// make sure no more events are fired
1370	select {
1371	case e := <-chainSideCh:
1372		t.Errorf("unexpected event fired: %v", e)
1373	case <-time.After(250 * time.Millisecond):
1374	}
1375
1376}
1377
1378// Tests if the canonical block can be fetched from the database during chain insertion.
1379func TestCanonicalBlockRetrieval(t *testing.T) {
1380	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
1381	if err != nil {
1382		t.Fatalf("failed to create pristine chain: %v", err)
1383	}
1384	defer blockchain.Stop()
1385
1386	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
1387
1388	var pend sync.WaitGroup
1389	pend.Add(len(chain))
1390
1391	for i := range chain {
1392		go func(block *types.Block) {
1393			defer pend.Done()
1394
1395			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
1396			for {
1397				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
1398				if ch == (common.Hash{}) {
1399					continue // busy wait for canonical hash to be written
1400				}
1401				if ch != block.Hash() {
1402					t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
1403					return
1404				}
1405				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
1406				if fb == nil {
1407					t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
1408					return
1409				}
1410				if fb.Hash() != block.Hash() {
1411					t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
1412					return
1413				}
1414				return
1415			}
1416		}(chain[i])
1417
1418		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
1419			t.Fatalf("failed to insert block %d: %v", i, err)
1420		}
1421	}
1422	pend.Wait()
1423}
1424
1425func TestEIP155Transition(t *testing.T) {
1426	// Configure and generate a sample block chain
1427	var (
1428		db         = rawdb.NewMemoryDatabase()
1429		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1430		address    = crypto.PubkeyToAddress(key.PublicKey)
1431		funds      = big.NewInt(1000000000)
1432		deleteAddr = common.Address{1}
1433		gspec      = &Genesis{
1434			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
1435			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
1436		}
1437		genesis = gspec.MustCommit(db)
1438	)
1439
1440	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1441	defer blockchain.Stop()
1442
1443	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
1444		var (
1445			tx      *types.Transaction
1446			err     error
1447			basicTx = func(signer types.Signer) (*types.Transaction, error) {
1448				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
1449			}
1450		)
1451		switch i {
1452		case 0:
1453			tx, err = basicTx(types.HomesteadSigner{})
1454			if err != nil {
1455				t.Fatal(err)
1456			}
1457			block.AddTx(tx)
1458		case 2:
1459			tx, err = basicTx(types.HomesteadSigner{})
1460			if err != nil {
1461				t.Fatal(err)
1462			}
1463			block.AddTx(tx)
1464
1465			tx, err = basicTx(types.LatestSigner(gspec.Config))
1466			if err != nil {
1467				t.Fatal(err)
1468			}
1469			block.AddTx(tx)
1470		case 3:
1471			tx, err = basicTx(types.HomesteadSigner{})
1472			if err != nil {
1473				t.Fatal(err)
1474			}
1475			block.AddTx(tx)
1476
1477			tx, err = basicTx(types.LatestSigner(gspec.Config))
1478			if err != nil {
1479				t.Fatal(err)
1480			}
1481			block.AddTx(tx)
1482		}
1483	})
1484
1485	if _, err := blockchain.InsertChain(blocks); err != nil {
1486		t.Fatal(err)
1487	}
1488	block := blockchain.GetBlockByNumber(1)
1489	if block.Transactions()[0].Protected() {
1490		t.Error("Expected block[0].txs[0] to not be replay protected")
1491	}
1492
1493	block = blockchain.GetBlockByNumber(3)
1494	if block.Transactions()[0].Protected() {
1495		t.Error("Expected block[3].txs[0] to not be replay protected")
1496	}
1497	if !block.Transactions()[1].Protected() {
1498		t.Error("Expected block[3].txs[1] to be replay protected")
1499	}
1500	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
1501		t.Fatal(err)
1502	}
1503
1504	// generate an invalid chain id transaction
1505	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
1506	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
1507		var (
1508			tx      *types.Transaction
1509			err     error
1510			basicTx = func(signer types.Signer) (*types.Transaction, error) {
1511				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
1512			}
1513		)
1514		if i == 0 {
1515			tx, err = basicTx(types.LatestSigner(config))
1516			if err != nil {
1517				t.Fatal(err)
1518			}
1519			block.AddTx(tx)
1520		}
1521	})
1522	_, err := blockchain.InsertChain(blocks)
1523	if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) {
1524		t.Errorf("have %v, want %v", have, want)
1525	}
1526}
1527
1528func TestEIP161AccountRemoval(t *testing.T) {
1529	// Configure and generate a sample block chain
1530	var (
1531		db      = rawdb.NewMemoryDatabase()
1532		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1533		address = crypto.PubkeyToAddress(key.PublicKey)
1534		funds   = big.NewInt(1000000000)
1535		theAddr = common.Address{1}
1536		gspec   = &Genesis{
1537			Config: &params.ChainConfig{
1538				ChainID:        big.NewInt(1),
1539				HomesteadBlock: new(big.Int),
1540				EIP155Block:    new(big.Int),
1541				EIP150Block:    new(big.Int),
1542				EIP158Block:    big.NewInt(2),
1543			},
1544			Alloc: GenesisAlloc{address: {Balance: funds}},
1545		}
1546		genesis = gspec.MustCommit(db)
1547	)
1548	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1549	defer blockchain.Stop()
1550
1551	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
1552		var (
1553			tx     *types.Transaction
1554			err    error
1555			signer = types.LatestSigner(gspec.Config)
1556		)
1557		switch i {
1558		case 0:
1559			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1560		case 1:
1561			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1562		case 2:
1563			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
1564		}
1565		if err != nil {
1566			t.Fatal(err)
1567		}
1568		block.AddTx(tx)
1569	})
1570	// account must exist pre eip 161
1571	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
1572		t.Fatal(err)
1573	}
1574	if st, _ := blockchain.State(); !st.Exist(theAddr) {
1575		t.Error("expected account to exist")
1576	}
1577
1578	// account needs to be deleted post eip 161
1579	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
1580		t.Fatal(err)
1581	}
1582	if st, _ := blockchain.State(); st.Exist(theAddr) {
1583		t.Error("account should not exist")
1584	}
1585
1586	// account mustn't be created post eip 161
1587	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
1588		t.Fatal(err)
1589	}
1590	if st, _ := blockchain.State(); st.Exist(theAddr) {
1591		t.Error("account should not exist")
1592	}
1593}
1594
1595// This is a regression test (i.e. as weird as it is, don't delete it ever), which
1596// tests that under weird reorg conditions the blockchain and its internal header-
1597// chain return the same latest block/header.
1598//
1599// https://github.com/ethereum/go-ethereum/pull/15941
1600func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
1601	// Generate a canonical chain to act as the main dataset
1602	engine := ethash.NewFaker()
1603
1604	db := rawdb.NewMemoryDatabase()
1605	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1606	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
1607
1608	// Generate a bunch of fork blocks, each side forking from the canonical chain
1609	forks := make([]*types.Block, len(blocks))
1610	for i := 0; i < len(forks); i++ {
1611		parent := genesis
1612		if i > 0 {
1613			parent = blocks[i-1]
1614		}
1615		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
1616		forks[i] = fork[0]
1617	}
1618	// Import the canonical and fork chain side by side, verifying the current block
1619	// and current header consistency
1620	diskdb := rawdb.NewMemoryDatabase()
1621	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
1622
1623	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
1624	if err != nil {
1625		t.Fatalf("failed to create tester chain: %v", err)
1626	}
1627	for i := 0; i < len(blocks); i++ {
1628		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
1629			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
1630		}
1631		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
1632			t.Errorf("block %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number(), chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
1633		}
1634		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
1635			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
1636		}
1637		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
1638			t.Errorf(" fork %d: current block/header mismatch: block #%d [%x..], header #%d [%x..]", i, chain.CurrentBlock().Number(), chain.CurrentBlock().Hash().Bytes()[:4], chain.CurrentHeader().Number, chain.CurrentHeader().Hash().Bytes()[:4])
1639		}
1640	}
1641}
1642
1643// Tests that importing small side forks doesn't leave junk in the trie database
1644// cache (which would eventually cause memory issues).
1645func TestTrieForkGC(t *testing.T) {
1646	// Generate a canonical chain to act as the main dataset
1647	engine := ethash.NewFaker()
1648
1649	db := rawdb.NewMemoryDatabase()
1650	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1651	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
1652
1653	// Generate a bunch of fork blocks, each side forking from the canonical chain
1654	forks := make([]*types.Block, len(blocks))
1655	for i := 0; i < len(forks); i++ {
1656		parent := genesis
1657		if i > 0 {
1658			parent = blocks[i-1]
1659		}
1660		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
1661		forks[i] = fork[0]
1662	}
1663	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
1664	diskdb := rawdb.NewMemoryDatabase()
1665	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
1666
1667	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
1668	if err != nil {
1669		t.Fatalf("failed to create tester chain: %v", err)
1670	}
1671	for i := 0; i < len(blocks); i++ {
1672		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
1673			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
1674		}
1675		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
1676			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
1677		}
1678	}
1679	// Dereference all the recent tries and ensure no past trie is left in
1680	for i := 0; i < TriesInMemory; i++ {
1681		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
1682		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
1683	}
1684	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
1685		t.Fatalf("stale tries still alive after garbase collection")
1686	}
1687}
1688
1689// Tests that doing large reorgs works even if the state associated with the
1690// forking point is not available any more.
1691func TestLargeReorgTrieGC(t *testing.T) {
1692	// Generate the original common chain segment and the two competing forks
1693	engine := ethash.NewFaker()
1694
1695	db := rawdb.NewMemoryDatabase()
1696	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1697
1698	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
1699	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
1700	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
1701
1702	// Import the shared chain and the original canonical one
1703	diskdb := rawdb.NewMemoryDatabase()
1704	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
1705
1706	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
1707	if err != nil {
1708		t.Fatalf("failed to create tester chain: %v", err)
1709	}
1710	if _, err := chain.InsertChain(shared); err != nil {
1711		t.Fatalf("failed to insert shared chain: %v", err)
1712	}
1713	if _, err := chain.InsertChain(original); err != nil {
1714		t.Fatalf("failed to insert original chain: %v", err)
1715	}
1716	// Ensure that the state associated with the forking point is pruned away
1717	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
1718		t.Fatalf("common-but-old ancestor still cache")
1719	}
1720	// Import the competitor chain without exceeding the canonical's TD and ensure
1721	// we have not processed any of the blocks (protection against malicious blocks)
1722	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
1723		t.Fatalf("failed to insert competitor chain: %v", err)
1724	}
1725	for i, block := range competitor[:len(competitor)-2] {
1726		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
1727			t.Fatalf("competitor %d: low TD chain became processed", i)
1728		}
1729	}
1730	// Import the head of the competitor chain, triggering the reorg and ensure we
1731	// successfully reprocess all the stashed away blocks.
1732	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
1733		t.Fatalf("failed to finalize competitor chain: %v", err)
1734	}
1735	for i, block := range competitor[:len(competitor)-TriesInMemory] {
1736		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
1737			t.Fatalf("competitor %d: competing chain state missing", i)
1738		}
1739	}
1740}
1741
1742func TestBlockchainRecovery(t *testing.T) {
1743	// Configure and generate a sample block chain
1744	var (
1745		gendb   = rawdb.NewMemoryDatabase()
1746		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1747		address = crypto.PubkeyToAddress(key.PublicKey)
1748		funds   = big.NewInt(1000000000)
1749		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
1750		genesis = gspec.MustCommit(gendb)
1751	)
1752	height := uint64(1024)
1753	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
1754
1755	// Import the chain as a ancient-first node and ensure all pointers are updated
1756	frdir, err := ioutil.TempDir("", "")
1757	if err != nil {
1758		t.Fatalf("failed to create temp freezer dir: %v", err)
1759	}
1760	defer os.Remove(frdir)
1761
1762	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
1763	if err != nil {
1764		t.Fatalf("failed to create temp freezer db: %v", err)
1765	}
1766	gspec.MustCommit(ancientDb)
1767	ancient, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1768
1769	headers := make([]*types.Header, len(blocks))
1770	for i, block := range blocks {
1771		headers[i] = block.Header()
1772	}
1773	if n, err := ancient.InsertHeaderChain(headers, 1); err != nil {
1774		t.Fatalf("failed to insert header %d: %v", n, err)
1775	}
1776	if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil {
1777		t.Fatalf("failed to insert receipt %d: %v", n, err)
1778	}
1779	rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior
1780	ancient.Stop()
1781
1782	// Destroy head fast block manually
1783	midBlock := blocks[len(blocks)/2]
1784	rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash())
1785
1786	// Reopen broken blockchain again
1787	ancient, _ = NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1788	defer ancient.Stop()
1789	if num := ancient.CurrentBlock().NumberU64(); num != 0 {
1790		t.Errorf("head block mismatch: have #%v, want #%v", num, 0)
1791	}
1792	if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() {
1793		t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64())
1794	}
1795	if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() {
1796		t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64())
1797	}
1798}
1799
1800// This test checks that InsertReceiptChain will roll back correctly when attempting to insert a side chain.
1801func TestInsertReceiptChainRollback(t *testing.T) {
1802	// Generate forked chain. The returned BlockChain object is used to process the side chain blocks.
1803	tmpChain, sideblocks, canonblocks, err := getLongAndShortChains()
1804	if err != nil {
1805		t.Fatal(err)
1806	}
1807	defer tmpChain.Stop()
1808	// Get the side chain receipts.
1809	if _, err := tmpChain.InsertChain(sideblocks); err != nil {
1810		t.Fatal("processing side chain failed:", err)
1811	}
1812	t.Log("sidechain head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash())
1813	sidechainReceipts := make([]types.Receipts, len(sideblocks))
1814	for i, block := range sideblocks {
1815		sidechainReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
1816	}
1817	// Get the canon chain receipts.
1818	if _, err := tmpChain.InsertChain(canonblocks); err != nil {
1819		t.Fatal("processing canon chain failed:", err)
1820	}
1821	t.Log("canon head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash())
1822	canonReceipts := make([]types.Receipts, len(canonblocks))
1823	for i, block := range canonblocks {
1824		canonReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash())
1825	}
1826
1827	// Set up a BlockChain that uses the ancient store.
1828	frdir, err := ioutil.TempDir("", "")
1829	if err != nil {
1830		t.Fatalf("failed to create temp freezer dir: %v", err)
1831	}
1832	defer os.Remove(frdir)
1833	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
1834	if err != nil {
1835		t.Fatalf("failed to create temp freezer db: %v", err)
1836	}
1837	gspec := Genesis{Config: params.AllEthashProtocolChanges}
1838	gspec.MustCommit(ancientDb)
1839	ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
1840	defer ancientChain.Stop()
1841
1842	// Import the canonical header chain.
1843	canonHeaders := make([]*types.Header, len(canonblocks))
1844	for i, block := range canonblocks {
1845		canonHeaders[i] = block.Header()
1846	}
1847	if _, err = ancientChain.InsertHeaderChain(canonHeaders, 1); err != nil {
1848		t.Fatal("can't import canon headers:", err)
1849	}
1850
1851	// Try to insert blocks/receipts of the side chain.
1852	_, err = ancientChain.InsertReceiptChain(sideblocks, sidechainReceipts, uint64(len(sideblocks)))
1853	if err == nil {
1854		t.Fatal("expected error from InsertReceiptChain.")
1855	}
1856	if ancientChain.CurrentFastBlock().NumberU64() != 0 {
1857		t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentFastBlock().NumberU64())
1858	}
1859	if frozen, err := ancientChain.db.Ancients(); err != nil || frozen != 1 {
1860		t.Fatalf("failed to truncate ancient data, frozen index is %d", frozen)
1861	}
1862
1863	// Insert blocks/receipts of the canonical chain.
1864	_, err = ancientChain.InsertReceiptChain(canonblocks, canonReceipts, uint64(len(canonblocks)))
1865	if err != nil {
1866		t.Fatalf("can't import canon chain receipts: %v", err)
1867	}
1868	if ancientChain.CurrentFastBlock().NumberU64() != canonblocks[len(canonblocks)-1].NumberU64() {
1869		t.Fatalf("failed to insert ancient recept chain after rollback")
1870	}
1871	if frozen, _ := ancientChain.db.Ancients(); frozen != uint64(len(canonblocks))+1 {
1872		t.Fatalf("wrong ancients count %d", frozen)
1873	}
1874}
1875
1876// Tests that importing a very large side fork, which is larger than the canon chain,
1877// but where the difficulty per block is kept low: this means that it will not
1878// overtake the 'canon' chain until after it's passed canon by about 200 blocks.
1879//
1880// Details at:
1881//  - https://github.com/ethereum/go-ethereum/issues/18977
1882//  - https://github.com/ethereum/go-ethereum/pull/18988
1883func TestLowDiffLongChain(t *testing.T) {
1884	// Generate a canonical chain to act as the main dataset
1885	engine := ethash.NewFaker()
1886	db := rawdb.NewMemoryDatabase()
1887	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1888
1889	// We must use a pretty long chain to ensure that the fork doesn't overtake us
1890	// until after at least 128 blocks post tip
1891	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*TriesInMemory, func(i int, b *BlockGen) {
1892		b.SetCoinbase(common.Address{1})
1893		b.OffsetTime(-9)
1894	})
1895
1896	// Import the canonical chain
1897	diskdb := rawdb.NewMemoryDatabase()
1898	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
1899
1900	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
1901	if err != nil {
1902		t.Fatalf("failed to create tester chain: %v", err)
1903	}
1904	if n, err := chain.InsertChain(blocks); err != nil {
1905		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
1906	}
1907	// Generate fork chain, starting from an early block
1908	parent := blocks[10]
1909	fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*TriesInMemory, func(i int, b *BlockGen) {
1910		b.SetCoinbase(common.Address{2})
1911	})
1912
1913	// And now import the fork
1914	if i, err := chain.InsertChain(fork); err != nil {
1915		t.Fatalf("block %d: failed to insert into chain: %v", i, err)
1916	}
1917	head := chain.CurrentBlock()
1918	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
1919		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
1920	}
1921	// Sanity check that all the canonical numbers are present
1922	header := chain.CurrentHeader()
1923	for number := head.NumberU64(); number > 0; number-- {
1924		if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() {
1925			t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash())
1926		}
1927		header = chain.GetHeader(header.ParentHash, number-1)
1928	}
1929}
1930
1931// Tests that importing a sidechain (S), where
1932// - S is sidechain, containing blocks [Sn...Sm]
1933// - C is canon chain, containing blocks [G..Cn..Cm]
1934// - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock
1935// - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain
1936//
1937// The mergePoint can be these values:
1938// -1: the transition won't happen
1939// 0:  the transition happens since genesis
1940// 1:  the transition happens after some chain segments
1941func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int, mergePoint int) {
1942	// Copy the TestChainConfig so we can modify it during tests
1943	chainConfig := *params.TestChainConfig
1944	// Generate a canonical chain to act as the main dataset
1945	var (
1946		merger    = consensus.NewMerger(rawdb.NewMemoryDatabase())
1947		genEngine = beacon.New(ethash.NewFaker())
1948		runEngine = beacon.New(ethash.NewFaker())
1949		db        = rawdb.NewMemoryDatabase()
1950
1951		key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
1952		addr   = crypto.PubkeyToAddress(key.PublicKey)
1953		nonce  = uint64(0)
1954
1955		gspec = &Genesis{
1956			Config:  &chainConfig,
1957			Alloc:   GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}},
1958			BaseFee: big.NewInt(params.InitialBaseFee),
1959		}
1960		signer     = types.LatestSigner(gspec.Config)
1961		genesis, _ = gspec.Commit(db)
1962	)
1963	// Generate and import the canonical chain
1964	diskdb := rawdb.NewMemoryDatabase()
1965	gspec.MustCommit(diskdb)
1966	chain, err := NewBlockChain(diskdb, nil, &chainConfig, runEngine, vm.Config{}, nil, nil)
1967	if err != nil {
1968		t.Fatalf("failed to create tester chain: %v", err)
1969	}
1970	// Activate the transition since genesis if required
1971	if mergePoint == 0 {
1972		merger.ReachTTD()
1973		merger.FinalizePoS()
1974
1975		// Set the terminal total difficulty in the config
1976		gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
1977	}
1978	blocks, _ := GenerateChain(&chainConfig, genesis, genEngine, db, 2*TriesInMemory, func(i int, gen *BlockGen) {
1979		tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key)
1980		if err != nil {
1981			t.Fatalf("failed to create tx: %v", err)
1982		}
1983		gen.AddTx(tx)
1984		nonce++
1985	})
1986	if n, err := chain.InsertChain(blocks); err != nil {
1987		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
1988	}
1989
1990	lastPrunedIndex := len(blocks) - TriesInMemory - 1
1991	lastPrunedBlock := blocks[lastPrunedIndex]
1992	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
1993
1994	// Verify pruning of lastPrunedBlock
1995	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
1996		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
1997	}
1998	// Verify firstNonPrunedBlock is not pruned
1999	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
2000		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
2001	}
2002
2003	// Activate the transition in the middle of the chain
2004	if mergePoint == 1 {
2005		merger.ReachTTD()
2006		merger.FinalizePoS()
2007		// Set the terminal total difficulty in the config
2008		gspec.Config.TerminalTotalDifficulty = big.NewInt(int64(len(blocks)))
2009	}
2010
2011	// Generate the sidechain
2012	// First block should be a known block, block after should be a pruned block. So
2013	// canon(pruned), side, side...
2014
2015	// Generate fork chain, make it longer than canon
2016	parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock
2017	parent := blocks[parentIndex]
2018	fork, _ := GenerateChain(&chainConfig, parent, genEngine, db, 2*TriesInMemory, func(i int, b *BlockGen) {
2019		b.SetCoinbase(common.Address{2})
2020	})
2021	// Prepend the parent(s)
2022	var sidechain []*types.Block
2023	for i := numCanonBlocksInSidechain; i > 0; i-- {
2024		sidechain = append(sidechain, blocks[parentIndex+1-i])
2025	}
2026	sidechain = append(sidechain, fork...)
2027	n, err := chain.InsertChain(sidechain)
2028	if err != nil {
2029		t.Errorf("Got error, %v number %d - %d", err, sidechain[n].NumberU64(), n)
2030	}
2031	head := chain.CurrentBlock()
2032	if got := fork[len(fork)-1].Hash(); got != head.Hash() {
2033		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
2034	}
2035}
2036
2037// Tests that importing a sidechain (S), where
2038// - S is sidechain, containing blocks [Sn...Sm]
2039// - C is canon chain, containing blocks [G..Cn..Cm]
2040// - The common ancestor Cc is pruned
2041// - The first block in S: Sn, is == Cn
2042// That is: the sidechain for import contains some blocks already present in canon chain.
2043// So the blocks are
2044// [ Cn, Cn+1, Cc, Sn+3 ... Sm]
2045//   ^    ^    ^  pruned
2046func TestPrunedImportSide(t *testing.T) {
2047	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
2048	//glogger.Verbosity(3)
2049	//log.Root().SetHandler(log.Handler(glogger))
2050	testSideImport(t, 3, 3, -1)
2051	testSideImport(t, 3, -3, -1)
2052	testSideImport(t, 10, 0, -1)
2053	testSideImport(t, 1, 10, -1)
2054	testSideImport(t, 1, -10, -1)
2055}
2056
2057func TestPrunedImportSideWithMerging(t *testing.T) {
2058	//glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
2059	//glogger.Verbosity(3)
2060	//log.Root().SetHandler(log.Handler(glogger))
2061	testSideImport(t, 3, 3, 0)
2062	testSideImport(t, 3, -3, 0)
2063	testSideImport(t, 10, 0, 0)
2064	testSideImport(t, 1, 10, 0)
2065	testSideImport(t, 1, -10, 0)
2066
2067	testSideImport(t, 3, 3, 1)
2068	testSideImport(t, 3, -3, 1)
2069	testSideImport(t, 10, 0, 1)
2070	testSideImport(t, 1, 10, 1)
2071	testSideImport(t, 1, -10, 1)
2072}
2073
2074func TestInsertKnownHeaders(t *testing.T)      { testInsertKnownChainData(t, "headers") }
2075func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") }
2076func TestInsertKnownBlocks(t *testing.T)       { testInsertKnownChainData(t, "blocks") }
2077
2078func testInsertKnownChainData(t *testing.T, typ string) {
2079	engine := ethash.NewFaker()
2080
2081	db := rawdb.NewMemoryDatabase()
2082	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
2083
2084	blocks, receipts := GenerateChain(params.TestChainConfig, genesis, engine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
2085	// A longer chain but total difficulty is lower.
2086	blocks2, receipts2 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
2087	// A shorter chain but total difficulty is higher.
2088	blocks3, receipts3 := GenerateChain(params.TestChainConfig, blocks[len(blocks)-1], engine, db, 64, func(i int, b *BlockGen) {
2089		b.SetCoinbase(common.Address{1})
2090		b.OffsetTime(-9) // A higher difficulty
2091	})
2092	// Import the shared chain and the original canonical one
2093	dir, err := ioutil.TempDir("", "")
2094	if err != nil {
2095		t.Fatalf("failed to create temp freezer dir: %v", err)
2096	}
2097	defer os.Remove(dir)
2098	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false)
2099	if err != nil {
2100		t.Fatalf("failed to create temp freezer db: %v", err)
2101	}
2102	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(chaindb)
2103	defer os.RemoveAll(dir)
2104
2105	chain, err := NewBlockChain(chaindb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
2106	if err != nil {
2107		t.Fatalf("failed to create tester chain: %v", err)
2108	}
2109
2110	var (
2111		inserter func(blocks []*types.Block, receipts []types.Receipts) error
2112		asserter func(t *testing.T, block *types.Block)
2113	)
2114	if typ == "headers" {
2115		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2116			headers := make([]*types.Header, 0, len(blocks))
2117			for _, block := range blocks {
2118				headers = append(headers, block.Header())
2119			}
2120			_, err := chain.InsertHeaderChain(headers, 1)
2121			return err
2122		}
2123		asserter = func(t *testing.T, block *types.Block) {
2124			if chain.CurrentHeader().Hash() != block.Hash() {
2125				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
2126			}
2127		}
2128	} else if typ == "receipts" {
2129		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2130			headers := make([]*types.Header, 0, len(blocks))
2131			for _, block := range blocks {
2132				headers = append(headers, block.Header())
2133			}
2134			_, err := chain.InsertHeaderChain(headers, 1)
2135			if err != nil {
2136				return err
2137			}
2138			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
2139			return err
2140		}
2141		asserter = func(t *testing.T, block *types.Block) {
2142			if chain.CurrentFastBlock().Hash() != block.Hash() {
2143				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
2144			}
2145		}
2146	} else {
2147		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2148			_, err := chain.InsertChain(blocks)
2149			return err
2150		}
2151		asserter = func(t *testing.T, block *types.Block) {
2152			if chain.CurrentBlock().Hash() != block.Hash() {
2153				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
2154			}
2155		}
2156	}
2157
2158	if err := inserter(blocks, receipts); err != nil {
2159		t.Fatalf("failed to insert chain data: %v", err)
2160	}
2161
2162	// Reimport the chain data again. All the imported
2163	// chain data are regarded "known" data.
2164	if err := inserter(blocks, receipts); err != nil {
2165		t.Fatalf("failed to insert chain data: %v", err)
2166	}
2167	asserter(t, blocks[len(blocks)-1])
2168
2169	// Import a long canonical chain with some known data as prefix.
2170	rollback := blocks[len(blocks)/2].NumberU64()
2171
2172	chain.SetHead(rollback - 1)
2173	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
2174		t.Fatalf("failed to insert chain data: %v", err)
2175	}
2176	asserter(t, blocks2[len(blocks2)-1])
2177
2178	// Import a heavier shorter but higher total difficulty chain with some known data as prefix.
2179	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
2180		t.Fatalf("failed to insert chain data: %v", err)
2181	}
2182	asserter(t, blocks3[len(blocks3)-1])
2183
2184	// Import a longer but lower total difficulty chain with some known data as prefix.
2185	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
2186		t.Fatalf("failed to insert chain data: %v", err)
2187	}
2188	// The head shouldn't change.
2189	asserter(t, blocks3[len(blocks3)-1])
2190
2191	// Rollback the heavier chain and re-insert the longer chain again
2192	chain.SetHead(rollback - 1)
2193	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
2194		t.Fatalf("failed to insert chain data: %v", err)
2195	}
2196	asserter(t, blocks2[len(blocks2)-1])
2197}
2198
2199func TestInsertKnownHeadersWithMerging(t *testing.T) {
2200	testInsertKnownChainDataWithMerging(t, "headers", 0)
2201}
2202func TestInsertKnownReceiptChainWithMerging(t *testing.T) {
2203	testInsertKnownChainDataWithMerging(t, "receipts", 0)
2204}
2205func TestInsertKnownBlocksWithMerging(t *testing.T) {
2206	testInsertKnownChainDataWithMerging(t, "blocks", 0)
2207}
2208func TestInsertKnownHeadersAfterMerging(t *testing.T) {
2209	testInsertKnownChainDataWithMerging(t, "headers", 1)
2210}
2211func TestInsertKnownReceiptChainAfterMerging(t *testing.T) {
2212	testInsertKnownChainDataWithMerging(t, "receipts", 1)
2213}
2214func TestInsertKnownBlocksAfterMerging(t *testing.T) {
2215	testInsertKnownChainDataWithMerging(t, "blocks", 1)
2216}
2217
2218// mergeHeight can be assigned in these values:
2219// 0: means the merging is applied since genesis
2220// 1: means the merging is applied after the first segment
2221func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight int) {
2222	// Copy the TestChainConfig so we can modify it during tests
2223	chainConfig := *params.TestChainConfig
2224	var (
2225		db        = rawdb.NewMemoryDatabase()
2226		genesis   = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: &chainConfig}).MustCommit(db)
2227		runMerger = consensus.NewMerger(db)
2228		runEngine = beacon.New(ethash.NewFaker())
2229		genEngine = beacon.New(ethash.NewFaker())
2230	)
2231	applyMerge := func(engine *beacon.Beacon, height int) {
2232		if engine != nil {
2233			runMerger.FinalizePoS()
2234			// Set the terminal total difficulty in the config
2235			chainConfig.TerminalTotalDifficulty = big.NewInt(int64(height))
2236		}
2237	}
2238
2239	// Apply merging since genesis
2240	if mergeHeight == 0 {
2241		applyMerge(genEngine, 0)
2242	}
2243	blocks, receipts := GenerateChain(&chainConfig, genesis, genEngine, db, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
2244
2245	// Apply merging after the first segment
2246	if mergeHeight == 1 {
2247		applyMerge(genEngine, len(blocks))
2248	}
2249	// Longer chain and shorter chain
2250	blocks2, receipts2 := GenerateChain(&chainConfig, blocks[len(blocks)-1], genEngine, db, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
2251	blocks3, receipts3 := GenerateChain(&chainConfig, blocks[len(blocks)-1], genEngine, db, 64, func(i int, b *BlockGen) {
2252		b.SetCoinbase(common.Address{1})
2253		b.OffsetTime(-9) // Time shifted, difficulty shouldn't be changed
2254	})
2255
2256	// Import the shared chain and the original canonical one
2257	dir, err := ioutil.TempDir("", "")
2258	if err != nil {
2259		t.Fatalf("failed to create temp freezer dir: %v", err)
2260	}
2261	defer os.Remove(dir)
2262	chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false)
2263	if err != nil {
2264		t.Fatalf("failed to create temp freezer db: %v", err)
2265	}
2266	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(chaindb)
2267	defer os.RemoveAll(dir)
2268
2269	chain, err := NewBlockChain(chaindb, nil, &chainConfig, runEngine, vm.Config{}, nil, nil)
2270	if err != nil {
2271		t.Fatalf("failed to create tester chain: %v", err)
2272	}
2273	var (
2274		inserter func(blocks []*types.Block, receipts []types.Receipts) error
2275		asserter func(t *testing.T, block *types.Block)
2276	)
2277	if typ == "headers" {
2278		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2279			headers := make([]*types.Header, 0, len(blocks))
2280			for _, block := range blocks {
2281				headers = append(headers, block.Header())
2282			}
2283			_, err := chain.InsertHeaderChain(headers, 1)
2284			return err
2285		}
2286		asserter = func(t *testing.T, block *types.Block) {
2287			if chain.CurrentHeader().Hash() != block.Hash() {
2288				t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex())
2289			}
2290		}
2291	} else if typ == "receipts" {
2292		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2293			headers := make([]*types.Header, 0, len(blocks))
2294			for _, block := range blocks {
2295				headers = append(headers, block.Header())
2296			}
2297			_, err := chain.InsertHeaderChain(headers, 1)
2298			if err != nil {
2299				return err
2300			}
2301			_, err = chain.InsertReceiptChain(blocks, receipts, 0)
2302			return err
2303		}
2304		asserter = func(t *testing.T, block *types.Block) {
2305			if chain.CurrentFastBlock().Hash() != block.Hash() {
2306				t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex())
2307			}
2308		}
2309	} else {
2310		inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
2311			_, err := chain.InsertChain(blocks)
2312			return err
2313		}
2314		asserter = func(t *testing.T, block *types.Block) {
2315			if chain.CurrentBlock().Hash() != block.Hash() {
2316				t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex())
2317			}
2318		}
2319	}
2320
2321	// Apply merging since genesis if required
2322	if mergeHeight == 0 {
2323		applyMerge(runEngine, 0)
2324	}
2325	if err := inserter(blocks, receipts); err != nil {
2326		t.Fatalf("failed to insert chain data: %v", err)
2327	}
2328
2329	// Reimport the chain data again. All the imported
2330	// chain data are regarded "known" data.
2331	if err := inserter(blocks, receipts); err != nil {
2332		t.Fatalf("failed to insert chain data: %v", err)
2333	}
2334	asserter(t, blocks[len(blocks)-1])
2335
2336	// Import a long canonical chain with some known data as prefix.
2337	rollback := blocks[len(blocks)/2].NumberU64()
2338	chain.SetHead(rollback - 1)
2339	if err := inserter(blocks, receipts); err != nil {
2340		t.Fatalf("failed to insert chain data: %v", err)
2341	}
2342	asserter(t, blocks[len(blocks)-1])
2343
2344	// Apply merging after the first segment
2345	if mergeHeight == 1 {
2346		applyMerge(runEngine, len(blocks))
2347	}
2348
2349	// Import a longer chain with some known data as prefix.
2350	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
2351		t.Fatalf("failed to insert chain data: %v", err)
2352	}
2353	asserter(t, blocks2[len(blocks2)-1])
2354
2355	// Import a shorter chain with some known data as prefix.
2356	// The reorg is expected since the fork choice rule is
2357	// already changed.
2358	if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil {
2359		t.Fatalf("failed to insert chain data: %v", err)
2360	}
2361	// The head shouldn't change.
2362	asserter(t, blocks3[len(blocks3)-1])
2363
2364	// Reimport the longer chain again, the reorg is still expected
2365	chain.SetHead(rollback - 1)
2366	if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil {
2367		t.Fatalf("failed to insert chain data: %v", err)
2368	}
2369	asserter(t, blocks2[len(blocks2)-1])
2370}
2371
2372// getLongAndShortChains returns two chains: A is longer, B is heavier.
2373func getLongAndShortChains() (bc *BlockChain, longChain []*types.Block, heavyChain []*types.Block, err error) {
2374	// Generate a canonical chain to act as the main dataset
2375	engine := ethash.NewFaker()
2376	db := rawdb.NewMemoryDatabase()
2377	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
2378
2379	// Generate and import the canonical chain,
2380	// Offset the time, to keep the difficulty low
2381	longChain, _ = GenerateChain(params.TestChainConfig, genesis, engine, db, 80, func(i int, b *BlockGen) {
2382		b.SetCoinbase(common.Address{1})
2383	})
2384	diskdb := rawdb.NewMemoryDatabase()
2385	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
2386
2387	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
2388	if err != nil {
2389		return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err)
2390	}
2391
2392	// Generate fork chain, make it shorter than canon, with common ancestor pretty early
2393	parentIndex := 3
2394	parent := longChain[parentIndex]
2395	heavyChainExt, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 75, func(i int, b *BlockGen) {
2396		b.SetCoinbase(common.Address{2})
2397		b.OffsetTime(-9)
2398	})
2399	heavyChain = append(heavyChain, longChain[:parentIndex+1]...)
2400	heavyChain = append(heavyChain, heavyChainExt...)
2401
2402	// Verify that the test is sane
2403	var (
2404		longerTd  = new(big.Int)
2405		shorterTd = new(big.Int)
2406	)
2407	for index, b := range longChain {
2408		longerTd.Add(longerTd, b.Difficulty())
2409		if index <= parentIndex {
2410			shorterTd.Add(shorterTd, b.Difficulty())
2411		}
2412	}
2413	for _, b := range heavyChain {
2414		shorterTd.Add(shorterTd, b.Difficulty())
2415	}
2416	if shorterTd.Cmp(longerTd) <= 0 {
2417		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd)
2418	}
2419	longerNum := longChain[len(longChain)-1].NumberU64()
2420	shorterNum := heavyChain[len(heavyChain)-1].NumberU64()
2421	if shorterNum >= longerNum {
2422		return nil, nil, nil, fmt.Errorf("Test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum)
2423	}
2424	return chain, longChain, heavyChain, nil
2425}
2426
2427// TestReorgToShorterRemovesCanonMapping tests that if we
2428// 1. Have a chain [0 ... N .. X]
2429// 2. Reorg to shorter but heavier chain [0 ... N ... Y]
2430// 3. Then there should be no canon mapping for the block at height X
2431// 4. The forked block should still be retrievable by hash
2432func TestReorgToShorterRemovesCanonMapping(t *testing.T) {
2433	chain, canonblocks, sideblocks, err := getLongAndShortChains()
2434	if err != nil {
2435		t.Fatal(err)
2436	}
2437	if n, err := chain.InsertChain(canonblocks); err != nil {
2438		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
2439	}
2440	canonNum := chain.CurrentBlock().NumberU64()
2441	canonHash := chain.CurrentBlock().Hash()
2442	_, err = chain.InsertChain(sideblocks)
2443	if err != nil {
2444		t.Errorf("Got error, %v", err)
2445	}
2446	head := chain.CurrentBlock()
2447	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
2448		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
2449	}
2450	// We have now inserted a sidechain.
2451	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
2452		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
2453	}
2454	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
2455		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
2456	}
2457	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
2458		t.Errorf("expected block to be present: %x", blockByHash.Hash())
2459	}
2460	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
2461		t.Errorf("expected header to be present: %x", headerByHash.Hash())
2462	}
2463}
2464
2465// TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario
2466// as TestReorgToShorterRemovesCanonMapping, but applied on headerchain
2467// imports -- that is, for fast sync
2468func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) {
2469	chain, canonblocks, sideblocks, err := getLongAndShortChains()
2470	if err != nil {
2471		t.Fatal(err)
2472	}
2473	// Convert into headers
2474	canonHeaders := make([]*types.Header, len(canonblocks))
2475	for i, block := range canonblocks {
2476		canonHeaders[i] = block.Header()
2477	}
2478	if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil {
2479		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
2480	}
2481	canonNum := chain.CurrentHeader().Number.Uint64()
2482	canonHash := chain.CurrentBlock().Hash()
2483	sideHeaders := make([]*types.Header, len(sideblocks))
2484	for i, block := range sideblocks {
2485		sideHeaders[i] = block.Header()
2486	}
2487	if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil {
2488		t.Fatalf("header %d: failed to insert into chain: %v", n, err)
2489	}
2490	head := chain.CurrentHeader()
2491	if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() {
2492		t.Fatalf("head wrong, expected %x got %x", head.Hash(), got)
2493	}
2494	// We have now inserted a sidechain.
2495	if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil {
2496		t.Errorf("expected block to be gone: %v", blockByNum.NumberU64())
2497	}
2498	if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil {
2499		t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64())
2500	}
2501	if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil {
2502		t.Errorf("expected block to be present: %x", blockByHash.Hash())
2503	}
2504	if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil {
2505		t.Errorf("expected header to be present: %x", headerByHash.Hash())
2506	}
2507}
2508
2509func TestTransactionIndices(t *testing.T) {
2510	// Configure and generate a sample block chain
2511	var (
2512		gendb   = rawdb.NewMemoryDatabase()
2513		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
2514		address = crypto.PubkeyToAddress(key.PublicKey)
2515		funds   = big.NewInt(100000000000000000)
2516		gspec   = &Genesis{
2517			Config:  params.TestChainConfig,
2518			Alloc:   GenesisAlloc{address: {Balance: funds}},
2519			BaseFee: big.NewInt(params.InitialBaseFee),
2520		}
2521		genesis = gspec.MustCommit(gendb)
2522		signer  = types.LatestSigner(gspec.Config)
2523	)
2524	height := uint64(128)
2525	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
2526		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
2527		if err != nil {
2528			panic(err)
2529		}
2530		block.AddTx(tx)
2531	})
2532	blocks2, _ := GenerateChain(gspec.Config, blocks[len(blocks)-1], ethash.NewFaker(), gendb, 10, nil)
2533
2534	check := func(tail *uint64, chain *BlockChain) {
2535		stored := rawdb.ReadTxIndexTail(chain.db)
2536		if tail == nil && stored != nil {
2537			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
2538		}
2539		if tail != nil && *stored != *tail {
2540			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
2541		}
2542		if tail != nil {
2543			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
2544				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
2545				if block.Transactions().Len() == 0 {
2546					continue
2547				}
2548				for _, tx := range block.Transactions() {
2549					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
2550						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
2551					}
2552				}
2553			}
2554			for i := uint64(0); i < *tail; i++ {
2555				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
2556				if block.Transactions().Len() == 0 {
2557					continue
2558				}
2559				for _, tx := range block.Transactions() {
2560					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
2561						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
2562					}
2563				}
2564			}
2565		}
2566	}
2567	frdir, err := ioutil.TempDir("", "")
2568	if err != nil {
2569		t.Fatalf("failed to create temp freezer dir: %v", err)
2570	}
2571	defer os.Remove(frdir)
2572	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
2573	if err != nil {
2574		t.Fatalf("failed to create temp freezer db: %v", err)
2575	}
2576	gspec.MustCommit(ancientDb)
2577
2578	// Import all blocks into ancient db
2579	l := uint64(0)
2580	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
2581	if err != nil {
2582		t.Fatalf("failed to create tester chain: %v", err)
2583	}
2584	headers := make([]*types.Header, len(blocks))
2585	for i, block := range blocks {
2586		headers[i] = block.Header()
2587	}
2588	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
2589		t.Fatalf("failed to insert header %d: %v", n, err)
2590	}
2591	if n, err := chain.InsertReceiptChain(blocks, receipts, 128); err != nil {
2592		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
2593	}
2594	chain.Stop()
2595	ancientDb.Close()
2596
2597	// Init block chain with external ancients, check all needed indices has been indexed.
2598	limit := []uint64{0, 32, 64, 128}
2599	for _, l := range limit {
2600		ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
2601		if err != nil {
2602			t.Fatalf("failed to create temp freezer db: %v", err)
2603		}
2604		gspec.MustCommit(ancientDb)
2605		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
2606		if err != nil {
2607			t.Fatalf("failed to create tester chain: %v", err)
2608		}
2609		time.Sleep(50 * time.Millisecond) // Wait for indices initialisation
2610		var tail uint64
2611		if l != 0 {
2612			tail = uint64(128) - l + 1
2613		}
2614		check(&tail, chain)
2615		chain.Stop()
2616		ancientDb.Close()
2617	}
2618
2619	// Reconstruct a block chain which only reserves HEAD-64 tx indices
2620	ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
2621	if err != nil {
2622		t.Fatalf("failed to create temp freezer db: %v", err)
2623	}
2624	gspec.MustCommit(ancientDb)
2625
2626	limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */}
2627	tails := []uint64{0, 67 /* 130 - 64 + 1 */, 100 /* 131 - 32 + 1 */, 69 /* 132 - 64 + 1 */, 0}
2628	for i, l := range limit {
2629		chain, err = NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
2630		if err != nil {
2631			t.Fatalf("failed to create tester chain: %v", err)
2632		}
2633		chain.InsertChain(blocks2[i : i+1]) // Feed chain a higher block to trigger indices updater.
2634		time.Sleep(50 * time.Millisecond)   // Wait for indices initialisation
2635		check(&tails[i], chain)
2636		chain.Stop()
2637	}
2638}
2639
2640func TestSkipStaleTxIndicesInSnapSync(t *testing.T) {
2641	// Configure and generate a sample block chain
2642	var (
2643		gendb   = rawdb.NewMemoryDatabase()
2644		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
2645		address = crypto.PubkeyToAddress(key.PublicKey)
2646		funds   = big.NewInt(100000000000000000)
2647		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
2648		genesis = gspec.MustCommit(gendb)
2649		signer  = types.LatestSigner(gspec.Config)
2650	)
2651	height := uint64(128)
2652	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), func(i int, block *BlockGen) {
2653		tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key)
2654		if err != nil {
2655			panic(err)
2656		}
2657		block.AddTx(tx)
2658	})
2659
2660	check := func(tail *uint64, chain *BlockChain) {
2661		stored := rawdb.ReadTxIndexTail(chain.db)
2662		if tail == nil && stored != nil {
2663			t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored)
2664		}
2665		if tail != nil && *stored != *tail {
2666			t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored)
2667		}
2668		if tail != nil {
2669			for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ {
2670				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
2671				if block.Transactions().Len() == 0 {
2672					continue
2673				}
2674				for _, tx := range block.Transactions() {
2675					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil {
2676						t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex())
2677					}
2678				}
2679			}
2680			for i := uint64(0); i < *tail; i++ {
2681				block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i)
2682				if block.Transactions().Len() == 0 {
2683					continue
2684				}
2685				for _, tx := range block.Transactions() {
2686					if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil {
2687						t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex())
2688					}
2689				}
2690			}
2691		}
2692	}
2693
2694	frdir, err := ioutil.TempDir("", "")
2695	if err != nil {
2696		t.Fatalf("failed to create temp freezer dir: %v", err)
2697	}
2698	defer os.Remove(frdir)
2699	ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false)
2700	if err != nil {
2701		t.Fatalf("failed to create temp freezer db: %v", err)
2702	}
2703	gspec.MustCommit(ancientDb)
2704
2705	// Import all blocks into ancient db, only HEAD-32 indices are kept.
2706	l := uint64(32)
2707	chain, err := NewBlockChain(ancientDb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, &l)
2708	if err != nil {
2709		t.Fatalf("failed to create tester chain: %v", err)
2710	}
2711	headers := make([]*types.Header, len(blocks))
2712	for i, block := range blocks {
2713		headers[i] = block.Header()
2714	}
2715	if n, err := chain.InsertHeaderChain(headers, 0); err != nil {
2716		t.Fatalf("failed to insert header %d: %v", n, err)
2717	}
2718	// The indices before ancient-N(32) should be ignored. After that all blocks should be indexed.
2719	if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil {
2720		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
2721	}
2722	tail := uint64(32)
2723	check(&tail, chain)
2724}
2725
2726// Benchmarks large blocks with value transfers to non-existing accounts
2727func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
2728	var (
2729		signer          = types.HomesteadSigner{}
2730		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
2731		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
2732		bankFunds       = big.NewInt(100000000000000000)
2733		gspec           = Genesis{
2734			Config: params.TestChainConfig,
2735			Alloc: GenesisAlloc{
2736				testBankAddress: {Balance: bankFunds},
2737				common.HexToAddress("0xc0de"): {
2738					Code:    []byte{0x60, 0x01, 0x50},
2739					Balance: big.NewInt(0),
2740				}, // push 1, pop
2741			},
2742			GasLimit: 100e6, // 100 M
2743		}
2744	)
2745	// Generate the original common chain segment and the two competing forks
2746	engine := ethash.NewFaker()
2747	db := rawdb.NewMemoryDatabase()
2748	genesis := gspec.MustCommit(db)
2749
2750	blockGenerator := func(i int, block *BlockGen) {
2751		block.SetCoinbase(common.Address{1})
2752		for txi := 0; txi < numTxs; txi++ {
2753			uniq := uint64(i*numTxs + txi)
2754			recipient := recipientFn(uniq)
2755			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, block.header.BaseFee, nil), signer, testBankKey)
2756			if err != nil {
2757				b.Error(err)
2758			}
2759			block.AddTx(tx)
2760		}
2761	}
2762
2763	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
2764	b.StopTimer()
2765	b.ResetTimer()
2766	for i := 0; i < b.N; i++ {
2767		// Import the shared chain and the original canonical one
2768		diskdb := rawdb.NewMemoryDatabase()
2769		gspec.MustCommit(diskdb)
2770
2771		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
2772		if err != nil {
2773			b.Fatalf("failed to create tester chain: %v", err)
2774		}
2775		b.StartTimer()
2776		if _, err := chain.InsertChain(shared); err != nil {
2777			b.Fatalf("failed to insert shared chain: %v", err)
2778		}
2779		b.StopTimer()
2780		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
2781			b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got)
2782
2783		}
2784	}
2785}
2786
2787func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
2788	var (
2789		numTxs    = 1000
2790		numBlocks = 1
2791	)
2792	recipientFn := func(nonce uint64) common.Address {
2793		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
2794	}
2795	dataFn := func(nonce uint64) []byte {
2796		return nil
2797	}
2798	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
2799}
2800
2801func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
2802	var (
2803		numTxs    = 1000
2804		numBlocks = 1
2805	)
2806	b.StopTimer()
2807	b.ResetTimer()
2808
2809	recipientFn := func(nonce uint64) common.Address {
2810		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
2811	}
2812	dataFn := func(nonce uint64) []byte {
2813		return nil
2814	}
2815	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
2816}
2817
2818func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
2819	var (
2820		numTxs    = 1000
2821		numBlocks = 1
2822	)
2823	b.StopTimer()
2824	b.ResetTimer()
2825
2826	recipientFn := func(nonce uint64) common.Address {
2827		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
2828	}
2829	dataFn := func(nonce uint64) []byte {
2830		return nil
2831	}
2832	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
2833}
2834
2835// Tests that importing a some old blocks, where all blocks are before the
2836// pruning point.
2837// This internally leads to a sidechain import, since the blocks trigger an
2838// ErrPrunedAncestor error.
2839// This may e.g. happen if
2840//   1. Downloader rollbacks a batch of inserted blocks and exits
2841//   2. Downloader starts to sync again
2842//   3. The blocks fetched are all known and canonical blocks
2843func TestSideImportPrunedBlocks(t *testing.T) {
2844	// Generate a canonical chain to act as the main dataset
2845	engine := ethash.NewFaker()
2846	db := rawdb.NewMemoryDatabase()
2847	genesis := (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
2848
2849	// Generate and import the canonical chain
2850	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*TriesInMemory, nil)
2851	diskdb := rawdb.NewMemoryDatabase()
2852
2853	(&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(diskdb)
2854	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
2855	if err != nil {
2856		t.Fatalf("failed to create tester chain: %v", err)
2857	}
2858	if n, err := chain.InsertChain(blocks); err != nil {
2859		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
2860	}
2861
2862	lastPrunedIndex := len(blocks) - TriesInMemory - 1
2863	lastPrunedBlock := blocks[lastPrunedIndex]
2864
2865	// Verify pruning of lastPrunedBlock
2866	if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) {
2867		t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64())
2868	}
2869	firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory]
2870	// Verify firstNonPrunedBlock is not pruned
2871	if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) {
2872		t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64())
2873	}
2874	// Now re-import some old blocks
2875	blockToReimport := blocks[5:8]
2876	_, err = chain.InsertChain(blockToReimport)
2877	if err != nil {
2878		t.Errorf("Got error, %v", err)
2879	}
2880}
2881
2882// TestDeleteCreateRevert tests a weird state transition corner case that we hit
2883// while changing the internals of statedb. The workflow is that a contract is
2884// self destructed, then in a followup transaction (but same block) it's created
2885// again and the transaction reverted.
2886//
2887// The original statedb implementation flushed dirty objects to the tries after
2888// each transaction, so this works ok. The rework accumulated writes in memory
2889// first, but the journal wiped the entire state object on create-revert.
2890func TestDeleteCreateRevert(t *testing.T) {
2891	var (
2892		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
2893		bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
2894		// Generate a canonical chain to act as the main dataset
2895		engine = ethash.NewFaker()
2896		db     = rawdb.NewMemoryDatabase()
2897
2898		// A sender who makes transactions, has some funds
2899		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
2900		address = crypto.PubkeyToAddress(key.PublicKey)
2901		funds   = big.NewInt(100000000000000000)
2902		gspec   = &Genesis{
2903			Config: params.TestChainConfig,
2904			Alloc: GenesisAlloc{
2905				address: {Balance: funds},
2906				// The address 0xAAAAA selfdestructs if called
2907				aa: {
2908					// Code needs to just selfdestruct
2909					Code:    []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)},
2910					Nonce:   1,
2911					Balance: big.NewInt(0),
2912				},
2913				// The address 0xBBBB send 1 wei to 0xAAAA, then reverts
2914				bb: {
2915					Code: []byte{
2916						byte(vm.PC),          // [0]
2917						byte(vm.DUP1),        // [0,0]
2918						byte(vm.DUP1),        // [0,0,0]
2919						byte(vm.DUP1),        // [0,0,0,0]
2920						byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value)
2921						byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa]
2922						byte(vm.GAS),
2923						byte(vm.CALL),
2924						byte(vm.REVERT),
2925					},
2926					Balance: big.NewInt(1),
2927				},
2928			},
2929		}
2930		genesis = gspec.MustCommit(db)
2931	)
2932
2933	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
2934		b.SetCoinbase(common.Address{1})
2935		// One transaction to AAAA
2936		tx, _ := types.SignTx(types.NewTransaction(0, aa,
2937			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
2938		b.AddTx(tx)
2939		// One transaction to BBBB
2940		tx, _ = types.SignTx(types.NewTransaction(1, bb,
2941			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
2942		b.AddTx(tx)
2943	})
2944	// Import the canonical chain
2945	diskdb := rawdb.NewMemoryDatabase()
2946	gspec.MustCommit(diskdb)
2947
2948	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil, nil)
2949	if err != nil {
2950		t.Fatalf("failed to create tester chain: %v", err)
2951	}
2952	if n, err := chain.InsertChain(blocks); err != nil {
2953		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
2954	}
2955}
2956
2957// TestDeleteRecreateSlots tests a state-transition that contains both deletion
2958// and recreation of contract state.
2959// Contract A exists, has slots 1 and 2 set
2960// Tx 1: Selfdestruct A
2961// Tx 2: Re-create A, set slots 3 and 4
2962// Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
2963// and then the new slots exist
2964func TestDeleteRecreateSlots(t *testing.T) {
2965	var (
2966		// Generate a canonical chain to act as the main dataset
2967		engine = ethash.NewFaker()
2968		db     = rawdb.NewMemoryDatabase()
2969		// A sender who makes transactions, has some funds
2970		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
2971		address   = crypto.PubkeyToAddress(key.PublicKey)
2972		funds     = big.NewInt(1000000000000000)
2973		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
2974		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
2975		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
2976	)
2977	// Populate two slots
2978	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
2979	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
2980
2981	// The bb-code needs to CREATE2 the aa contract. It consists of
2982	// both initcode and deployment code
2983	// initcode:
2984	// 1. Set slots 3=3, 4=4,
2985	// 2. Return aaCode
2986
2987	initCode := []byte{
2988		byte(vm.PUSH1), 0x3, // value
2989		byte(vm.PUSH1), 0x3, // location
2990		byte(vm.SSTORE),     // Set slot[3] = 1
2991		byte(vm.PUSH1), 0x4, // value
2992		byte(vm.PUSH1), 0x4, // location
2993		byte(vm.SSTORE), // Set slot[4] = 1
2994		// Slots are set, now return the code
2995		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
2996		byte(vm.PUSH1), 0x0, // memory start on stack
2997		byte(vm.MSTORE),
2998		// Code is now in memory.
2999		byte(vm.PUSH1), 0x2, // size
3000		byte(vm.PUSH1), byte(32 - 2), // offset
3001		byte(vm.RETURN),
3002	}
3003	if l := len(initCode); l > 32 {
3004		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
3005	}
3006	bbCode := []byte{
3007		// Push initcode onto stack
3008		byte(vm.PUSH1) + byte(len(initCode)-1)}
3009	bbCode = append(bbCode, initCode...)
3010	bbCode = append(bbCode, []byte{
3011		byte(vm.PUSH1), 0x0, // memory start on stack
3012		byte(vm.MSTORE),
3013		byte(vm.PUSH1), 0x00, // salt
3014		byte(vm.PUSH1), byte(len(initCode)), // size
3015		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
3016		byte(vm.PUSH1), 0x00, // endowment
3017		byte(vm.CREATE2),
3018	}...)
3019
3020	initHash := crypto.Keccak256Hash(initCode)
3021	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
3022	t.Logf("Destination address: %x\n", aa)
3023
3024	gspec := &Genesis{
3025		Config: params.TestChainConfig,
3026		Alloc: GenesisAlloc{
3027			address: {Balance: funds},
3028			// The address 0xAAAAA selfdestructs if called
3029			aa: {
3030				// Code needs to just selfdestruct
3031				Code:    aaCode,
3032				Nonce:   1,
3033				Balance: big.NewInt(0),
3034				Storage: aaStorage,
3035			},
3036			// The contract BB recreates AA
3037			bb: {
3038				Code:    bbCode,
3039				Balance: big.NewInt(1),
3040			},
3041		},
3042	}
3043	genesis := gspec.MustCommit(db)
3044
3045	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
3046		b.SetCoinbase(common.Address{1})
3047		// One transaction to AA, to kill it
3048		tx, _ := types.SignTx(types.NewTransaction(0, aa,
3049			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3050		b.AddTx(tx)
3051		// One transaction to BB, to recreate AA
3052		tx, _ = types.SignTx(types.NewTransaction(1, bb,
3053			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3054		b.AddTx(tx)
3055	})
3056	// Import the canonical chain
3057	diskdb := rawdb.NewMemoryDatabase()
3058	gspec.MustCommit(diskdb)
3059	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
3060		Debug:  true,
3061		Tracer: logger.NewJSONLogger(nil, os.Stdout),
3062	}, nil, nil)
3063	if err != nil {
3064		t.Fatalf("failed to create tester chain: %v", err)
3065	}
3066	if n, err := chain.InsertChain(blocks); err != nil {
3067		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3068	}
3069	statedb, _ := chain.State()
3070
3071	// If all is correct, then slot 1 and 2 are zero
3072	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
3073		t.Errorf("got %x exp %x", got, exp)
3074	}
3075	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
3076		t.Errorf("got %x exp %x", got, exp)
3077	}
3078	// Also, 3 and 4 should be set
3079	if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp {
3080		t.Fatalf("got %x exp %x", got, exp)
3081	}
3082	if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp {
3083		t.Fatalf("got %x exp %x", got, exp)
3084	}
3085}
3086
3087// TestDeleteRecreateAccount tests a state-transition that contains deletion of a
3088// contract with storage, and a recreate of the same contract via a
3089// regular value-transfer
3090// Expected outcome is that _all_ slots are cleared from A
3091func TestDeleteRecreateAccount(t *testing.T) {
3092	var (
3093		// Generate a canonical chain to act as the main dataset
3094		engine = ethash.NewFaker()
3095		db     = rawdb.NewMemoryDatabase()
3096		// A sender who makes transactions, has some funds
3097		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
3098		address = crypto.PubkeyToAddress(key.PublicKey)
3099		funds   = big.NewInt(1000000000000000)
3100
3101		aa        = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43")
3102		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
3103		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
3104	)
3105	// Populate two slots
3106	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
3107	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
3108
3109	gspec := &Genesis{
3110		Config: params.TestChainConfig,
3111		Alloc: GenesisAlloc{
3112			address: {Balance: funds},
3113			// The address 0xAAAAA selfdestructs if called
3114			aa: {
3115				// Code needs to just selfdestruct
3116				Code:    aaCode,
3117				Nonce:   1,
3118				Balance: big.NewInt(0),
3119				Storage: aaStorage,
3120			},
3121		},
3122	}
3123	genesis := gspec.MustCommit(db)
3124
3125	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 1, func(i int, b *BlockGen) {
3126		b.SetCoinbase(common.Address{1})
3127		// One transaction to AA, to kill it
3128		tx, _ := types.SignTx(types.NewTransaction(0, aa,
3129			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3130		b.AddTx(tx)
3131		// One transaction to AA, to recreate it (but without storage
3132		tx, _ = types.SignTx(types.NewTransaction(1, aa,
3133			big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3134		b.AddTx(tx)
3135	})
3136	// Import the canonical chain
3137	diskdb := rawdb.NewMemoryDatabase()
3138	gspec.MustCommit(diskdb)
3139	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
3140		Debug:  true,
3141		Tracer: logger.NewJSONLogger(nil, os.Stdout),
3142	}, nil, nil)
3143	if err != nil {
3144		t.Fatalf("failed to create tester chain: %v", err)
3145	}
3146	if n, err := chain.InsertChain(blocks); err != nil {
3147		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3148	}
3149	statedb, _ := chain.State()
3150
3151	// If all is correct, then both slots are zero
3152	if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
3153		t.Errorf("got %x exp %x", got, exp)
3154	}
3155	if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
3156		t.Errorf("got %x exp %x", got, exp)
3157	}
3158}
3159
3160// TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion
3161// and recreation of contract state.
3162// Contract A exists, has slots 1 and 2 set
3163// Tx 1: Selfdestruct A
3164// Tx 2: Re-create A, set slots 3 and 4
3165// Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct,
3166// and then the new slots exist
3167func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
3168	var (
3169		// Generate a canonical chain to act as the main dataset
3170		engine = ethash.NewFaker()
3171		db     = rawdb.NewMemoryDatabase()
3172		// A sender who makes transactions, has some funds
3173		key, _    = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
3174		address   = crypto.PubkeyToAddress(key.PublicKey)
3175		funds     = big.NewInt(1000000000000000)
3176		bb        = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
3177		aaStorage = make(map[common.Hash]common.Hash)          // Initial storage in AA
3178		aaCode    = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct)
3179	)
3180	// Populate two slots
3181	aaStorage[common.HexToHash("01")] = common.HexToHash("01")
3182	aaStorage[common.HexToHash("02")] = common.HexToHash("02")
3183
3184	// The bb-code needs to CREATE2 the aa contract. It consists of
3185	// both initcode and deployment code
3186	// initcode:
3187	// 1. Set slots 3=blocknum+1, 4=4,
3188	// 2. Return aaCode
3189
3190	initCode := []byte{
3191		byte(vm.PUSH1), 0x1, //
3192		byte(vm.NUMBER),     // value = number + 1
3193		byte(vm.ADD),        //
3194		byte(vm.PUSH1), 0x3, // location
3195		byte(vm.SSTORE),     // Set slot[3] = number + 1
3196		byte(vm.PUSH1), 0x4, // value
3197		byte(vm.PUSH1), 0x4, // location
3198		byte(vm.SSTORE), // Set slot[4] = 4
3199		// Slots are set, now return the code
3200		byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack
3201		byte(vm.PUSH1), 0x0, // memory start on stack
3202		byte(vm.MSTORE),
3203		// Code is now in memory.
3204		byte(vm.PUSH1), 0x2, // size
3205		byte(vm.PUSH1), byte(32 - 2), // offset
3206		byte(vm.RETURN),
3207	}
3208	if l := len(initCode); l > 32 {
3209		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
3210	}
3211	bbCode := []byte{
3212		// Push initcode onto stack
3213		byte(vm.PUSH1) + byte(len(initCode)-1)}
3214	bbCode = append(bbCode, initCode...)
3215	bbCode = append(bbCode, []byte{
3216		byte(vm.PUSH1), 0x0, // memory start on stack
3217		byte(vm.MSTORE),
3218		byte(vm.PUSH1), 0x00, // salt
3219		byte(vm.PUSH1), byte(len(initCode)), // size
3220		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
3221		byte(vm.PUSH1), 0x00, // endowment
3222		byte(vm.CREATE2),
3223	}...)
3224
3225	initHash := crypto.Keccak256Hash(initCode)
3226	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
3227	t.Logf("Destination address: %x\n", aa)
3228	gspec := &Genesis{
3229		Config: params.TestChainConfig,
3230		Alloc: GenesisAlloc{
3231			address: {Balance: funds},
3232			// The address 0xAAAAA selfdestructs if called
3233			aa: {
3234				// Code needs to just selfdestruct
3235				Code:    aaCode,
3236				Nonce:   1,
3237				Balance: big.NewInt(0),
3238				Storage: aaStorage,
3239			},
3240			// The contract BB recreates AA
3241			bb: {
3242				Code:    bbCode,
3243				Balance: big.NewInt(1),
3244			},
3245		},
3246	}
3247	genesis := gspec.MustCommit(db)
3248	var nonce uint64
3249
3250	type expectation struct {
3251		exist    bool
3252		blocknum int
3253		values   map[int]int
3254	}
3255	var current = &expectation{
3256		exist:    true, // exists in genesis
3257		blocknum: 0,
3258		values:   map[int]int{1: 1, 2: 2},
3259	}
3260	var expectations []*expectation
3261	var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction {
3262		tx, _ := types.SignTx(types.NewTransaction(nonce, aa,
3263			big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3264		nonce++
3265		if e.exist {
3266			e.exist = false
3267			e.values = nil
3268		}
3269		t.Logf("block %d; adding destruct\n", e.blocknum)
3270		return tx
3271	}
3272	var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction {
3273		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
3274			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3275		nonce++
3276		if !e.exist {
3277			e.exist = true
3278			e.values = map[int]int{3: e.blocknum + 1, 4: 4}
3279		}
3280		t.Logf("block %d; adding resurrect\n", e.blocknum)
3281		return tx
3282	}
3283
3284	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 150, func(i int, b *BlockGen) {
3285		var exp = new(expectation)
3286		exp.blocknum = i + 1
3287		exp.values = make(map[int]int)
3288		for k, v := range current.values {
3289			exp.values[k] = v
3290		}
3291		exp.exist = current.exist
3292
3293		b.SetCoinbase(common.Address{1})
3294		if i%2 == 0 {
3295			b.AddTx(newDestruct(exp, b))
3296		}
3297		if i%3 == 0 {
3298			b.AddTx(newResurrect(exp, b))
3299		}
3300		if i%5 == 0 {
3301			b.AddTx(newDestruct(exp, b))
3302		}
3303		if i%7 == 0 {
3304			b.AddTx(newResurrect(exp, b))
3305		}
3306		expectations = append(expectations, exp)
3307		current = exp
3308	})
3309	// Import the canonical chain
3310	diskdb := rawdb.NewMemoryDatabase()
3311	gspec.MustCommit(diskdb)
3312	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
3313		//Debug:  true,
3314		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
3315	}, nil, nil)
3316	if err != nil {
3317		t.Fatalf("failed to create tester chain: %v", err)
3318	}
3319	var asHash = func(num int) common.Hash {
3320		return common.BytesToHash([]byte{byte(num)})
3321	}
3322	for i, block := range blocks {
3323		blockNum := i + 1
3324		if n, err := chain.InsertChain([]*types.Block{block}); err != nil {
3325			t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3326		}
3327		statedb, _ := chain.State()
3328		// If all is correct, then slot 1 and 2 are zero
3329		if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp {
3330			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
3331		}
3332		if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp {
3333			t.Errorf("block %d, got %x exp %x", blockNum, got, exp)
3334		}
3335		exp := expectations[i]
3336		if exp.exist {
3337			if !statedb.Exist(aa) {
3338				t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa)
3339			}
3340			for slot, val := range exp.values {
3341				if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue {
3342					t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue)
3343				}
3344			}
3345		} else {
3346			if statedb.Exist(aa) {
3347				t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa)
3348			}
3349		}
3350	}
3351}
3352
3353// TestInitThenFailCreateContract tests a pretty notorious case that happened
3354// on mainnet over blocks 7338108, 7338110 and 7338115.
3355// - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated
3356//   with 0.001 ether (thus created but no code)
3357// - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on
3358//   the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the
3359//   deployment fails due to OOG during initcode execution
3360// - Block 7338115: another tx checks the balance of
3361//   e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as
3362//   zero.
3363//
3364// The problem being that the snapshotter maintains a destructset, and adds items
3365// to the destructset in case something is created "onto" an existing item.
3366// We need to either roll back the snapDestructs, or not place it into snapDestructs
3367// in the first place.
3368//
3369func TestInitThenFailCreateContract(t *testing.T) {
3370	var (
3371		// Generate a canonical chain to act as the main dataset
3372		engine = ethash.NewFaker()
3373		db     = rawdb.NewMemoryDatabase()
3374		// A sender who makes transactions, has some funds
3375		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
3376		address = crypto.PubkeyToAddress(key.PublicKey)
3377		funds   = big.NewInt(1000000000000000)
3378		bb      = common.HexToAddress("0x000000000000000000000000000000000000bbbb")
3379	)
3380
3381	// The bb-code needs to CREATE2 the aa contract. It consists of
3382	// both initcode and deployment code
3383	// initcode:
3384	// 1. If blocknum < 1, error out (e.g invalid opcode)
3385	// 2. else, return a snippet of code
3386	initCode := []byte{
3387		byte(vm.PUSH1), 0x1, // y (2)
3388		byte(vm.NUMBER), // x (number)
3389		byte(vm.GT),     // x > y?
3390		byte(vm.PUSH1), byte(0x8),
3391		byte(vm.JUMPI), // jump to label if number > 2
3392		byte(0xFE),     // illegal opcode
3393		byte(vm.JUMPDEST),
3394		byte(vm.PUSH1), 0x2, // size
3395		byte(vm.PUSH1), 0x0, // offset
3396		byte(vm.RETURN), // return 2 bytes of zero-code
3397	}
3398	if l := len(initCode); l > 32 {
3399		t.Fatalf("init code is too long for a pushx, need a more elaborate deployer")
3400	}
3401	bbCode := []byte{
3402		// Push initcode onto stack
3403		byte(vm.PUSH1) + byte(len(initCode)-1)}
3404	bbCode = append(bbCode, initCode...)
3405	bbCode = append(bbCode, []byte{
3406		byte(vm.PUSH1), 0x0, // memory start on stack
3407		byte(vm.MSTORE),
3408		byte(vm.PUSH1), 0x00, // salt
3409		byte(vm.PUSH1), byte(len(initCode)), // size
3410		byte(vm.PUSH1), byte(32 - len(initCode)), // offset
3411		byte(vm.PUSH1), 0x00, // endowment
3412		byte(vm.CREATE2),
3413	}...)
3414
3415	initHash := crypto.Keccak256Hash(initCode)
3416	aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:])
3417	t.Logf("Destination address: %x\n", aa)
3418
3419	gspec := &Genesis{
3420		Config: params.TestChainConfig,
3421		Alloc: GenesisAlloc{
3422			address: {Balance: funds},
3423			// The address aa has some funds
3424			aa: {Balance: big.NewInt(100000)},
3425			// The contract BB tries to create code onto AA
3426			bb: {
3427				Code:    bbCode,
3428				Balance: big.NewInt(1),
3429			},
3430		},
3431	}
3432	genesis := gspec.MustCommit(db)
3433	nonce := uint64(0)
3434	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 4, func(i int, b *BlockGen) {
3435		b.SetCoinbase(common.Address{1})
3436		// One transaction to BB
3437		tx, _ := types.SignTx(types.NewTransaction(nonce, bb,
3438			big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key)
3439		b.AddTx(tx)
3440		nonce++
3441	})
3442
3443	// Import the canonical chain
3444	diskdb := rawdb.NewMemoryDatabase()
3445	gspec.MustCommit(diskdb)
3446	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{
3447		//Debug:  true,
3448		//Tracer: vm.NewJSONLogger(nil, os.Stdout),
3449	}, nil, nil)
3450	if err != nil {
3451		t.Fatalf("failed to create tester chain: %v", err)
3452	}
3453	statedb, _ := chain.State()
3454	if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
3455		t.Fatalf("Genesis err, got %v exp %v", got, exp)
3456	}
3457	// First block tries to create, but fails
3458	{
3459		block := blocks[0]
3460		if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil {
3461			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
3462		}
3463		statedb, _ = chain.State()
3464		if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 {
3465			t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp)
3466		}
3467	}
3468	// Import the rest of the blocks
3469	for _, block := range blocks[1:] {
3470		if _, err := chain.InsertChain([]*types.Block{block}); err != nil {
3471			t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err)
3472		}
3473	}
3474}
3475
3476// TestEIP2718Transition tests that an EIP-2718 transaction will be accepted
3477// after the fork block has passed. This is verified by sending an EIP-2930
3478// access list transaction, which specifies a single slot access, and then
3479// checking that the gas usage of a hot SLOAD and a cold SLOAD are calculated
3480// correctly.
3481func TestEIP2718Transition(t *testing.T) {
3482	var (
3483		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
3484
3485		// Generate a canonical chain to act as the main dataset
3486		engine = ethash.NewFaker()
3487		db     = rawdb.NewMemoryDatabase()
3488
3489		// A sender who makes transactions, has some funds
3490		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
3491		address = crypto.PubkeyToAddress(key.PublicKey)
3492		funds   = big.NewInt(1000000000000000)
3493		gspec   = &Genesis{
3494			Config: params.TestChainConfig,
3495			Alloc: GenesisAlloc{
3496				address: {Balance: funds},
3497				// The address 0xAAAA sloads 0x00 and 0x01
3498				aa: {
3499					Code: []byte{
3500						byte(vm.PC),
3501						byte(vm.PC),
3502						byte(vm.SLOAD),
3503						byte(vm.SLOAD),
3504					},
3505					Nonce:   0,
3506					Balance: big.NewInt(0),
3507				},
3508			},
3509		}
3510		genesis = gspec.MustCommit(db)
3511	)
3512
3513	blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
3514		b.SetCoinbase(common.Address{1})
3515
3516		// One transaction to 0xAAAA
3517		signer := types.LatestSigner(gspec.Config)
3518		tx, _ := types.SignNewTx(key, signer, &types.AccessListTx{
3519			ChainID:  gspec.Config.ChainID,
3520			Nonce:    0,
3521			To:       &aa,
3522			Gas:      30000,
3523			GasPrice: b.header.BaseFee,
3524			AccessList: types.AccessList{{
3525				Address:     aa,
3526				StorageKeys: []common.Hash{{0}},
3527			}},
3528		})
3529		b.AddTx(tx)
3530	})
3531
3532	// Import the canonical chain
3533	diskdb := rawdb.NewMemoryDatabase()
3534	gspec.MustCommit(diskdb)
3535
3536	chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
3537	if err != nil {
3538		t.Fatalf("failed to create tester chain: %v", err)
3539	}
3540	if n, err := chain.InsertChain(blocks); err != nil {
3541		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3542	}
3543
3544	block := chain.GetBlockByNumber(1)
3545
3546	// Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list
3547	expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
3548		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
3549	if block.GasUsed() != expected {
3550		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed())
3551
3552	}
3553}
3554
3555// TestEIP1559Transition tests the following:
3556//
3557// 1. A transaction whose gasFeeCap is greater than the baseFee is valid.
3558// 2. Gas accounting for access lists on EIP-1559 transactions is correct.
3559// 3. Only the transaction's tip will be received by the coinbase.
3560// 4. The transaction sender pays for both the tip and baseFee.
3561// 5. The coinbase receives only the partially realized tip when
3562//    gasFeeCap - gasTipCap < baseFee.
3563// 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap).
3564func TestEIP1559Transition(t *testing.T) {
3565	var (
3566		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
3567
3568		// Generate a canonical chain to act as the main dataset
3569		engine = ethash.NewFaker()
3570		db     = rawdb.NewMemoryDatabase()
3571
3572		// A sender who makes transactions, has some funds
3573		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
3574		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
3575		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
3576		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
3577		funds   = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether))
3578		gspec   = &Genesis{
3579			Config: params.AllEthashProtocolChanges,
3580			Alloc: GenesisAlloc{
3581				addr1: {Balance: funds},
3582				addr2: {Balance: funds},
3583				// The address 0xAAAA sloads 0x00 and 0x01
3584				aa: {
3585					Code: []byte{
3586						byte(vm.PC),
3587						byte(vm.PC),
3588						byte(vm.SLOAD),
3589						byte(vm.SLOAD),
3590					},
3591					Nonce:   0,
3592					Balance: big.NewInt(0),
3593				},
3594			},
3595		}
3596	)
3597
3598	gspec.Config.BerlinBlock = common.Big0
3599	gspec.Config.LondonBlock = common.Big0
3600	genesis := gspec.MustCommit(db)
3601	signer := types.LatestSigner(gspec.Config)
3602
3603	blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
3604		b.SetCoinbase(common.Address{1})
3605
3606		// One transaction to 0xAAAA
3607		accesses := types.AccessList{types.AccessTuple{
3608			Address:     aa,
3609			StorageKeys: []common.Hash{{0}},
3610		}}
3611
3612		txdata := &types.DynamicFeeTx{
3613			ChainID:    gspec.Config.ChainID,
3614			Nonce:      0,
3615			To:         &aa,
3616			Gas:        30000,
3617			GasFeeCap:  newGwei(5),
3618			GasTipCap:  big.NewInt(2),
3619			AccessList: accesses,
3620			Data:       []byte{},
3621		}
3622		tx := types.NewTx(txdata)
3623		tx, _ = types.SignTx(tx, signer, key1)
3624
3625		b.AddTx(tx)
3626	})
3627
3628	diskdb := rawdb.NewMemoryDatabase()
3629	gspec.MustCommit(diskdb)
3630
3631	chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{}, nil, nil)
3632	if err != nil {
3633		t.Fatalf("failed to create tester chain: %v", err)
3634	}
3635	if n, err := chain.InsertChain(blocks); err != nil {
3636		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3637	}
3638
3639	block := chain.GetBlockByNumber(1)
3640
3641	// 1+2: Ensure EIP-1559 access lists are accounted for via gas usage.
3642	expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas +
3643		vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929
3644	if block.GasUsed() != expectedGas {
3645		t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed())
3646	}
3647
3648	state, _ := chain.State()
3649
3650	// 3: Ensure that miner received only the tx's tip.
3651	actual := state.GetBalance(block.Coinbase())
3652	expected := new(big.Int).Add(
3653		new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()),
3654		ethash.ConstantinopleBlockReward,
3655	)
3656	if actual.Cmp(expected) != 0 {
3657		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
3658	}
3659
3660	// 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee).
3661	actual = new(big.Int).Sub(funds, state.GetBalance(addr1))
3662	expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64()))
3663	if actual.Cmp(expected) != 0 {
3664		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
3665	}
3666
3667	blocks, _ = GenerateChain(gspec.Config, block, engine, db, 1, func(i int, b *BlockGen) {
3668		b.SetCoinbase(common.Address{2})
3669
3670		txdata := &types.LegacyTx{
3671			Nonce:    0,
3672			To:       &aa,
3673			Gas:      30000,
3674			GasPrice: newGwei(5),
3675		}
3676		tx := types.NewTx(txdata)
3677		tx, _ = types.SignTx(tx, signer, key2)
3678
3679		b.AddTx(tx)
3680	})
3681
3682	if n, err := chain.InsertChain(blocks); err != nil {
3683		t.Fatalf("block %d: failed to insert into chain: %v", n, err)
3684	}
3685
3686	block = chain.GetBlockByNumber(2)
3687	state, _ = chain.State()
3688	effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64()
3689
3690	// 6+5: Ensure that miner received only the tx's effective tip.
3691	actual = state.GetBalance(block.Coinbase())
3692	expected = new(big.Int).Add(
3693		new(big.Int).SetUint64(block.GasUsed()*effectiveTip),
3694		ethash.ConstantinopleBlockReward,
3695	)
3696	if actual.Cmp(expected) != 0 {
3697		t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual)
3698	}
3699
3700	// 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee).
3701	actual = new(big.Int).Sub(funds, state.GetBalance(addr2))
3702	expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64()))
3703	if actual.Cmp(expected) != 0 {
3704		t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual)
3705	}
3706}
3707