gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/core/blockchain_test.go (about)

     1  // Copyright 2018 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain 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 aquachain 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 aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"math/big"
    21  	"math/rand"
    22  	"testing"
    23  	"time"
    24  
    25  	"gitlab.com/aquachain/aquachain/aquadb"
    26  	"gitlab.com/aquachain/aquachain/common"
    27  	"gitlab.com/aquachain/aquachain/consensus/aquahash"
    28  	"gitlab.com/aquachain/aquachain/core/state"
    29  	"gitlab.com/aquachain/aquachain/core/types"
    30  	"gitlab.com/aquachain/aquachain/core/vm"
    31  	"gitlab.com/aquachain/aquachain/crypto"
    32  	"gitlab.com/aquachain/aquachain/params"
    33  )
    34  
    35  // Test fork of length N starting from block i
    36  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    37  	// Copy old chain up to #i into a new db
    38  	db, blockchain2, err := newCanonical(aquahash.NewFaker(), i, full)
    39  	if err != nil {
    40  		t.Fatal("could not make new canonical in testFork", err)
    41  	}
    42  	defer blockchain2.Stop()
    43  
    44  	// Assert the chains have the same header/block at #i
    45  	var hash1, hash2 common.Hash
    46  	if full {
    47  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    48  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    49  	} else {
    50  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    51  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    52  	}
    53  	if hash1 != hash2 {
    54  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    55  	}
    56  	// Extend the newly created chain
    57  	var (
    58  		blockChainB  []*types.Block
    59  		headerChainB []*types.Header
    60  	)
    61  	if full {
    62  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, aquahash.NewFaker(), db, forkSeed)
    63  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
    64  			t.Fatalf("failed to insert forking chain: %v", err)
    65  		}
    66  	} else {
    67  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, aquahash.NewFaker(), db, forkSeed)
    68  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
    69  			t.Fatalf("failed to insert forking chain: %v", err)
    70  		}
    71  	}
    72  	// Sanity check that the forked chain can be imported into the original
    73  	var tdPre, tdPost *big.Int
    74  
    75  	if full {
    76  		blk := blockchain.CurrentBlock()
    77  		hash := blk.Hash()
    78  		tdPre = blockchain.GetTdByHash(hash)
    79  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
    80  			t.Fatalf("failed to import forked block chain: %v", err)
    81  		}
    82  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
    83  	} else {
    84  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
    85  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
    86  			t.Fatalf("failed to import forked header chain: %v", err)
    87  		}
    88  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
    89  	}
    90  	// Compare the total difficulties of the chains
    91  	comparator(tdPre, tdPost)
    92  }
    93  
    94  // testBlockChainImport tries to process a chain of blocks, writing them into
    95  // the database if successful.
    96  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
    97  	for _, block := range chain {
    98  		// Try and process the block
    99  		//block.SetVersion(blockchain.GetBlockVersion(block.Number()))
   100  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   101  		if err == nil {
   102  			err = blockchain.validator.ValidateBody(block)
   103  		}
   104  		if err != nil {
   105  			if err == ErrKnownBlock {
   106  				continue
   107  			}
   108  			// if !blockchain.HasState(block.Hash()) {
   109  			// 	fmt.Printf("block: %s\nparent: %s\n", block, blockchain.GetBlockByHash(block.ParentHash()))
   110  			// }
   111  			return err
   112  		}
   113  		parent := blockchain.GetBlockByHash(block.ParentHash())
   114  		statedb, err := state.New(parent.Root(), blockchain.stateCache)
   115  		if err != nil {
   116  			return err
   117  		}
   118  		receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{})
   119  		if err != nil {
   120  			blockchain.reportBlock(block, receipts, err)
   121  			return err
   122  		}
   123  		err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas)
   124  		if err != nil {
   125  			blockchain.reportBlock(block, receipts, err)
   126  			return err
   127  		}
   128  		blockchain.mu.Lock()
   129  		WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   130  		WriteBlock(blockchain.db, block)
   131  		statedb.Commit(false)
   132  		blockchain.mu.Unlock()
   133  	}
   134  	return nil
   135  }
   136  
   137  // testHeaderChainImport tries to process a chain of header, writing them into
   138  // the database if successful.
   139  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   140  	for _, header := range chain {
   141  		// Try and validate the header
   142  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   143  			return err
   144  		}
   145  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   146  		blockchain.mu.Lock()
   147  		WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   148  		WriteHeader(blockchain.db, header)
   149  		blockchain.mu.Unlock()
   150  	}
   151  	return nil
   152  }
   153  
   154  func TestLastBlock(t *testing.T) {
   155  	_, blockchain, err := newCanonical(aquahash.NewFaker(), 0, true)
   156  	if err != nil {
   157  		t.Fatalf("failed to create pristine chain: %v", err)
   158  	}
   159  	defer blockchain.Stop()
   160  
   161  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, aquahash.NewFullFaker(), blockchain.db, 0)
   162  	if _, err := blockchain.InsertChain(blocks); err != nil {
   163  		t.Fatalf("Failed to insert block: %v", err)
   164  	}
   165  	if blocks[len(blocks)-1].Hash() != GetHeadBlockHash(blockchain.db) {
   166  		t.Fatalf("Write/Get HeadBlockHash failed")
   167  	}
   168  }
   169  
   170  // Tests that given a starting canonical chain of a given size, it can be extended
   171  // with various length chains.
   172  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   173  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   174  
   175  func testExtendCanonical(t *testing.T, full bool) {
   176  	length := 5
   177  
   178  	// Make first chain starting from genesis
   179  	_, processor, err := newCanonical(aquahash.NewFaker(), length, full)
   180  	if err != nil {
   181  		t.Fatalf("failed to make new canonical chain: %v", err)
   182  	}
   183  	defer processor.Stop()
   184  
   185  	// Define the difficulty comparator
   186  	better := func(td1, td2 *big.Int) {
   187  		if td2.Cmp(td1) <= 0 {
   188  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   189  		}
   190  	}
   191  	// Start fork from current height
   192  	testFork(t, processor, length, 1, full, better)
   193  	testFork(t, processor, length, 2, full, better)
   194  	testFork(t, processor, length, 5, full, better)
   195  	testFork(t, processor, length, 10, full, better)
   196  }
   197  
   198  // Tests that given a starting canonical chain of a given size, creating shorter
   199  // forks do not take canonical ownership.
   200  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   201  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   202  
   203  func testShorterFork(t *testing.T, full bool) {
   204  	length := 10
   205  
   206  	// Make first chain starting from genesis
   207  	_, processor, err := newCanonical(aquahash.NewFaker(), length, full)
   208  	if err != nil {
   209  		t.Fatalf("failed to make new canonical chain: %v", err)
   210  	}
   211  	defer processor.Stop()
   212  
   213  	// Define the difficulty comparator
   214  	worse := func(td1, td2 *big.Int) {
   215  		if td2.Cmp(td1) >= 0 {
   216  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   217  		}
   218  	}
   219  	// Sum of numbers must be less than `length` for this to be a shorter fork
   220  	testFork(t, processor, 0, 3, full, worse)
   221  	testFork(t, processor, 0, 7, full, worse)
   222  	testFork(t, processor, 1, 1, full, worse)
   223  	testFork(t, processor, 1, 7, full, worse)
   224  	testFork(t, processor, 5, 3, full, worse)
   225  	testFork(t, processor, 5, 4, full, worse)
   226  }
   227  
   228  // Tests that given a starting canonical chain of a given size, creating longer
   229  // forks do take canonical ownership.
   230  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   231  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   232  
   233  func testLongerFork(t *testing.T, full bool) {
   234  	length := 10
   235  
   236  	// Make first chain starting from genesis
   237  	_, processor, err := newCanonical(aquahash.NewFaker(), length, full)
   238  	if err != nil {
   239  		t.Fatalf("failed to make new canonical chain: %v", err)
   240  	}
   241  	defer processor.Stop()
   242  
   243  	// Define the difficulty comparator
   244  	better := func(td1, td2 *big.Int) {
   245  		if td2.Cmp(td1) <= 0 {
   246  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   247  		}
   248  	}
   249  	// Sum of numbers must be greater than `length` for this to be a longer fork
   250  	testFork(t, processor, 0, 11, full, better)
   251  	testFork(t, processor, 0, 15, full, better)
   252  	testFork(t, processor, 1, 10, full, better)
   253  	testFork(t, processor, 1, 12, full, better)
   254  	testFork(t, processor, 5, 6, full, better)
   255  	testFork(t, processor, 5, 8, full, better)
   256  }
   257  
   258  // Tests that given a starting canonical chain of a given size, creating equal
   259  // forks do take canonical ownership.
   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  	// Make first chain starting from genesis
   267  	_, processor, err := newCanonical(aquahash.NewFaker(), length, full)
   268  	if err != nil {
   269  		t.Fatalf("failed to make new canonical chain: %v", err)
   270  	}
   271  	defer processor.Stop()
   272  
   273  	// Define the difficulty comparator
   274  	equal := func(td1, td2 *big.Int) {
   275  		if td2.Cmp(td1) != 0 {
   276  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   277  		}
   278  	}
   279  	// Sum of numbers must be equal to `length` for this to be an equal fork
   280  	testFork(t, processor, 0, 10, full, equal)
   281  	testFork(t, processor, 1, 9, full, equal)
   282  	testFork(t, processor, 2, 8, full, equal)
   283  	testFork(t, processor, 5, 5, full, equal)
   284  	testFork(t, processor, 6, 4, full, equal)
   285  	testFork(t, processor, 9, 1, full, equal)
   286  }
   287  
   288  // Tests that chains missing links do not get accepted by the processor.
   289  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   290  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   291  
   292  func testBrokenChain(t *testing.T, full bool) {
   293  	// Make chain starting from genesis
   294  	db, blockchain, err := newCanonical(aquahash.NewFaker(), 10, full)
   295  	if err != nil {
   296  		t.Fatalf("failed to make new canonical chain: %v", err)
   297  	}
   298  	defer blockchain.Stop()
   299  
   300  	// Create a forked chain, and try to insert with a missing link
   301  	if full {
   302  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, aquahash.NewFaker(), db, forkSeed)[1:]
   303  		if err := testBlockChainImport(chain, blockchain); err == nil {
   304  			t.Errorf("broken block chain not reported")
   305  		}
   306  	} else {
   307  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, aquahash.NewFaker(), db, forkSeed)[1:]
   308  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   309  			t.Errorf("broken header chain not reported")
   310  		}
   311  	}
   312  }
   313  
   314  // Tests that reorganising a long difficult chain after a short easy one
   315  // overwrites the canonical numbers and links in the database.
   316  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   317  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   318  
   319  func testReorgShort(t *testing.T, full bool) {
   320  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 399609468-10667223, full)
   321  }
   322  
   323  // Tests that reorganising a short difficult chain after a long easy one
   324  // overwrites the canonical numbers and links in the database.
   325  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   326  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   327  
   328  func testReorgLong(t *testing.T, full bool) {
   329  	// Create a long easy chain vs. a short heavy one. Due to difficulty adjustment
   330  	// we need a fairly long chain of blocks with different difficulties for a short
   331  	// one to become heavyer than a long one. The 96 is an empirical value.
   332  	easy := make([]int64, 96)
   333  	for i := 0; i < len(easy); i++ {
   334  		easy[i] = 240
   335  	}
   336  	diff := make([]int64, len(easy)-1)
   337  	for i := 0; i < len(diff); i++ {
   338  		diff[i] = -20
   339  	}
   340  	testReorg(t, easy, diff, 1124583695, full)
   341  }
   342  
   343  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   344  	// Create a pristine chain and database
   345  	db, blockchain, err := newCanonical(aquahash.NewFaker(), 0, full)
   346  	if err != nil {
   347  		t.Fatalf("failed to create pristine chain: %v", err)
   348  	}
   349  	defer blockchain.Stop()
   350  
   351  	var headNum *big.Int
   352  	var head *types.Header
   353  	var headTd *big.Int
   354  	// Insert an easy and a difficult chain afterwards
   355  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), aquahash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   356  		b.OffsetTime(first[i])
   357  	})
   358  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), aquahash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   359  		b.OffsetTime(second[i])
   360  	})
   361  
   362  	if full {
   363  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   364  			t.Fatalf("failed to insert easy chain: %v", err)
   365  		}
   366  		headNum = blockchain.CurrentBlock().Number()
   367  		head = blockchain.CurrentBlock().Header()
   368  		headTd = blockchain.GetTdByHash(head.Hash())
   369  		println("easy chain", headNum.String(), "td", headTd.String())
   370  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   371  			t.Fatalf("failed to insert difficult chain: %v", err)
   372  		}
   373  		headNum = blockchain.CurrentBlock().Number()
   374  		head = blockchain.CurrentBlock().Header()
   375  		headTd = blockchain.GetTdByHash(head.Hash())
   376  	} else {
   377  		easyHeaders := make([]*types.Header, len(easyBlocks))
   378  		for i, block := range easyBlocks {
   379  			easyHeaders[i] = block.Header()
   380  		}
   381  		diffHeaders := make([]*types.Header, len(diffBlocks))
   382  		for i, block := range diffBlocks {
   383  			diffHeaders[i] = block.Header()
   384  		}
   385  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   386  			t.Fatalf("failed to insert easy chain: %v", err)
   387  		}
   388  		head = blockchain.CurrentHeader()
   389  		headNum = blockchain.CurrentHeader().Number
   390  		headTd = blockchain.GetTdByHash(head.Hash())
   391  		println("easy chain", headNum.String(), "td", headTd.String())
   392  
   393  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   394  			t.Fatalf("failed to insert difficult chain: %v", err)
   395  		}
   396  		head = blockchain.CurrentHeader()
   397  		headNum = blockchain.CurrentHeader().Number
   398  		headTd = blockchain.GetTdByHash(head.Hash())
   399  	}
   400  	println("current chain", headNum.String(), "td", headTd.String())
   401  
   402  	// Check that the chain is valid number and link wise
   403  	if full {
   404  		prev := blockchain.CurrentBlock()
   405  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   406  			if prev.ParentHash() != block.Hash() {
   407  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   408  			}
   409  		}
   410  	} else {
   411  		prev := blockchain.CurrentHeader()
   412  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   413  			if prev.ParentHash != header.Hash() {
   414  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   415  			}
   416  		}
   417  	}
   418  	// Make sure the chain total difficulty is the correct one
   419  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), new(big.Int).Sub(big.NewInt(td), blockchain.genesisBlock.Difficulty()))
   420  	if full {
   421  		headNum = blockchain.CurrentBlock().Number()
   422  	} else {
   423  		headNum = blockchain.CurrentHeader().Number
   424  	}
   425  
   426  	if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   427  		diff := new(big.Int).Sub(want, have)
   428  		t.Errorf("total difficulty block %s mismatch: have %v, want %v, d %v", headNum, have, want, diff)
   429  	}
   430  }
   431  
   432  // Tests that the insertion functions detect banned hashes.
   433  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   434  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   435  
   436  func testBadHashes(t *testing.T, full bool) {
   437  	// Create a pristine chain and database
   438  	db, blockchain, err := newCanonical(aquahash.NewFaker(), 0, full)
   439  	if err != nil {
   440  		t.Fatalf("failed to create pristine chain: %v", err)
   441  	}
   442  	defer blockchain.Stop()
   443  
   444  	// Create a chain, ban a hash and try to import
   445  	if full {
   446  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, aquahash.NewFaker(), db, 10)
   447  
   448  		BadHashes[blocks[2].Header().Hash()] = true
   449  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   450  
   451  		_, err = blockchain.InsertChain(blocks)
   452  	} else {
   453  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, aquahash.NewFaker(), db, 10)
   454  
   455  		BadHashes[headers[2].Hash()] = true
   456  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   457  
   458  		_, err = blockchain.InsertHeaderChain(headers, 1)
   459  	}
   460  	if err != ErrBlacklistedHash {
   461  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   462  	}
   463  }
   464  
   465  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   466  // good state prior to the bad hash.
   467  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   468  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   469  
   470  func testReorgBadHashes(t *testing.T, full bool) {
   471  	// Create a pristine chain and database
   472  	db, blockchain, err := newCanonical(aquahash.NewFaker(), 0, full)
   473  	if err != nil {
   474  		t.Fatalf("failed to create pristine chain: %v", err)
   475  	}
   476  	// Create a chain, import and ban afterwards
   477  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, aquahash.NewFaker(), db, 10)
   478  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, aquahash.NewFaker(), db, 10)
   479  
   480  	if full {
   481  		if _, err = blockchain.InsertChain(blocks); err != nil {
   482  			t.Errorf("failed to import blocks: %v", err)
   483  		}
   484  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   485  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   486  		}
   487  		BadHashes[blocks[3].Header().Hash()] = true
   488  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   489  	} else {
   490  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   491  			t.Errorf("failed to import headers: %v", err)
   492  		}
   493  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   494  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   495  		}
   496  		BadHashes[headers[3].Hash()] = true
   497  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   498  	}
   499  	blockchain.Stop()
   500  
   501  	// Create a new BlockChain and check that it rolled back the state.
   502  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, aquahash.NewFaker(), vm.Config{})
   503  	if err != nil {
   504  		t.Fatalf("failed to create new chain manager: %v", err)
   505  	}
   506  	if full {
   507  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   508  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   509  		}
   510  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   511  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   512  		}
   513  	} else {
   514  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   515  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   516  		}
   517  	}
   518  	ncm.Stop()
   519  }
   520  
   521  // Tests chain insertions in the face of one entity containing an invalid nonce.
   522  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   523  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   524  
   525  func testInsertNonceError(t *testing.T, full bool) {
   526  	for i := 1; i < 25 && !t.Failed(); i++ {
   527  		// Create a pristine chain and database
   528  		db, blockchain, err := newCanonical(aquahash.NewFaker(), 0, full)
   529  		if err != nil {
   530  			t.Fatalf("failed to create pristine chain: %v", err)
   531  		}
   532  		defer blockchain.Stop()
   533  
   534  		// Create and insert a chain with a failing nonce
   535  		var (
   536  			failAt  int
   537  			failRes int
   538  			failNum uint64
   539  		)
   540  		if full {
   541  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, aquahash.NewFaker(), db, 0)
   542  
   543  			failAt = rand.Int() % len(blocks)
   544  			failNum = blocks[failAt].NumberU64()
   545  
   546  			blockchain.engine = aquahash.NewFakeFailer(failNum)
   547  			failRes, err = blockchain.InsertChain(blocks)
   548  		} else {
   549  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, aquahash.NewFaker(), db, 0)
   550  
   551  			failAt = rand.Int() % len(headers)
   552  			failNum = headers[failAt].Number.Uint64()
   553  
   554  			blockchain.engine = aquahash.NewFakeFailer(failNum)
   555  			blockchain.hc.engine = blockchain.engine
   556  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   557  		}
   558  		// Check that the returned error indicates the failure.
   559  		if failRes != failAt {
   560  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   561  		}
   562  		// Check that all no blocks after the failing block have been inserted.
   563  		for j := 0; j < i-failAt; j++ {
   564  			if full {
   565  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   566  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   567  				}
   568  			} else {
   569  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   570  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   571  				}
   572  			}
   573  		}
   574  	}
   575  }
   576  
   577  // Tests that fast importing a block chain produces the same chain data as the
   578  // classical full block processing.
   579  func TestFastVsFullChains(t *testing.T) {
   580  	// Configure and generate a sample block chain
   581  	var (
   582  		gendb   = aquadb.NewMemDatabase()
   583  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   584  		address = crypto.PubkeyToAddress(key.PublicKey)
   585  		funds   = big.NewInt(1000000000)
   586  		gspec   = &Genesis{
   587  			Config: params.TestChainConfig,
   588  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   589  		}
   590  		genesis = gspec.MustCommit(gendb)
   591  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   592  	)
   593  	blocks, receipts := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   594  		block.SetCoinbase(common.Address{0x00})
   595  
   596  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   597  		if i%3 == 2 {
   598  			for j := 0; j < i%4+1; j++ {
   599  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   600  				if err != nil {
   601  					panic(err)
   602  				}
   603  				block.AddTx(tx)
   604  			}
   605  		}
   606  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   607  		if i%5 == 5 {
   608  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   609  		}
   610  	})
   611  	// Import the chain as an archive node for the comparison baseline
   612  	archiveDb := aquadb.NewMemDatabase()
   613  	gspec.MustCommit(archiveDb)
   614  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   615  	defer archive.Stop()
   616  
   617  	if n, err := archive.InsertChain(blocks); err != nil {
   618  		t.Fatalf("failed to process block %d: %v", n, err)
   619  	}
   620  	// Fast import the chain as a non-archive node to test
   621  	fastDb := aquadb.NewMemDatabase()
   622  	gspec.MustCommit(fastDb)
   623  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   624  	defer fast.Stop()
   625  
   626  	headers := make([]*types.Header, len(blocks))
   627  	for i, block := range blocks {
   628  		headers[i] = block.Header()
   629  	}
   630  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   631  		t.Fatalf("failed to insert header %d: %v", n, err)
   632  	}
   633  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   634  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   635  	}
   636  	// Iterate over all chain data components, and cross reference
   637  	for i := 0; i < len(blocks); i++ {
   638  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   639  
   640  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   641  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   642  		}
   643  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   644  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   645  		}
   646  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   647  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   648  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   649  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   650  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   651  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   652  		}
   653  		if freceipts, areceipts := GetBlockReceipts(fastDb, hash, GetBlockNumber(fastDb, hash)), GetBlockReceipts(archiveDb, hash, GetBlockNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   654  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   655  		}
   656  	}
   657  	// Check that the canonical chains are the same between the databases
   658  	for i := 0; i < len(blocks)+1; i++ {
   659  		if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   660  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   661  		}
   662  	}
   663  }
   664  
   665  // Tests that various import methods move the chain head pointers to the correct
   666  // positions.
   667  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   668  	// Configure and generate a sample block chain
   669  	var (
   670  		gendb   = aquadb.NewMemDatabase()
   671  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   672  		address = crypto.PubkeyToAddress(key.PublicKey)
   673  		funds   = big.NewInt(1000000000)
   674  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   675  		genesis = gspec.MustCommit(gendb)
   676  	)
   677  	height := uint64(1024)
   678  	blocks, receipts := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), gendb, int(height), nil)
   679  
   680  	// Configure a subchain to roll back
   681  	remove := []common.Hash{}
   682  	for _, block := range blocks[height/2:] {
   683  		remove = append(remove, block.Hash())
   684  	}
   685  	// Create a small assertion method to check the three heads
   686  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   687  		if num := chain.CurrentBlock().NumberU64(); num != block {
   688  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   689  		}
   690  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   691  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   692  		}
   693  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   694  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   695  		}
   696  	}
   697  	// Import the chain as an archive node and ensure all pointers are updated
   698  	archiveDb := aquadb.NewMemDatabase()
   699  	gspec.MustCommit(archiveDb)
   700  
   701  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   702  	if n, err := archive.InsertChain(blocks); err != nil {
   703  		t.Fatalf("failed to process block %d: %v", n, err)
   704  	}
   705  	defer archive.Stop()
   706  
   707  	assert(t, "archive", archive, height, height, height)
   708  	archive.Rollback(remove)
   709  	assert(t, "archive", archive, height/2, height/2, height/2)
   710  
   711  	// Import the chain as a non-archive node and ensure all pointers are updated
   712  	fastDb := aquadb.NewMemDatabase()
   713  	gspec.MustCommit(fastDb)
   714  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   715  	defer fast.Stop()
   716  
   717  	headers := make([]*types.Header, len(blocks))
   718  	for i, block := range blocks {
   719  		headers[i] = block.Header()
   720  	}
   721  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   722  		t.Fatalf("failed to insert header %d: %v", n, err)
   723  	}
   724  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   725  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   726  	}
   727  	assert(t, "fast", fast, height, height, 0)
   728  	fast.Rollback(remove)
   729  	assert(t, "fast", fast, height/2, height/2, 0)
   730  
   731  	// Import the chain as a light node and ensure all pointers are updated
   732  	lightDb := aquadb.NewMemDatabase()
   733  	gspec.MustCommit(lightDb)
   734  
   735  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   736  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   737  		t.Fatalf("failed to insert header %d: %v", n, err)
   738  	}
   739  	defer light.Stop()
   740  
   741  	assert(t, "light", light, height, 0, 0)
   742  	light.Rollback(remove)
   743  	assert(t, "light", light, height/2, 0, 0)
   744  }
   745  
   746  // Tests that chain reorganisations handle transaction removals and reinsertions.
   747  func TestChainTxReorgs(t *testing.T) {
   748  	var (
   749  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   750  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   751  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   752  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   753  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   754  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   755  		db      = aquadb.NewMemDatabase()
   756  		gspec   = &Genesis{
   757  			Config:   params.TestChainConfig,
   758  			GasLimit: 3141592,
   759  			Alloc: GenesisAlloc{
   760  				addr1: {Balance: big.NewInt(1000000)},
   761  				addr2: {Balance: big.NewInt(1000000)},
   762  				addr3: {Balance: big.NewInt(1000000)},
   763  			},
   764  		}
   765  		genesis = gspec.MustCommit(db)
   766  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   767  	)
   768  
   769  	// Create two transactions shared between the chains:
   770  	//  - postponed: transaction included at a later block in the forked chain
   771  	//  - swapped: transaction included at the same block number in the forked chain
   772  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   773  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   774  
   775  	// Create two transactions that will be dropped by the forked chain:
   776  	//  - pastDrop: transaction dropped retroactively from a past block
   777  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
   778  	var pastDrop, freshDrop *types.Transaction
   779  
   780  	// Create three transactions that will be added in the forked chain:
   781  	//  - pastAdd:   transaction added before the reorganization is detected
   782  	//  - freshAdd:  transaction added at the exact block the reorg is detected
   783  	//  - futureAdd: transaction added after the reorg has already finished
   784  	var pastAdd, freshAdd, futureAdd *types.Transaction
   785  
   786  	chain, _ := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   787  		switch i {
   788  		case 0:
   789  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   790  
   791  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
   792  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
   793  
   794  		case 2:
   795  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   796  
   797  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
   798  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
   799  
   800  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
   801  		}
   802  	})
   803  	// Import the chain. This runs all block validation rules.
   804  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   805  	if i, err := blockchain.InsertChain(chain); err != nil {
   806  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   807  	}
   808  	defer blockchain.Stop()
   809  
   810  	// overwrite the old chain
   811  	chain, _ = GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   812  		switch i {
   813  		case 0:
   814  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   815  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
   816  
   817  		case 2:
   818  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
   819  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
   820  
   821  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   822  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
   823  
   824  		case 3:
   825  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   826  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
   827  		}
   828  	})
   829  	if _, err := blockchain.InsertChain(chain); err != nil {
   830  		t.Fatalf("failed to insert forked chain: %v", err)
   831  	}
   832  
   833  	// removed tx
   834  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   835  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
   836  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   837  		}
   838  		if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt != nil {
   839  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   840  		}
   841  	}
   842  	// added tx
   843  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   844  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
   845  			t.Errorf("add %d: expected tx to be found", i)
   846  		}
   847  		if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil {
   848  			t.Errorf("add %d: expected receipt to be found", i)
   849  		}
   850  	}
   851  	// shared tx
   852  	for i, tx := range (types.Transactions{postponed, swapped}) {
   853  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
   854  			t.Errorf("share %d: expected tx to be found", i)
   855  		}
   856  		if rcpt, _, _, _ := GetReceipt(db, tx.Hash()); rcpt == nil {
   857  			t.Errorf("share %d: expected receipt to be found", i)
   858  		}
   859  	}
   860  }
   861  
   862  func TestLogReorgs(t *testing.T) {
   863  
   864  	var (
   865  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   866  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   867  		db      = aquadb.NewMemDatabase()
   868  		// this code generates a log
   869  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   870  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   871  		genesis = gspec.MustCommit(db)
   872  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   873  	)
   874  
   875  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   876  	defer blockchain.Stop()
   877  
   878  	rmLogsCh := make(chan RemovedLogsEvent)
   879  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   880  	chain, _ := GenerateChain(params.TestChainConfig, genesis, aquahash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   881  		if i == 1 {
   882  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   883  			if err != nil {
   884  				t.Fatalf("failed to create tx: %v", err)
   885  			}
   886  			gen.AddTx(tx)
   887  		}
   888  	})
   889  	if _, err := blockchain.InsertChain(chain); err != nil {
   890  		t.Fatalf("failed to insert chain: %v", err)
   891  	}
   892  
   893  	chain, _ = GenerateChain(params.TestChainConfig, genesis, aquahash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   894  	if _, err := blockchain.InsertChain(chain); err != nil {
   895  		t.Fatalf("failed to insert forked chain: %v", err)
   896  	}
   897  
   898  	timeout := time.NewTimer(1 * time.Second)
   899  	select {
   900  	case ev := <-rmLogsCh:
   901  		if len(ev.Logs) == 0 {
   902  			t.Error("expected logs")
   903  		}
   904  	case <-timeout.C:
   905  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   906  	}
   907  }
   908  
   909  func TestReorgSideEvent(t *testing.T) {
   910  	var (
   911  		db      = aquadb.NewMemDatabase()
   912  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   913  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   914  		gspec   = &Genesis{
   915  			Config: params.TestChainConfig,
   916  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
   917  		}
   918  		genesis = gspec.MustCommit(db)
   919  		signer  = types.NewEIP155Signer(gspec.Config.ChainId)
   920  	)
   921  
   922  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
   923  	defer blockchain.Stop()
   924  
   925  	chain, _ := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   926  	if _, err := blockchain.InsertChain(chain); err != nil {
   927  		t.Fatalf("failed to insert chain: %v", err)
   928  	}
   929  
   930  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
   931  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
   932  		if i == 2 {
   933  			gen.OffsetTime(-9)
   934  		}
   935  		if err != nil {
   936  			t.Fatalf("failed to create tx: %v", err)
   937  		}
   938  		gen.AddTx(tx)
   939  		gen.header.Version = gen.config.GetBlockVersion(gen.Number())
   940  	})
   941  	chainSideCh := make(chan ChainSideEvent, 64)
   942  	blockchain.SubscribeChainSideEvent(chainSideCh)
   943  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   944  		t.Fatalf("failed to insert chain: %v", err)
   945  	}
   946  
   947  	// first two block of the secondary chain are for a brief moment considered
   948  	// side chains because up to that point the first one is considered the
   949  	// heavier chain.
   950  	expectedSideHashes := map[common.Hash]bool{
   951  		replacementBlocks[0].Hash(): true,
   952  		replacementBlocks[1].Hash(): true,
   953  		chain[0].Hash():             true,
   954  		chain[1].Hash():             true,
   955  		chain[2].Hash():             true,
   956  	}
   957  
   958  	i := 0
   959  
   960  	const timeoutDura = 10 * time.Second
   961  	timeout := time.NewTimer(timeoutDura)
   962  done:
   963  	for {
   964  		select {
   965  		case ev := <-chainSideCh:
   966  			block := ev.Block
   967  			if block.Version() != blockchain.GetBlockVersion(block.Number()) {
   968  				t.Logf("%d: didn't expect %x to have version %x", i, block.Number(), block.Version())
   969  				continue
   970  			}
   971  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   972  				t.Logf("%d: didn't expect %x to be in side chain: %x", i, block.Number(), block.Hash())
   973  				continue
   974  			}
   975  			i++
   976  
   977  			if i == len(expectedSideHashes) {
   978  				timeout.Stop()
   979  
   980  				break done
   981  			}
   982  			timeout.Reset(timeoutDura)
   983  
   984  		case <-timeout.C:
   985  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
   986  		}
   987  	}
   988  
   989  	// make sure no more events are fired
   990  	select {
   991  	case e := <-chainSideCh:
   992  		t.Errorf("unexpected event fired: %v", e)
   993  	case <-time.After(350 * time.Millisecond):
   994  	}
   995  
   996  }
   997  
   998  // Tests if the canonical block can be fetched from the database during chain insertion.
   999  func TestCanonicalBlockRetrieval(t *testing.T) {
  1000  	_, blockchain, err := newCanonical(aquahash.NewFaker(), 0, true)
  1001  	if err != nil {
  1002  		t.Fatalf("failed to create pristine chain: %v", err)
  1003  	}
  1004  	defer blockchain.Stop()
  1005  
  1006  	numBlocks := 15 // shortl after hf5 pow switch
  1007  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, aquahash.NewFaker(), blockchain.db, numBlocks, func(i int, gen *BlockGen) {})
  1008  
  1009  	// var pend sync.WaitGroup
  1010  	// pend.Add(len(chain))
  1011  
  1012  	t.Logf("iterating %d blocks", len(chain))
  1013  	for i, block := range chain {
  1014  		// go func(t *testing.T, block *types.Block) {
  1015  		// defer pend.Done()
  1016  
  1017  		// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1018  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1019  			t.Fatalf("failed to insert block %d: %v", i, err)
  1020  		}
  1021  		ch := GetCanonicalHash(blockchain.db, block.NumberU64())
  1022  		if ch == (common.Hash{}) {
  1023  			t.Fatalf("no canonical hash for block %d", i)
  1024  		}
  1025  
  1026  		if ch != block.Hash() {
  1027  			t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1028  		}
  1029  		fb := GetBlockNoVersion(blockchain.db, ch, block.NumberU64())
  1030  		if fb == nil {
  1031  			t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1032  		}
  1033  		var parent *types.Block
  1034  		if i != 0 {
  1035  			parent = GetBlockNoVersion(blockchain.db, fb.ParentHash(), block.NumberU64()-1)
  1036  			if fb == nil {
  1037  				t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1038  			}
  1039  			parent.SetVersion(blockchain.Config().GetBlockVersion(parent.Number()))
  1040  			if parent.Hash().Hex() != fb.ParentHash().Hex() {
  1041  				t.Fatalf("parent hash != canonical parent hash")
  1042  			}
  1043  		}
  1044  
  1045  		if fb.SetVersion(blockchain.Config().GetBlockVersion(fb.Number())) != block.Hash() {
  1046  			t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1047  		}
  1048  
  1049  		t.Logf("block %d: hash=%s version=%d", i, ch.Hex()[:10], fb.Version())
  1050  		if i != 0 {
  1051  			t.Logf(" >parentblock %d: hash=%s version=%d", i-1, parent.Hash().Hex()[:10], parent.Version())
  1052  
  1053  		}
  1054  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1055  			t.Fatalf("failed to insert block %d: %v", i, err)
  1056  		}
  1057  
  1058  		// }(t, chain[i])
  1059  
  1060  	}
  1061  	// pend.Wait()
  1062  }
  1063  
  1064  func TestEIP155Transition(t *testing.T) {
  1065  	// Configure and generate a sample block chain
  1066  	var (
  1067  		db         = aquadb.NewMemDatabase()
  1068  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1069  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1070  		funds      = big.NewInt(1000000000)
  1071  		deleteAddr = common.Address{1}
  1072  		gspec      = &Genesis{
  1073  			Config: &params.ChainConfig{ChainId: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1074  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1075  		}
  1076  		genesis = gspec.MustCommit(db)
  1077  	)
  1078  
  1079  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
  1080  	defer blockchain.Stop()
  1081  
  1082  	blocks, _ := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1083  		var (
  1084  			tx      *types.Transaction
  1085  			err     error
  1086  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1087  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1088  			}
  1089  		)
  1090  		switch i {
  1091  		case 0:
  1092  			tx, err = basicTx(types.HomesteadSigner{})
  1093  			if err != nil {
  1094  				t.Fatal(err)
  1095  			}
  1096  			block.AddTx(tx)
  1097  		case 2:
  1098  			tx, err = basicTx(types.HomesteadSigner{})
  1099  			if err != nil {
  1100  				t.Fatal(err)
  1101  			}
  1102  			block.AddTx(tx)
  1103  
  1104  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1105  			if err != nil {
  1106  				t.Fatal(err)
  1107  			}
  1108  			block.AddTx(tx)
  1109  		case 3:
  1110  			tx, err = basicTx(types.HomesteadSigner{})
  1111  			if err != nil {
  1112  				t.Fatal(err)
  1113  			}
  1114  			block.AddTx(tx)
  1115  
  1116  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainId))
  1117  			if err != nil {
  1118  				t.Fatal(err)
  1119  			}
  1120  			block.AddTx(tx)
  1121  		}
  1122  	})
  1123  
  1124  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1125  		t.Fatal(err)
  1126  	}
  1127  	block := blockchain.GetBlockByNumber(1)
  1128  	if block.Transactions()[0].Protected() {
  1129  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1130  	}
  1131  
  1132  	block = blockchain.GetBlockByNumber(3)
  1133  	if block.Transactions()[0].Protected() {
  1134  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1135  	}
  1136  	if !block.Transactions()[1].Protected() {
  1137  		t.Error("Expected block[3].txs[1] to be replay protected")
  1138  	}
  1139  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1140  		if len(blocks[4:]) != 0 {
  1141  			t.Fatal(err)
  1142  		}
  1143  	}
  1144  
  1145  	// generate an invalid chain id transaction
  1146  	config := &params.ChainConfig{ChainId: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1147  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], aquahash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1148  		var (
  1149  			tx      *types.Transaction
  1150  			err     error
  1151  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1152  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1153  			}
  1154  		)
  1155  		switch i {
  1156  		case 0:
  1157  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1158  			if err != nil {
  1159  				t.Fatal(err)
  1160  			}
  1161  			block.AddTx(tx)
  1162  		}
  1163  	})
  1164  	_, err := blockchain.InsertChain(blocks)
  1165  	if err != types.ErrInvalidChainId {
  1166  		t.Error("expected error:", types.ErrInvalidChainId)
  1167  	}
  1168  }
  1169  
  1170  func TestEIP161AccountRemoval(t *testing.T) {
  1171  	// Configure and generate a sample block chain
  1172  	var (
  1173  		db      = aquadb.NewMemDatabase()
  1174  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1175  		address = crypto.PubkeyToAddress(key.PublicKey)
  1176  		funds   = big.NewInt(1000000000)
  1177  		theAddr = common.Address{1}
  1178  		gspec   = &Genesis{
  1179  			Config: &params.ChainConfig{
  1180  				ChainId:        big.NewInt(1),
  1181  				HomesteadBlock: new(big.Int),
  1182  				EIP155Block:    new(big.Int),
  1183  				EIP158Block:    big.NewInt(2),
  1184  			},
  1185  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1186  		}
  1187  		genesis = gspec.MustCommit(db)
  1188  	)
  1189  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, aquahash.NewFaker(), vm.Config{})
  1190  	defer blockchain.Stop()
  1191  
  1192  	blocks, _ := GenerateChain(gspec.Config, genesis, aquahash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1193  		var (
  1194  			tx     *types.Transaction
  1195  			err    error
  1196  			signer = types.NewEIP155Signer(gspec.Config.ChainId)
  1197  		)
  1198  		switch i {
  1199  		case 0:
  1200  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1201  		case 1:
  1202  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1203  		case 2:
  1204  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1205  		}
  1206  		if err != nil {
  1207  			t.Fatal(err)
  1208  		}
  1209  		block.AddTx(tx)
  1210  	})
  1211  	// account must exist pre eip 161
  1212  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1213  		t.Fatal(err)
  1214  	}
  1215  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1216  		t.Error("expected account to exist")
  1217  	}
  1218  
  1219  	// account needs to be deleted post eip 161
  1220  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1221  		t.Fatal(err)
  1222  	}
  1223  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1224  		t.Error("account should not exist")
  1225  	}
  1226  
  1227  	// account musn't be created post eip 161
  1228  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1229  		t.Fatal(err)
  1230  	}
  1231  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1232  		t.Error("account should not exist")
  1233  	}
  1234  }
  1235  
  1236  // This is a regression test (i.e. as weird as it is, don't delete it ever), which
  1237  // tests that under weird reorg conditions the blockchain and its internal header-
  1238  // chain return the same latest block/header.
  1239  //
  1240  // https://gitlab.com/aquachain/aquachain/pull/15941
  1241  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1242  	// Generate a canonical chain to act as the main dataset
  1243  	engine := aquahash.NewFaker()
  1244  
  1245  	db := aquadb.NewMemDatabase()
  1246  	genesis := new(Genesis).MustCommit(db)
  1247  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1248  
  1249  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1250  	forks := make([]*types.Block, len(blocks))
  1251  	for i := 0; i < len(forks); i++ {
  1252  		parent := genesis
  1253  		if i > 0 {
  1254  			parent = blocks[i-1]
  1255  		}
  1256  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1257  		forks[i] = fork[0]
  1258  	}
  1259  	// Import the canonical and fork chain side by side, verifying the current block
  1260  	// and current header consistency
  1261  	diskdb := aquadb.NewMemDatabase()
  1262  	new(Genesis).MustCommit(diskdb)
  1263  
  1264  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1265  	if err != nil {
  1266  		t.Fatalf("failed to create tester chain: %v", err)
  1267  	}
  1268  	for i := 0; i < len(blocks); i++ {
  1269  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1270  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1271  		}
  1272  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1273  			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])
  1274  		}
  1275  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1276  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1277  		}
  1278  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1279  			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])
  1280  		}
  1281  	}
  1282  }
  1283  
  1284  // Tests that importing small side forks doesn't leave junk in the trie database
  1285  // cache (which would eventually cause memory issues).
  1286  func TestTrieForkGC(t *testing.T) {
  1287  	// Generate a canonical chain to act as the main dataset
  1288  	engine := aquahash.NewFaker()
  1289  
  1290  	db := aquadb.NewMemDatabase()
  1291  	genesis := new(Genesis).MustCommit(db)
  1292  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1293  
  1294  	// Generate a bunch of fork blocks, each side forking from the canonical chain
  1295  	forks := make([]*types.Block, len(blocks))
  1296  	for i := 0; i < len(forks); i++ {
  1297  		parent := genesis
  1298  		if i > 0 {
  1299  			parent = blocks[i-1]
  1300  		}
  1301  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1302  		forks[i] = fork[0]
  1303  	}
  1304  	// Import the canonical and fork chain side by side, forcing the trie cache to cache both
  1305  	diskdb := aquadb.NewMemDatabase()
  1306  	new(Genesis).MustCommit(diskdb)
  1307  
  1308  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1309  	if err != nil {
  1310  		t.Fatalf("failed to create tester chain: %v", err)
  1311  	}
  1312  	for i := 0; i < len(blocks); i++ {
  1313  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1314  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1315  		}
  1316  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1317  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1318  		}
  1319  	}
  1320  	// Dereference all the recent tries and ensure no past trie is left in
  1321  	for i := 0; i < triesInMemory; i++ {
  1322  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root(), common.Hash{})
  1323  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root(), common.Hash{})
  1324  	}
  1325  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1326  		t.Fatalf("stale tries still alive after garbase collection")
  1327  	}
  1328  }
  1329  
  1330  // Tests that doing large reorgs works even if the state associated with the
  1331  // forking point is not available any more.
  1332  func TestLargeReorgTrieGC(t *testing.T) {
  1333  	// Generate the original common chain segment and the two competing forks
  1334  	engine := aquahash.NewFaker()
  1335  
  1336  	db := aquadb.NewMemDatabase()
  1337  	genesis := new(Genesis).MustCommit(db)
  1338  
  1339  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1340  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1341  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1342  
  1343  	// Import the shared chain and the original canonical one
  1344  	diskdb := aquadb.NewMemDatabase()
  1345  	new(Genesis).MustCommit(diskdb)
  1346  
  1347  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{})
  1348  	if err != nil {
  1349  		t.Fatalf("failed to create tester chain: %v", err)
  1350  	}
  1351  	if _, err := chain.InsertChain(shared); err != nil {
  1352  		t.Fatalf("failed to insert shared chain: %v", err)
  1353  	}
  1354  	if _, err := chain.InsertChain(original); err != nil {
  1355  		t.Fatalf("failed to insert shared chain: %v", err)
  1356  	}
  1357  	// Ensure that the state associated with the forking point is pruned away
  1358  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1359  		t.Fatalf("common-but-old ancestor still cache")
  1360  	}
  1361  	// Import the competitor chain without exceeding the canonical's TD and ensure
  1362  	// we have not processed any of the blocks (protection against malicious blocks)
  1363  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1364  		t.Fatalf("failed to insert competitor chain: %v", err)
  1365  	}
  1366  	for i, block := range competitor[:len(competitor)-2] {
  1367  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1368  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1369  		}
  1370  	}
  1371  	// Import the head of the competitor chain, triggering the reorg and ensure we
  1372  	// successfully reprocess all the stashed away blocks.
  1373  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1374  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1375  	}
  1376  	for i, block := range competitor[:len(competitor)-triesInMemory] {
  1377  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1378  			t.Fatalf("competitor %d: competing chain state missing", i)
  1379  		}
  1380  	}
  1381  }