github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/blockchain_test.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"math/rand"
     7  	"sync"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/neatlab/neatio/chain/consensus"
    12  
    13  	"github.com/neatlab/neatio/chain/core/rawdb"
    14  	"github.com/neatlab/neatio/chain/core/state"
    15  	"github.com/neatlab/neatio/chain/core/types"
    16  	"github.com/neatlab/neatio/chain/core/vm"
    17  	"github.com/neatlab/neatio/neatdb"
    18  	"github.com/neatlab/neatio/params"
    19  	"github.com/neatlab/neatio/utilities/common"
    20  	"github.com/neatlab/neatio/utilities/crypto"
    21  )
    22  
    23  func newCanonical(engine consensus.Engine, n int, full bool) (neatdb.Database, *BlockChain, error) {
    24  	var (
    25  		db      = rawdb.NewMemoryDatabase()
    26  		genesis = new(Genesis).MustCommit(db)
    27  	)
    28  
    29  	blockchain, _ := NewBlockChain(db, nil, params.TestChainConfig, engine, vm.Config{}, nil)
    30  
    31  	if n == 0 {
    32  		return db, blockchain, nil
    33  	}
    34  	if full {
    35  
    36  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    37  		_, err := blockchain.InsertChain(blocks)
    38  		return db, blockchain, err
    39  	}
    40  
    41  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    42  	_, err := blockchain.InsertHeaderChain(headers, 1)
    43  	return db, blockchain, err
    44  }
    45  
    46  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    47  
    48  	db, blockchain2, err := newCanonical(nil, i, full)
    49  	if err != nil {
    50  		t.Fatal("could not make new canonical in testFork", err)
    51  	}
    52  	defer blockchain2.Stop()
    53  
    54  	var hash1, hash2 common.Hash
    55  	if full {
    56  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    57  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    58  	} else {
    59  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    60  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    61  	}
    62  	if hash1 != hash2 {
    63  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    64  	}
    65  
    66  	var (
    67  		blockChainB  []*types.Block
    68  		headerChainB []*types.Header
    69  	)
    70  	if full {
    71  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, nil, db, forkSeed)
    72  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
    73  			t.Fatalf("failed to insert forking chain: %v", err)
    74  		}
    75  	} else {
    76  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, nil, db, forkSeed)
    77  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
    78  			t.Fatalf("failed to insert forking chain: %v", err)
    79  		}
    80  	}
    81  
    82  	var tdPre, tdPost *big.Int
    83  
    84  	if full {
    85  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
    86  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
    87  			t.Fatalf("failed to import forked block chain: %v", err)
    88  		}
    89  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
    90  	} else {
    91  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
    92  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
    93  			t.Fatalf("failed to import forked header chain: %v", err)
    94  		}
    95  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
    96  	}
    97  
    98  	comparator(tdPre, tdPost)
    99  }
   100  
   101  func printChain(bc *BlockChain) {
   102  	for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
   103  		b := bc.GetBlockByNumber(uint64(i))
   104  		fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
   105  	}
   106  }
   107  
   108  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   109  	for _, block := range chain {
   110  
   111  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   112  		if err == nil {
   113  			err = blockchain.validator.ValidateBody(block)
   114  		}
   115  		if err != nil {
   116  			if err == ErrKnownBlock {
   117  				continue
   118  			}
   119  			return err
   120  		}
   121  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache)
   122  		if err != nil {
   123  			return err
   124  		}
   125  		receipts, _, usedGas, _, err := blockchain.Processor().Process(block, statedb, vm.Config{})
   126  		if err != nil {
   127  			blockchain.reportBlock(block, receipts, err)
   128  			return err
   129  		}
   130  		err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas)
   131  		if err != nil {
   132  			blockchain.reportBlock(block, receipts, err)
   133  			return err
   134  		}
   135  		blockchain.chainmu.Lock()
   136  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   137  		rawdb.WriteBlock(blockchain.db, block)
   138  		statedb.Commit(false)
   139  		blockchain.chainmu.Unlock()
   140  	}
   141  	return nil
   142  }
   143  
   144  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   145  	for _, header := range chain {
   146  
   147  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   148  			return err
   149  		}
   150  
   151  		blockchain.chainmu.Lock()
   152  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   153  		rawdb.WriteHeader(blockchain.db, header)
   154  		blockchain.chainmu.Unlock()
   155  	}
   156  	return nil
   157  }
   158  
   159  func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) {
   160  	_, err := blockchain.InsertChain(chain)
   161  	if err != nil {
   162  		fmt.Println(err)
   163  		t.FailNow()
   164  	}
   165  	done <- true
   166  }
   167  
   168  func TestLastBlock(t *testing.T) {
   169  	_, blockchain, err := newCanonical(nil, 0, true)
   170  	if err != nil {
   171  		t.Fatalf("failed to create pristine chain: %v", err)
   172  	}
   173  	defer blockchain.Stop()
   174  
   175  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, nil, blockchain.db, 0)
   176  	if _, err := blockchain.InsertChain(blocks); err != nil {
   177  		t.Fatalf("Failed to insert block: %v", err)
   178  	}
   179  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   180  		t.Fatalf("Write/Get HeadBlockHash failed")
   181  	}
   182  }
   183  
   184  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   185  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   186  
   187  func testExtendCanonical(t *testing.T, full bool) {
   188  	length := 5
   189  
   190  	_, processor, err := newCanonical(nil, length, full)
   191  	if err != nil {
   192  		t.Fatalf("failed to make new canonical chain: %v", err)
   193  	}
   194  	defer processor.Stop()
   195  
   196  	better := func(td1, td2 *big.Int) {
   197  		if td2.Cmp(td1) <= 0 {
   198  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   199  		}
   200  	}
   201  
   202  	testFork(t, processor, length, 1, full, better)
   203  	testFork(t, processor, length, 2, full, better)
   204  	testFork(t, processor, length, 5, full, better)
   205  	testFork(t, processor, length, 10, full, better)
   206  }
   207  
   208  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   209  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   210  
   211  func testShorterFork(t *testing.T, full bool) {
   212  	length := 10
   213  
   214  	_, processor, err := newCanonical(nil, length, full)
   215  	if err != nil {
   216  		t.Fatalf("failed to make new canonical chain: %v", err)
   217  	}
   218  	defer processor.Stop()
   219  
   220  	worse := func(td1, td2 *big.Int) {
   221  		if td2.Cmp(td1) >= 0 {
   222  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   223  		}
   224  	}
   225  
   226  	testFork(t, processor, 0, 3, full, worse)
   227  	testFork(t, processor, 0, 7, full, worse)
   228  	testFork(t, processor, 1, 1, full, worse)
   229  	testFork(t, processor, 1, 7, full, worse)
   230  	testFork(t, processor, 5, 3, full, worse)
   231  	testFork(t, processor, 5, 4, full, worse)
   232  }
   233  
   234  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   235  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   236  
   237  func testLongerFork(t *testing.T, full bool) {
   238  	length := 10
   239  
   240  	_, processor, err := newCanonical(nil, length, full)
   241  	if err != nil {
   242  		t.Fatalf("failed to make new canonical chain: %v", err)
   243  	}
   244  	defer processor.Stop()
   245  
   246  	better := func(td1, td2 *big.Int) {
   247  		if td2.Cmp(td1) <= 0 {
   248  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   249  		}
   250  	}
   251  
   252  	testFork(t, processor, 0, 11, full, better)
   253  	testFork(t, processor, 0, 15, full, better)
   254  	testFork(t, processor, 1, 10, full, better)
   255  	testFork(t, processor, 1, 12, full, better)
   256  	testFork(t, processor, 5, 6, full, better)
   257  	testFork(t, processor, 5, 8, full, better)
   258  }
   259  
   260  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   261  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   262  
   263  func testEqualFork(t *testing.T, full bool) {
   264  	length := 10
   265  
   266  	_, processor, err := newCanonical(nil, length, full)
   267  	if err != nil {
   268  		t.Fatalf("failed to make new canonical chain: %v", err)
   269  	}
   270  	defer processor.Stop()
   271  
   272  	equal := func(td1, td2 *big.Int) {
   273  		if td2.Cmp(td1) != 0 {
   274  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   275  		}
   276  	}
   277  
   278  	testFork(t, processor, 0, 10, full, equal)
   279  	testFork(t, processor, 1, 9, full, equal)
   280  	testFork(t, processor, 2, 8, full, equal)
   281  	testFork(t, processor, 5, 5, full, equal)
   282  	testFork(t, processor, 6, 4, full, equal)
   283  	testFork(t, processor, 9, 1, full, equal)
   284  }
   285  
   286  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   287  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   288  
   289  func testBrokenChain(t *testing.T, full bool) {
   290  
   291  	db, blockchain, err := newCanonical(nil, 10, full)
   292  	if err != nil {
   293  		t.Fatalf("failed to make new canonical chain: %v", err)
   294  	}
   295  	defer blockchain.Stop()
   296  
   297  	if full {
   298  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, nil, db, forkSeed)[1:]
   299  		if err := testBlockChainImport(chain, blockchain); err == nil {
   300  			t.Errorf("broken block chain not reported")
   301  		}
   302  	} else {
   303  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, nil, db, forkSeed)[1:]
   304  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   305  			t.Errorf("broken header chain not reported")
   306  		}
   307  	}
   308  }
   309  
   310  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   311  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   312  
   313  func testReorgLong(t *testing.T, full bool) {
   314  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full)
   315  }
   316  
   317  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   318  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   319  
   320  func testReorgShort(t *testing.T, full bool) {
   321  
   322  	easy := make([]int64, 96)
   323  	for i := 0; i < len(easy); i++ {
   324  		easy[i] = 60
   325  	}
   326  	diff := make([]int64, len(easy)-1)
   327  	for i := 0; i < len(diff); i++ {
   328  		diff[i] = -9
   329  	}
   330  	testReorg(t, easy, diff, 12615120, full)
   331  }
   332  
   333  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   334  
   335  	db, blockchain, err := newCanonical(nil, 0, full)
   336  	if err != nil {
   337  		t.Fatalf("failed to create pristine chain: %v", err)
   338  	}
   339  	defer blockchain.Stop()
   340  
   341  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), nil, db, len(first), func(i int, b *BlockGen) {
   342  		b.OffsetTime(first[i])
   343  	})
   344  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), nil, db, len(second), func(i int, b *BlockGen) {
   345  		b.OffsetTime(second[i])
   346  	})
   347  	if full {
   348  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   349  			t.Fatalf("failed to insert easy chain: %v", err)
   350  		}
   351  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   352  			t.Fatalf("failed to insert difficult chain: %v", err)
   353  		}
   354  	} else {
   355  		easyHeaders := make([]*types.Header, len(easyBlocks))
   356  		for i, block := range easyBlocks {
   357  			easyHeaders[i] = block.Header()
   358  		}
   359  		diffHeaders := make([]*types.Header, len(diffBlocks))
   360  		for i, block := range diffBlocks {
   361  			diffHeaders[i] = block.Header()
   362  		}
   363  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   364  			t.Fatalf("failed to insert easy chain: %v", err)
   365  		}
   366  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   367  			t.Fatalf("failed to insert difficult chain: %v", err)
   368  		}
   369  	}
   370  
   371  	if full {
   372  		prev := blockchain.CurrentBlock()
   373  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   374  			if prev.ParentHash() != block.Hash() {
   375  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   376  			}
   377  		}
   378  	} else {
   379  		prev := blockchain.CurrentHeader()
   380  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   381  			if prev.ParentHash != header.Hash() {
   382  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   383  			}
   384  		}
   385  	}
   386  
   387  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   388  	if full {
   389  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   390  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   391  		}
   392  	} else {
   393  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   394  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   395  		}
   396  	}
   397  }
   398  
   399  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   400  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   401  
   402  func testBadHashes(t *testing.T, full bool) {
   403  
   404  	db, blockchain, err := newCanonical(nil, 0, full)
   405  	if err != nil {
   406  		t.Fatalf("failed to create pristine chain: %v", err)
   407  	}
   408  	defer blockchain.Stop()
   409  
   410  	if full {
   411  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, nil, db, 10)
   412  
   413  		BadHashes[blocks[2].Header().Hash()] = true
   414  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   415  
   416  		_, err = blockchain.InsertChain(blocks)
   417  	} else {
   418  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, nil, db, 10)
   419  
   420  		BadHashes[headers[2].Hash()] = true
   421  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   422  
   423  		_, err = blockchain.InsertHeaderChain(headers, 1)
   424  	}
   425  	if err != ErrBlacklistedHash {
   426  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   427  	}
   428  }
   429  
   430  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   431  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   432  
   433  func testReorgBadHashes(t *testing.T, full bool) {
   434  
   435  	db, blockchain, err := newCanonical(nil, 0, full)
   436  	if err != nil {
   437  		t.Fatalf("failed to create pristine chain: %v", err)
   438  	}
   439  
   440  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, nil, db, 10)
   441  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, nil, db, 10)
   442  
   443  	if full {
   444  		if _, err = blockchain.InsertChain(blocks); err != nil {
   445  			t.Errorf("failed to import blocks: %v", err)
   446  		}
   447  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   448  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   449  		}
   450  		BadHashes[blocks[3].Header().Hash()] = true
   451  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   452  	} else {
   453  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   454  			t.Errorf("failed to import headers: %v", err)
   455  		}
   456  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   457  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   458  		}
   459  		BadHashes[headers[3].Hash()] = true
   460  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   461  	}
   462  	blockchain.Stop()
   463  
   464  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, nil, vm.Config{}, nil)
   465  	if err != nil {
   466  		t.Fatalf("failed to create new chain manager: %v", err)
   467  	}
   468  	if full {
   469  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   470  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   471  		}
   472  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   473  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   474  		}
   475  	} else {
   476  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   477  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   478  		}
   479  	}
   480  	ncm.Stop()
   481  }
   482  
   483  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   484  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   485  
   486  func testInsertNonceError(t *testing.T, full bool) {
   487  	for i := 1; i < 25 && !t.Failed(); i++ {
   488  
   489  		db, blockchain, err := newCanonical(nil, 0, full)
   490  		if err != nil {
   491  			t.Fatalf("failed to create pristine chain: %v", err)
   492  		}
   493  		defer blockchain.Stop()
   494  
   495  		var (
   496  			failAt  int
   497  			failRes int
   498  			failNum uint64
   499  		)
   500  		if full {
   501  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, nil, db, 0)
   502  
   503  			failAt = rand.Int() % len(blocks)
   504  			failNum = blocks[failAt].NumberU64()
   505  
   506  			failRes, err = blockchain.InsertChain(blocks)
   507  		} else {
   508  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, nil, db, 0)
   509  
   510  			failAt = rand.Int() % len(headers)
   511  			failNum = headers[failAt].Number.Uint64()
   512  
   513  			blockchain.hc.engine = blockchain.engine
   514  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   515  		}
   516  
   517  		if failRes != failAt {
   518  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   519  		}
   520  
   521  		for j := 0; j < i-failAt; j++ {
   522  			if full {
   523  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   524  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   525  				}
   526  			} else {
   527  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   528  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   529  				}
   530  			}
   531  		}
   532  	}
   533  }
   534  
   535  func TestFastVsFullChains(t *testing.T) {
   536  
   537  	var (
   538  		gendb   = rawdb.NewMemoryDatabase()
   539  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   540  		address = crypto.PubkeyToAddress(key.PublicKey)
   541  		funds   = big.NewInt(1000000000)
   542  		gspec   = &Genesis{
   543  			Config: params.TestChainConfig,
   544  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   545  		}
   546  		genesis = gspec.MustCommit(gendb)
   547  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   548  	)
   549  	blocks, receipts := GenerateChain(gspec.Config, genesis, nil, gendb, 1024, func(i int, block *BlockGen) {
   550  		block.SetCoinbase(common.Address{0x00})
   551  
   552  		if i%3 == 2 {
   553  			for j := 0; j < i%4+1; j++ {
   554  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   555  				if err != nil {
   556  					panic(err)
   557  				}
   558  				block.AddTx(tx)
   559  			}
   560  		}
   561  
   562  		if i%5 == 5 {
   563  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   564  		}
   565  	})
   566  
   567  	archiveDb := rawdb.NewMemoryDatabase()
   568  	gspec.MustCommit(archiveDb)
   569  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, nil, vm.Config{}, nil)
   570  	defer archive.Stop()
   571  
   572  	if n, err := archive.InsertChain(blocks); err != nil {
   573  		t.Fatalf("failed to process block %d: %v", n, err)
   574  	}
   575  
   576  	fastDb := rawdb.NewMemoryDatabase()
   577  	gspec.MustCommit(fastDb)
   578  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, nil, vm.Config{}, nil)
   579  	defer fast.Stop()
   580  
   581  	headers := make([]*types.Header, len(blocks))
   582  	for i, block := range blocks {
   583  		headers[i] = block.Header()
   584  	}
   585  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   586  		t.Fatalf("failed to insert header %d: %v", n, err)
   587  	}
   588  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   589  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   590  	}
   591  
   592  	for i := 0; i < len(blocks); i++ {
   593  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   594  
   595  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   596  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   597  		}
   598  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   599  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   600  		}
   601  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   602  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   603  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   604  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   605  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   606  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   607  		}
   608  		if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   609  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   610  		}
   611  	}
   612  
   613  	for i := 0; i < len(blocks)+1; i++ {
   614  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   615  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   616  		}
   617  	}
   618  }
   619  
   620  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   621  
   622  	var (
   623  		gendb   = rawdb.NewMemoryDatabase()
   624  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   625  		address = crypto.PubkeyToAddress(key.PublicKey)
   626  		funds   = big.NewInt(1000000000)
   627  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   628  		genesis = gspec.MustCommit(gendb)
   629  	)
   630  	height := uint64(1024)
   631  	blocks, receipts := GenerateChain(gspec.Config, genesis, nil, gendb, int(height), nil)
   632  
   633  	remove := []common.Hash{}
   634  	for _, block := range blocks[height/2:] {
   635  		remove = append(remove, block.Hash())
   636  	}
   637  
   638  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   639  		if num := chain.CurrentBlock().NumberU64(); num != block {
   640  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   641  		}
   642  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   643  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   644  		}
   645  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   646  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   647  		}
   648  	}
   649  
   650  	archiveDb := rawdb.NewMemoryDatabase()
   651  	gspec.MustCommit(archiveDb)
   652  
   653  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, nil, vm.Config{}, nil)
   654  	if n, err := archive.InsertChain(blocks); err != nil {
   655  		t.Fatalf("failed to process block %d: %v", n, err)
   656  	}
   657  	defer archive.Stop()
   658  
   659  	assert(t, "archive", archive, height, height, height)
   660  	archive.Rollback(remove)
   661  	assert(t, "archive", archive, height/2, height/2, height/2)
   662  
   663  	fastDb := rawdb.NewMemoryDatabase()
   664  	gspec.MustCommit(fastDb)
   665  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, nil, vm.Config{}, nil)
   666  	defer fast.Stop()
   667  
   668  	headers := make([]*types.Header, len(blocks))
   669  	for i, block := range blocks {
   670  		headers[i] = block.Header()
   671  	}
   672  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   673  		t.Fatalf("failed to insert header %d: %v", n, err)
   674  	}
   675  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   676  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   677  	}
   678  	assert(t, "fast", fast, height, height, 0)
   679  	fast.Rollback(remove)
   680  	assert(t, "fast", fast, height/2, height/2, 0)
   681  
   682  	lightDb := rawdb.NewMemoryDatabase()
   683  	gspec.MustCommit(lightDb)
   684  
   685  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, nil, vm.Config{}, nil)
   686  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   687  		t.Fatalf("failed to insert header %d: %v", n, err)
   688  	}
   689  	defer light.Stop()
   690  
   691  	assert(t, "light", light, height, 0, 0)
   692  	light.Rollback(remove)
   693  	assert(t, "light", light, height/2, 0, 0)
   694  }
   695  
   696  func TestChainTxReorgs(t *testing.T) {
   697  	var (
   698  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   699  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   700  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   701  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   702  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   703  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   704  		db      = rawdb.NewMemoryDatabase()
   705  		gspec   = &Genesis{
   706  			Config:   params.TestChainConfig,
   707  			GasLimit: 3141592,
   708  			Alloc: GenesisAlloc{
   709  				addr1: {Balance: big.NewInt(1000000)},
   710  				addr2: {Balance: big.NewInt(1000000)},
   711  				addr3: {Balance: big.NewInt(1000000)},
   712  			},
   713  		}
   714  		genesis = gspec.MustCommit(db)
   715  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   716  	)
   717  
   718  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   719  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   720  
   721  	var pastDrop, freshDrop *types.Transaction
   722  
   723  	var pastAdd, freshAdd, futureAdd *types.Transaction
   724  
   725  	chain, _ := GenerateChain(gspec.Config, genesis, nil, db, 3, func(i int, gen *BlockGen) {
   726  		switch i {
   727  		case 0:
   728  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   729  
   730  			gen.AddTx(pastDrop)
   731  			gen.AddTx(postponed)
   732  
   733  		case 2:
   734  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   735  
   736  			gen.AddTx(freshDrop)
   737  			gen.AddTx(swapped)
   738  
   739  			gen.OffsetTime(9)
   740  		}
   741  	})
   742  
   743  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, nil, vm.Config{}, nil)
   744  	if i, err := blockchain.InsertChain(chain); err != nil {
   745  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   746  	}
   747  	defer blockchain.Stop()
   748  
   749  	chain, _ = GenerateChain(gspec.Config, genesis, nil, db, 5, func(i int, gen *BlockGen) {
   750  		switch i {
   751  		case 0:
   752  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   753  			gen.AddTx(pastAdd)
   754  
   755  		case 2:
   756  			gen.AddTx(postponed)
   757  			gen.AddTx(swapped)
   758  
   759  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   760  			gen.AddTx(freshAdd)
   761  
   762  		case 3:
   763  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   764  			gen.AddTx(futureAdd)
   765  		}
   766  	})
   767  	if _, err := blockchain.InsertChain(chain); err != nil {
   768  		t.Fatalf("failed to insert forked chain: %v", err)
   769  	}
   770  
   771  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   772  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   773  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   774  		}
   775  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil {
   776  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   777  		}
   778  	}
   779  
   780  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   781  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   782  			t.Errorf("add %d: expected tx to be found", i)
   783  		}
   784  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   785  			t.Errorf("add %d: expected receipt to be found", i)
   786  		}
   787  	}
   788  
   789  	for i, tx := range (types.Transactions{postponed, swapped}) {
   790  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   791  			t.Errorf("share %d: expected tx to be found", i)
   792  		}
   793  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   794  			t.Errorf("share %d: expected receipt to be found", i)
   795  		}
   796  	}
   797  }
   798  
   799  func TestLogReorgs(t *testing.T) {
   800  
   801  	var (
   802  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   803  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   804  		db      = rawdb.NewMemoryDatabase()
   805  
   806  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   807  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   808  		genesis = gspec.MustCommit(db)
   809  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   810  	)
   811  
   812  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, nil, vm.Config{}, nil)
   813  	defer blockchain.Stop()
   814  
   815  	rmLogsCh := make(chan RemovedLogsEvent)
   816  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   817  	chain, _ := GenerateChain(params.TestChainConfig, genesis, nil, db, 2, func(i int, gen *BlockGen) {
   818  		if i == 1 {
   819  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   820  			if err != nil {
   821  				t.Fatalf("failed to create tx: %v", err)
   822  			}
   823  			gen.AddTx(tx)
   824  		}
   825  	})
   826  	if _, err := blockchain.InsertChain(chain); err != nil {
   827  		t.Fatalf("failed to insert chain: %v", err)
   828  	}
   829  
   830  	chain, _ = GenerateChain(params.TestChainConfig, genesis, nil, db, 3, func(i int, gen *BlockGen) {})
   831  	if _, err := blockchain.InsertChain(chain); err != nil {
   832  		t.Fatalf("failed to insert forked chain: %v", err)
   833  	}
   834  
   835  	timeout := time.NewTimer(1 * time.Second)
   836  	select {
   837  	case ev := <-rmLogsCh:
   838  		if len(ev.Logs) == 0 {
   839  			t.Error("expected logs")
   840  		}
   841  	case <-timeout.C:
   842  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   843  	}
   844  }
   845  
   846  func TestReorgSideEvent(t *testing.T) {
   847  	var (
   848  		db      = rawdb.NewMemoryDatabase()
   849  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   850  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   851  		gspec   = &Genesis{
   852  			Config: params.TestChainConfig,
   853  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
   854  		}
   855  		genesis = gspec.MustCommit(db)
   856  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   857  	)
   858  
   859  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, nil, vm.Config{}, nil)
   860  	defer blockchain.Stop()
   861  
   862  	chain, _ := GenerateChain(gspec.Config, genesis, nil, db, 3, func(i int, gen *BlockGen) {})
   863  	if _, err := blockchain.InsertChain(chain); err != nil {
   864  		t.Fatalf("failed to insert chain: %v", err)
   865  	}
   866  
   867  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, nil, db, 4, func(i int, gen *BlockGen) {
   868  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
   869  		if i == 2 {
   870  			gen.OffsetTime(-9)
   871  		}
   872  		if err != nil {
   873  			t.Fatalf("failed to create tx: %v", err)
   874  		}
   875  		gen.AddTx(tx)
   876  	})
   877  	chainSideCh := make(chan ChainSideEvent, 64)
   878  	blockchain.SubscribeChainSideEvent(chainSideCh)
   879  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   880  		t.Fatalf("failed to insert chain: %v", err)
   881  	}
   882  
   883  	expectedSideHashes := map[common.Hash]bool{
   884  		replacementBlocks[0].Hash(): true,
   885  		replacementBlocks[1].Hash(): true,
   886  		chain[0].Hash():             true,
   887  		chain[1].Hash():             true,
   888  		chain[2].Hash():             true,
   889  	}
   890  
   891  	i := 0
   892  
   893  	const timeoutDura = 10 * time.Second
   894  	timeout := time.NewTimer(timeoutDura)
   895  done:
   896  	for {
   897  		select {
   898  		case ev := <-chainSideCh:
   899  			block := ev.Block
   900  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   901  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
   902  			}
   903  			i++
   904  
   905  			if i == len(expectedSideHashes) {
   906  				timeout.Stop()
   907  
   908  				break done
   909  			}
   910  			timeout.Reset(timeoutDura)
   911  
   912  		case <-timeout.C:
   913  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
   914  		}
   915  	}
   916  
   917  	select {
   918  	case e := <-chainSideCh:
   919  		t.Errorf("unexpected event fired: %v", e)
   920  	case <-time.After(250 * time.Millisecond):
   921  	}
   922  
   923  }
   924  
   925  func TestCanonicalBlockRetrieval(t *testing.T) {
   926  	_, blockchain, err := newCanonical(nil, 0, true)
   927  	if err != nil {
   928  		t.Fatalf("failed to create pristine chain: %v", err)
   929  	}
   930  	defer blockchain.Stop()
   931  
   932  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, nil, blockchain.db, 10, func(i int, gen *BlockGen) {})
   933  
   934  	var pend sync.WaitGroup
   935  	pend.Add(len(chain))
   936  
   937  	for i := range chain {
   938  		go func(block *types.Block) {
   939  			defer pend.Done()
   940  
   941  			for {
   942  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
   943  				if ch == (common.Hash{}) {
   944  					continue
   945  				}
   946  				if ch != block.Hash() {
   947  					t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
   948  				}
   949  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
   950  				if fb == nil {
   951  					t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
   952  				}
   953  				if fb.Hash() != block.Hash() {
   954  					t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
   955  				}
   956  				return
   957  			}
   958  		}(chain[i])
   959  
   960  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
   961  			t.Fatalf("failed to insert block %d: %v", i, err)
   962  		}
   963  	}
   964  	pend.Wait()
   965  }
   966  
   967  func TestEIP155Transition(t *testing.T) {
   968  
   969  	var (
   970  		db         = rawdb.NewMemoryDatabase()
   971  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   972  		address    = crypto.PubkeyToAddress(key.PublicKey)
   973  		funds      = big.NewInt(1000000000)
   974  		deleteAddr = common.Address{1}
   975  		gspec      = &Genesis{
   976  			Config: &params.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
   977  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
   978  		}
   979  		genesis = gspec.MustCommit(db)
   980  	)
   981  
   982  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, nil, vm.Config{}, nil)
   983  	defer blockchain.Stop()
   984  
   985  	blocks, _ := GenerateChain(gspec.Config, genesis, nil, db, 4, func(i int, block *BlockGen) {
   986  		var (
   987  			tx      *types.Transaction
   988  			err     error
   989  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
   990  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 100000, new(big.Int), nil), signer, key)
   991  			}
   992  		)
   993  		switch i {
   994  		case 0:
   995  			tx, err = basicTx(types.HomesteadSigner{})
   996  			if err != nil {
   997  				t.Fatal(err)
   998  			}
   999  			block.AddTx(tx)
  1000  		case 2:
  1001  			tx, err = basicTx(types.HomesteadSigner{})
  1002  			if err != nil {
  1003  				t.Fatal(err)
  1004  			}
  1005  			block.AddTx(tx)
  1006  
  1007  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1008  			if err != nil {
  1009  				t.Fatal(err)
  1010  			}
  1011  			block.AddTx(tx)
  1012  		case 3:
  1013  			tx, err = basicTx(types.HomesteadSigner{})
  1014  			if err != nil {
  1015  				t.Fatal(err)
  1016  			}
  1017  			block.AddTx(tx)
  1018  
  1019  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1020  			if err != nil {
  1021  				t.Fatal(err)
  1022  			}
  1023  			block.AddTx(tx)
  1024  		}
  1025  	})
  1026  
  1027  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1028  		t.Fatal(err)
  1029  	}
  1030  	block := blockchain.GetBlockByNumber(1)
  1031  	if block.Transactions()[0].Protected() {
  1032  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1033  	}
  1034  
  1035  	block = blockchain.GetBlockByNumber(3)
  1036  	if block.Transactions()[0].Protected() {
  1037  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1038  	}
  1039  	if !block.Transactions()[1].Protected() {
  1040  		t.Error("Expected block[3].txs[1] to be replay protected")
  1041  	}
  1042  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1043  		t.Fatal(err)
  1044  	}
  1045  
  1046  	config := &params.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1047  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], nil, db, 4, func(i int, block *BlockGen) {
  1048  		var (
  1049  			tx      *types.Transaction
  1050  			err     error
  1051  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1052  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 100000, new(big.Int), nil), signer, key)
  1053  			}
  1054  		)
  1055  		switch i {
  1056  		case 0:
  1057  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1058  			if err != nil {
  1059  				t.Fatal(err)
  1060  			}
  1061  			block.AddTx(tx)
  1062  		}
  1063  	})
  1064  	_, err := blockchain.InsertChain(blocks)
  1065  	if err != types.ErrInvalidChainId {
  1066  		t.Error("expected error:", types.ErrInvalidChainId)
  1067  	}
  1068  }
  1069  
  1070  func TestEIP161AccountRemoval(t *testing.T) {
  1071  
  1072  	var (
  1073  		db      = rawdb.NewMemoryDatabase()
  1074  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1075  		address = crypto.PubkeyToAddress(key.PublicKey)
  1076  		funds   = big.NewInt(1000000000)
  1077  		theAddr = common.Address{1}
  1078  		gspec   = &Genesis{
  1079  			Config: &params.ChainConfig{
  1080  				ChainId:        big.NewInt(1),
  1081  				HomesteadBlock: new(big.Int),
  1082  				EIP155Block:    new(big.Int),
  1083  				EIP158Block:    big.NewInt(2),
  1084  			},
  1085  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1086  		}
  1087  		genesis = gspec.MustCommit(db)
  1088  	)
  1089  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, nil, vm.Config{}, nil)
  1090  	defer blockchain.Stop()
  1091  
  1092  	blocks, _ := GenerateChain(gspec.Config, genesis, nil, db, 3, func(i int, block *BlockGen) {
  1093  		var (
  1094  			tx     *types.Transaction
  1095  			err    error
  1096  			signer = types.NewEIP155Signer(gspec.Config.ChainId)
  1097  		)
  1098  		switch i {
  1099  		case 0:
  1100  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 100000, new(big.Int), nil), signer, key)
  1101  		case 1:
  1102  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 100000, new(big.Int), nil), signer, key)
  1103  		case 2:
  1104  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 100000, new(big.Int), nil), signer, key)
  1105  		}
  1106  		if err != nil {
  1107  			t.Fatal(err)
  1108  		}
  1109  		block.AddTx(tx)
  1110  	})
  1111  
  1112  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1113  		t.Fatal(err)
  1114  	}
  1115  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1116  		t.Error("expected account to exist")
  1117  	}
  1118  
  1119  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1120  		t.Fatal(err)
  1121  	}
  1122  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1123  		t.Error("account should not exist")
  1124  	}
  1125  
  1126  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1127  		t.Fatal(err)
  1128  	}
  1129  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1130  		t.Error("account should not exist")
  1131  	}
  1132  }
  1133  
  1134  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1135  
  1136  	engine := nil
  1137  
  1138  	db := rawdb.NewMemoryDatabase()
  1139  	genesis := new(Genesis).MustCommit(db)
  1140  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1141  
  1142  	forks := make([]*types.Block, len(blocks))
  1143  	for i := 0; i < len(forks); i++ {
  1144  		parent := genesis
  1145  		if i > 0 {
  1146  			parent = blocks[i-1]
  1147  		}
  1148  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1149  		forks[i] = fork[0]
  1150  	}
  1151  
  1152  	diskdb := rawdb.NewMemoryDatabase()
  1153  	new(Genesis).MustCommit(diskdb)
  1154  
  1155  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1156  	if err != nil {
  1157  		t.Fatalf("failed to create tester chain: %v", err)
  1158  	}
  1159  	for i := 0; i < len(blocks); i++ {
  1160  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1161  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1162  		}
  1163  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1164  			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])
  1165  		}
  1166  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1167  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1168  		}
  1169  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1170  			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])
  1171  		}
  1172  	}
  1173  }
  1174  
  1175  func TestTrieForkGC(t *testing.T) {
  1176  
  1177  	engine := nil
  1178  
  1179  	db := rawdb.NewMemoryDatabase()
  1180  	genesis := new(Genesis).MustCommit(db)
  1181  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1182  
  1183  	forks := make([]*types.Block, len(blocks))
  1184  	for i := 0; i < len(forks); i++ {
  1185  		parent := genesis
  1186  		if i > 0 {
  1187  			parent = blocks[i-1]
  1188  		}
  1189  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1190  		forks[i] = fork[0]
  1191  	}
  1192  
  1193  	diskdb := rawdb.NewMemoryDatabase()
  1194  	new(Genesis).MustCommit(diskdb)
  1195  
  1196  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1197  	if err != nil {
  1198  		t.Fatalf("failed to create tester chain: %v", err)
  1199  	}
  1200  	for i := 0; i < len(blocks); i++ {
  1201  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1202  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1203  		}
  1204  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1205  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1206  		}
  1207  	}
  1208  
  1209  	for i := 0; i < triesInMemory; i++ {
  1210  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1211  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1212  	}
  1213  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1214  		t.Fatalf("stale tries still alive after garbase collection")
  1215  	}
  1216  }
  1217  
  1218  func TestLargeReorgTrieGC(t *testing.T) {
  1219  
  1220  	engine := nil
  1221  
  1222  	db := rawdb.NewMemoryDatabase()
  1223  	genesis := new(Genesis).MustCommit(db)
  1224  
  1225  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1226  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1227  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1228  
  1229  	diskdb := rawdb.NewMemoryDatabase()
  1230  	new(Genesis).MustCommit(diskdb)
  1231  
  1232  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1233  	if err != nil {
  1234  		t.Fatalf("failed to create tester chain: %v", err)
  1235  	}
  1236  	if _, err := chain.InsertChain(shared); err != nil {
  1237  		t.Fatalf("failed to insert shared chain: %v", err)
  1238  	}
  1239  	if _, err := chain.InsertChain(original); err != nil {
  1240  		t.Fatalf("failed to insert shared chain: %v", err)
  1241  	}
  1242  
  1243  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1244  		t.Fatalf("common-but-old ancestor still cache")
  1245  	}
  1246  
  1247  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1248  		t.Fatalf("failed to insert competitor chain: %v", err)
  1249  	}
  1250  	for i, block := range competitor[:len(competitor)-2] {
  1251  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1252  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1253  		}
  1254  	}
  1255  
  1256  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1257  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1258  	}
  1259  	for i, block := range competitor[:len(competitor)-triesInMemory] {
  1260  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1261  			t.Fatalf("competitor %d: competing chain state missing", i)
  1262  		}
  1263  	}
  1264  }