github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/core/blockchain_test.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  	"math/rand"
    23  	"os"
    24  	"path/filepath"
    25  	"strconv"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/ethereumproject/ethash"
    30  	"github.com/ethereumproject/go-ethereum/common"
    31  	"github.com/ethereumproject/go-ethereum/core/state"
    32  	"github.com/ethereumproject/go-ethereum/core/types"
    33  	"github.com/ethereumproject/go-ethereum/core/vm"
    34  	"github.com/ethereumproject/go-ethereum/crypto"
    35  	"github.com/ethereumproject/go-ethereum/ethdb"
    36  	"github.com/ethereumproject/go-ethereum/event"
    37  	"github.com/ethereumproject/go-ethereum/logger/glog"
    38  	"github.com/ethereumproject/go-ethereum/rlp"
    39  	"github.com/hashicorp/golang-lru"
    40  	"io/ioutil"
    41  	"strings"
    42  )
    43  
    44  func init() {
    45  	// Disable any display logs for tests.
    46  	glog.SetD(0)
    47  }
    48  
    49  // GenesisBlockForTesting creates a block in which addr has the given wei balance.
    50  // The state trie of the block is written to db. the passed db needs to contain a state root
    51  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
    52  	statedb, err := state.New(common.Hash{}, state.NewDatabase(db))
    53  	if err != nil {
    54  		panic(err)
    55  	}
    56  
    57  	obj := statedb.GetOrNewStateObject(addr)
    58  	obj.SetBalance(balance)
    59  	root, err := statedb.CommitTo(db, false)
    60  	if err != nil {
    61  		panic(fmt.Sprintf("cannot write state: %v", err))
    62  	}
    63  
    64  	return types.NewBlock(&types.Header{
    65  		Difficulty: big.NewInt(131072),
    66  		GasLimit:   big.NewInt(4712388),
    67  		Root:       root,
    68  	}, nil, nil, nil)
    69  }
    70  
    71  func theBlockChain(db ethdb.Database, t *testing.T) *BlockChain {
    72  	pow, err := ethash.NewForTesting()
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  
    77  	var eventMux event.TypeMux
    78  	if _, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis); err != nil {
    79  		t.Fatal(err)
    80  	}
    81  	blockchain, err := NewBlockChain(db, testChainConfig(), pow, &eventMux)
    82  	if err != nil {
    83  		t.Error("failed creating blockchain:", err)
    84  		t.FailNow()
    85  		return nil
    86  	}
    87  
    88  	return blockchain
    89  }
    90  
    91  // Test fork of length N starting from block i
    92  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    93  	// Copy old chain up to #i into a new db
    94  	db, blockchain2, err := newCanonical(testChainConfig(), i, full)
    95  	if err != nil {
    96  		t.Fatal("could not make new canonical in testFork", err)
    97  	}
    98  	// Assert the chains have the same header/block at #i
    99  	var hash1, hash2 common.Hash
   100  	if full {
   101  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
   102  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
   103  	} else {
   104  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
   105  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
   106  	}
   107  	if hash1 != hash2 {
   108  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
   109  	}
   110  	// Extend the newly created chain
   111  	var (
   112  		blockChainB  []*types.Block
   113  		headerChainB []*types.Header
   114  	)
   115  	if full {
   116  		blockChainB = makeBlockChain(blockchain2.config, blockchain2.CurrentBlock(), n, db, forkSeed)
   117  		if res := blockchain2.InsertChain(blockChainB); res.Error != nil {
   118  			t.Fatalf("failed to insert forking chain: %v", res.Error)
   119  		}
   120  	} else {
   121  		headerChainB = makeHeaderChain(blockchain2.config, blockchain2.CurrentHeader(), n, db, forkSeed)
   122  		if res := blockchain2.InsertHeaderChain(headerChainB, 1); res.Error != nil {
   123  			t.Fatalf("failed to insert forking chain: %v", res.Error)
   124  		}
   125  	}
   126  	// Sanity check that the forked chain can be imported into the original
   127  	var tdPre, tdPost *big.Int
   128  
   129  	if full {
   130  		tdPre = blockchain.GetTd(blockchain.CurrentBlock().Hash())
   131  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   132  			t.Fatalf("failed to import forked block chain: %v", err)
   133  		}
   134  		tdPost = blockchain.GetTd(blockChainB[len(blockChainB)-1].Hash())
   135  	} else {
   136  		tdPre = blockchain.GetTd(blockchain.CurrentHeader().Hash())
   137  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   138  			t.Fatalf("failed to import forked header chain: %v", err)
   139  		}
   140  		tdPost = blockchain.GetTd(headerChainB[len(headerChainB)-1].Hash())
   141  	}
   142  	// Compare the total difficulties of the chains
   143  	comparator(tdPre, tdPost)
   144  }
   145  
   146  // testBlockChainImport tries to process a chain of blocks, writing them into
   147  // the database if successful.
   148  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   149  	for _, block := range chain {
   150  		// Try and process the block
   151  		err := blockchain.Validator().ValidateBlock(block)
   152  		if err != nil {
   153  			if IsKnownBlockErr(err) {
   154  				continue
   155  			}
   156  			return err
   157  		}
   158  		statedb, err := state.New(blockchain.GetBlock(block.ParentHash()).Root(), state.NewDatabase(blockchain.chainDb))
   159  		if err != nil {
   160  			return err
   161  		}
   162  		receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb)
   163  		if err != nil {
   164  			return err
   165  		}
   166  		err = blockchain.Validator().ValidateState(block, blockchain.GetBlock(block.ParentHash()), statedb, receipts, usedGas)
   167  		if err != nil {
   168  			return err
   169  		}
   170  		blockchain.mu.Lock()
   171  		WriteTd(blockchain.chainDb, block.Hash(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash())))
   172  		WriteBlock(blockchain.chainDb, block)
   173  		statedb.CommitTo(blockchain.chainDb, false)
   174  		blockchain.mu.Unlock()
   175  	}
   176  	return nil
   177  }
   178  
   179  // testHeaderChainImport tries to process a chain of header, writing them into
   180  // the database if successful.
   181  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   182  	for _, header := range chain {
   183  		// Try and validate the header
   184  		if err := blockchain.Validator().ValidateHeader(header, blockchain.GetHeader(header.ParentHash), false); err != nil {
   185  			return err
   186  		}
   187  		// Manually insert the header into the database, but don't reorganise (allows subsequent testing)
   188  		blockchain.mu.Lock()
   189  		WriteTd(blockchain.chainDb, header.Hash(), new(big.Int).Add(header.Difficulty, blockchain.GetTd(header.ParentHash)))
   190  		WriteHeader(blockchain.chainDb, header)
   191  		blockchain.mu.Unlock()
   192  	}
   193  	return nil
   194  }
   195  
   196  func loadChain(fn string, t *testing.T) (types.Blocks, error) {
   197  	fh, err := os.OpenFile(filepath.Join("testdata", fn), os.O_RDONLY, os.ModePerm)
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  	defer fh.Close()
   202  
   203  	var chain types.Blocks
   204  	if err := rlp.Decode(fh, &chain); err != nil {
   205  		return nil, err
   206  	}
   207  
   208  	return chain, nil
   209  }
   210  
   211  func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) {
   212  	res := blockchain.InsertChain(chain)
   213  	if res.Error != nil {
   214  		t.Fatal(res.Error)
   215  	}
   216  	done <- true
   217  }
   218  
   219  func TestLastBlock(t *testing.T) {
   220  	db, err := ethdb.NewMemDatabase()
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  
   225  	bchain := theBlockChain(db, t)
   226  	block := makeBlockChain(bchain.config, bchain.CurrentBlock(), 1, db, 0)[0]
   227  	bchain.insert(block)
   228  	if block.Hash() != GetHeadBlockHash(db) {
   229  		t.Errorf("Write/Get HeadBlockHash failed")
   230  	}
   231  }
   232  
   233  // Tests that given a starting canonical chain of a given size, it can be extended
   234  // with various length chains.
   235  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   236  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   237  
   238  func testExtendCanonical(t *testing.T, full bool) {
   239  	length := 5
   240  
   241  	// Make first chain starting from genesis
   242  	_, processor, err := newCanonical(testChainConfig(), length, full)
   243  	if err != nil {
   244  		t.Fatalf("failed to make new canonical chain: %v", err)
   245  	}
   246  	// Define the difficulty comparator
   247  	better := func(td1, td2 *big.Int) {
   248  		if td2.Cmp(td1) <= 0 {
   249  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   250  		}
   251  	}
   252  	// Start fork from current height
   253  	testFork(t, processor, length, 1, full, better)
   254  	testFork(t, processor, length, 2, full, better)
   255  	testFork(t, processor, length, 5, full, better)
   256  	testFork(t, processor, length, 10, full, better)
   257  }
   258  
   259  // Tests that given a starting canonical chain of a given size, creating shorter
   260  // forks do not take canonical ownership.
   261  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   262  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   263  
   264  func testShorterFork(t *testing.T, full bool) {
   265  	length := 10
   266  
   267  	// Make first chain starting from genesis
   268  	_, processor, err := newCanonical(testChainConfig(), length, full)
   269  	if err != nil {
   270  		t.Fatalf("failed to make new canonical chain: %v", err)
   271  	}
   272  	// Define the difficulty comparator
   273  	worse := func(td1, td2 *big.Int) {
   274  		if td2.Cmp(td1) >= 0 {
   275  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   276  		}
   277  	}
   278  	// Sum of numbers must be less than `length` for this to be a shorter fork
   279  	testFork(t, processor, 0, 3, full, worse)
   280  	testFork(t, processor, 0, 7, full, worse)
   281  	testFork(t, processor, 1, 1, full, worse)
   282  	testFork(t, processor, 1, 7, full, worse)
   283  	testFork(t, processor, 5, 3, full, worse)
   284  	testFork(t, processor, 5, 4, full, worse)
   285  }
   286  
   287  // Tests that given a starting canonical chain of a given size, creating longer
   288  // forks do take canonical ownership.
   289  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   290  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   291  
   292  func testLongerFork(t *testing.T, full bool) {
   293  	length := 10
   294  
   295  	// Make first chain starting from genesis
   296  	_, processor, err := newCanonical(testChainConfig(), length, full)
   297  	if err != nil {
   298  		t.Fatalf("failed to make new canonical chain: %v", err)
   299  	}
   300  	// Define the difficulty comparator
   301  	better := func(td1, td2 *big.Int) {
   302  		if td2.Cmp(td1) <= 0 {
   303  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   304  		}
   305  	}
   306  	// Sum of numbers must be greater than `length` for this to be a longer fork
   307  	testFork(t, processor, 0, 11, full, better)
   308  	testFork(t, processor, 0, 15, full, better)
   309  	testFork(t, processor, 1, 10, full, better)
   310  	testFork(t, processor, 1, 12, full, better)
   311  	testFork(t, processor, 5, 6, full, better)
   312  	testFork(t, processor, 5, 8, full, better)
   313  }
   314  
   315  // Tests that given a starting canonical chain of a given size, creating equal
   316  // forks do take canonical ownership.
   317  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   318  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   319  
   320  func testEqualFork(t *testing.T, full bool) {
   321  	length := 10
   322  
   323  	// Make first chain starting from genesis
   324  	_, processor, err := newCanonical(testChainConfig(), length, full)
   325  	if err != nil {
   326  		t.Fatalf("failed to make new canonical chain: %v", err)
   327  	}
   328  	// Define the difficulty comparator
   329  	equal := func(td1, td2 *big.Int) {
   330  		if td2.Cmp(td1) != 0 {
   331  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   332  		}
   333  	}
   334  	// Sum of numbers must be equal to `length` for this to be an equal fork
   335  	testFork(t, processor, 0, 10, full, equal)
   336  	testFork(t, processor, 1, 9, full, equal)
   337  	testFork(t, processor, 2, 8, full, equal)
   338  	testFork(t, processor, 5, 5, full, equal)
   339  	testFork(t, processor, 6, 4, full, equal)
   340  	testFork(t, processor, 9, 1, full, equal)
   341  }
   342  
   343  // Tests that chains missing links do not get accepted by the processor.
   344  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   345  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   346  
   347  func testBrokenChain(t *testing.T, full bool) {
   348  	// Make chain starting from genesis
   349  	db, blockchain, err := newCanonical(testChainConfig(), 10, full)
   350  	if err != nil {
   351  		t.Fatalf("failed to make new canonical chain: %v", err)
   352  	}
   353  	// Create a forked chain, and try to insert with a missing link
   354  	if full {
   355  		chain := makeBlockChain(blockchain.config, blockchain.CurrentBlock(), 5, db, forkSeed)[1:]
   356  		if err := testBlockChainImport(chain, blockchain); err == nil {
   357  			t.Errorf("broken block chain not reported")
   358  		}
   359  	} else {
   360  		chain := makeHeaderChain(blockchain.config, blockchain.CurrentHeader(), 5, db, forkSeed)[1:]
   361  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   362  			t.Errorf("broken header chain not reported")
   363  		}
   364  	}
   365  }
   366  
   367  func TestChainInsertions(t *testing.T) {
   368  	t.Skip("Skipped: outdated test files")
   369  
   370  	db, err := ethdb.NewMemDatabase()
   371  	if err != nil {
   372  		t.Fatal(err)
   373  	}
   374  
   375  	chain1, err := loadChain("valid1", t)
   376  	if err != nil {
   377  		t.Fatal(err)
   378  	}
   379  
   380  	chain2, err := loadChain("valid2", t)
   381  	if err != nil {
   382  		t.Fatal(err)
   383  	}
   384  
   385  	blockchain := theBlockChain(db, t)
   386  
   387  	const max = 2
   388  	done := make(chan bool, max)
   389  
   390  	go insertChain(done, blockchain, chain1, t)
   391  	go insertChain(done, blockchain, chain2, t)
   392  
   393  	for i := 0; i < max; i++ {
   394  		<-done
   395  	}
   396  
   397  	if chain2[len(chain2)-1].Hash() != blockchain.CurrentBlock().Hash() {
   398  		t.Error("chain2 is canonical and shouldn't be")
   399  	}
   400  
   401  	if chain1[len(chain1)-1].Hash() != blockchain.CurrentBlock().Hash() {
   402  		t.Error("chain1 isn't canonical and should be")
   403  	}
   404  }
   405  
   406  func TestChainMultipleInsertions(t *testing.T) {
   407  	t.Skip("Skipped: outdated test files")
   408  
   409  	db, err := ethdb.NewMemDatabase()
   410  	if err != nil {
   411  		t.Fatal(err)
   412  	}
   413  
   414  	const max = 4
   415  	chains := make([]types.Blocks, max)
   416  	var longest int
   417  	for i := 0; i < max; i++ {
   418  		var err error
   419  		name := "valid" + strconv.Itoa(i+1)
   420  		chains[i], err = loadChain(name, t)
   421  		if len(chains[i]) >= len(chains[longest]) {
   422  			longest = i
   423  		}
   424  		t.Log("loaded ", name, " with a length of ", len(chains[i]))
   425  		if err != nil {
   426  			t.Fatal(err)
   427  		}
   428  	}
   429  
   430  	blockchain := theBlockChain(db, t)
   431  
   432  	done := make(chan bool, max)
   433  	for i, chain := range chains {
   434  		// XXX the go routine would otherwise reference the same (chain[3]) variable and fail
   435  		i := i
   436  		chain := chain
   437  		go func() {
   438  			insertChain(done, blockchain, chain, t)
   439  			t.Log(i, "done")
   440  		}()
   441  	}
   442  
   443  	for i := 0; i < max; i++ {
   444  		<-done
   445  	}
   446  
   447  	if chains[longest][len(chains[longest])-1].Hash() != blockchain.CurrentBlock().Hash() {
   448  		t.Error("Invalid canonical chain")
   449  	}
   450  }
   451  
   452  type bproc struct{}
   453  
   454  func (bproc) ValidateBlock(*types.Block) error                        { return nil }
   455  func (bproc) ValidateHeader(*types.Header, *types.Header, bool) error { return nil }
   456  func (bproc) ValidateState(block, parent *types.Block, state *state.StateDB, receipts types.Receipts, usedGas *big.Int) error {
   457  	return nil
   458  }
   459  func (bproc) VerifyUncles(block, parent *types.Block) error { return nil }
   460  func (bproc) Process(block *types.Block, statedb *state.StateDB) (types.Receipts, vm.Logs, *big.Int, error) {
   461  	return nil, nil, nil, nil
   462  }
   463  
   464  func makeHeaderChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Header {
   465  	blocks := makeBlockChainWithDiff(genesis, d, seed)
   466  	headers := make([]*types.Header, len(blocks))
   467  	for i, block := range blocks {
   468  		headers[i] = block.Header()
   469  	}
   470  	return headers
   471  }
   472  
   473  func makeBlockChainWithDiff(genesis *types.Block, d []int, seed byte) []*types.Block {
   474  	var chain []*types.Block
   475  	for i, difficulty := range d {
   476  		header := &types.Header{
   477  			Coinbase:    common.Address{seed},
   478  			Number:      big.NewInt(int64(i + 1)),
   479  			Difficulty:  big.NewInt(int64(difficulty)),
   480  			UncleHash:   types.EmptyUncleHash,
   481  			TxHash:      types.EmptyRootHash,
   482  			ReceiptHash: types.EmptyRootHash,
   483  		}
   484  		if i == 0 {
   485  			header.ParentHash = genesis.Hash()
   486  		} else {
   487  			header.ParentHash = chain[i-1].Hash()
   488  		}
   489  		block := types.NewBlockWithHeader(header)
   490  		chain = append(chain, block)
   491  	}
   492  	return chain
   493  }
   494  
   495  func chm(t testing.TB, genesis *types.Block, db ethdb.Database) *BlockChain {
   496  	var eventMux event.TypeMux
   497  	config := testChainConfig()
   498  	bc := &BlockChain{
   499  		chainDb:      db,
   500  		genesisBlock: genesis,
   501  		eventMux:     &eventMux,
   502  		pow:          FakePow{},
   503  		config:       config,
   504  	}
   505  	valFn := func() HeaderValidator { return bc.Validator() }
   506  	var err error
   507  	bc.hc, err = NewHeaderChain(db, config, bc.eventMux, valFn, bc.getProcInterrupt)
   508  	if err != nil {
   509  		t.Fatal(err)
   510  	}
   511  	bc.bodyCache, err = lru.New(100)
   512  	if err != nil {
   513  		t.Fatal(err)
   514  	}
   515  	bc.bodyRLPCache, err = lru.New(100)
   516  	if err != nil {
   517  		t.Fatal(err)
   518  	}
   519  	bc.blockCache, err = lru.New(100)
   520  	if err != nil {
   521  		t.Fatal(err)
   522  	}
   523  	bc.futureBlocks, err = lru.New(100)
   524  	if err != nil {
   525  		t.Fatal(err)
   526  	}
   527  	bc.SetValidator(bproc{})
   528  	bc.SetProcessor(bproc{})
   529  	bc.ResetWithGenesisBlock(genesis)
   530  
   531  	return bc
   532  }
   533  
   534  // Tests that reorganising a long difficult chain after a short easy one
   535  // overwrites the canonical numbers and links in the database.
   536  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   537  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   538  
   539  func testReorgLong(t *testing.T, full bool) {
   540  	testReorg(t, []int{1, 2, 4}, []int{1, 2, 3, 4}, 10, full)
   541  }
   542  
   543  // Tests that reorganising a short difficult chain after a long easy one
   544  // overwrites the canonical numbers and links in the database.
   545  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   546  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   547  
   548  func testReorgShort(t *testing.T, full bool) {
   549  	testReorg(t, []int{1, 2, 3, 4}, []int{1, 10}, 11, full)
   550  }
   551  
   552  func testReorg(t *testing.T, first, second []int, td int64, full bool) {
   553  	// Create a pristine block chain
   554  	db, err := ethdb.NewMemDatabase()
   555  	if err != nil {
   556  		t.Fatal(err)
   557  	}
   558  	genesis, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
   559  	if err != nil {
   560  		t.Fatal(err)
   561  	}
   562  	bc := chm(t, genesis, db)
   563  
   564  	// Insert an easy and a difficult chain afterwards
   565  	if full {
   566  		bc.InsertChain(makeBlockChainWithDiff(genesis, first, 11))
   567  		bc.InsertChain(makeBlockChainWithDiff(genesis, second, 22))
   568  	} else {
   569  		bc.InsertHeaderChain(makeHeaderChainWithDiff(genesis, first, 11), 1)
   570  		bc.InsertHeaderChain(makeHeaderChainWithDiff(genesis, second, 22), 1)
   571  	}
   572  	// Check that the chain is valid number and link wise
   573  	if full {
   574  		prev := bc.CurrentBlock()
   575  		for block := bc.GetBlockByNumber(bc.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, bc.GetBlockByNumber(block.NumberU64()-1) {
   576  			if prev.ParentHash() != block.Hash() {
   577  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   578  			}
   579  		}
   580  	} else {
   581  		prev := bc.CurrentHeader()
   582  		for header := bc.GetHeaderByNumber(bc.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, bc.GetHeaderByNumber(header.Number.Uint64()-1) {
   583  			if prev.ParentHash != header.Hash() {
   584  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   585  			}
   586  		}
   587  	}
   588  	// Make sure the chain total difficulty is the correct one
   589  	want := new(big.Int).Add(genesis.Difficulty(), big.NewInt(td))
   590  	if full {
   591  		if have := bc.GetTd(bc.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   592  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   593  		}
   594  	} else {
   595  		if have := bc.GetTd(bc.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   596  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   597  		}
   598  	}
   599  }
   600  
   601  func TestInsertHeaderChainBadHash(t *testing.T) {
   602  	db, err := ethdb.NewMemDatabase()
   603  	if err != nil {
   604  		t.Fatal(err)
   605  	}
   606  	genesis, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
   607  	if err != nil {
   608  		t.Fatal(err)
   609  	}
   610  	headers := makeHeaderChainWithDiff(genesis, []int{1, 2, 4}, 10)
   611  	bc := chm(t, genesis, db)
   612  	bc.config.BadHashes = []*BadHash{
   613  		{
   614  			Block: headers[2].Number,
   615  			Hash:  headers[2].Hash(),
   616  		},
   617  	}
   618  
   619  	res := bc.InsertHeaderChain(headers, 1)
   620  	if res.Error != ErrHashKnownBad {
   621  		t.Errorf("got error %#v, want %#v", res.Error, ErrHashKnownBad)
   622  	}
   623  }
   624  
   625  func TestInsertChainBadHash(t *testing.T) {
   626  	db, err := ethdb.NewMemDatabase()
   627  	if err != nil {
   628  		t.Fatal(err)
   629  	}
   630  	genesis, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
   631  	if err != nil {
   632  		t.Fatal(err)
   633  	}
   634  	blocks := makeBlockChainWithDiff(genesis, []int{1, 2, 4}, 10)
   635  	bc := chm(t, genesis, db)
   636  	bc.config.BadHashes = []*BadHash{
   637  		{
   638  			Block: blocks[2].Number(),
   639  			Hash:  blocks[2].Header().Hash(),
   640  		},
   641  	}
   642  
   643  	res := bc.InsertChain(blocks)
   644  	if res.Error != ErrHashKnownBad {
   645  		t.Errorf("got error %#v, want %#v", res.Error, ErrHashKnownBad)
   646  	}
   647  }
   648  
   649  // Tests that bad hashes are detected on boot, and the chain rolled back to a
   650  // good state prior to the bad hash.
   651  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   652  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   653  
   654  func testReorgBadHashes(t *testing.T, full bool) {
   655  	// Create a pristine block chain
   656  	db, err := ethdb.NewMemDatabase()
   657  	if err != nil {
   658  		t.Fatal(err)
   659  	}
   660  	genesis, err := WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
   661  	if err != nil {
   662  		t.Fatal(err)
   663  	}
   664  	bc := chm(t, genesis, db)
   665  
   666  	// Create a chain, import and ban afterwards
   667  	headers := makeHeaderChainWithDiff(genesis, []int{1, 2, 3, 4}, 10)
   668  	blocks := makeBlockChainWithDiff(genesis, []int{1, 2, 3, 4}, 10)
   669  
   670  	if full {
   671  		if res := bc.InsertChain(blocks); res.Error != nil {
   672  			t.Fatalf("failed to import blocks: %v", res.Error)
   673  		}
   674  		if bc.CurrentBlock().Hash() != blocks[3].Hash() {
   675  			t.Errorf("last block hash mismatch: have: %x, want %x", bc.CurrentBlock().Hash(), blocks[3].Header().Hash())
   676  		}
   677  		bc.config.BadHashes = []*BadHash{
   678  			{
   679  				Block: blocks[3].Number(),
   680  				Hash:  blocks[3].Header().Hash(),
   681  			},
   682  		}
   683  		defer func() { bc.config.BadHashes = []*BadHash{} }()
   684  	} else {
   685  		if res := bc.InsertHeaderChain(headers, 1); res.Error != nil {
   686  			t.Fatalf("failed to import headers: %v", res.Error)
   687  		}
   688  		if bc.CurrentHeader().Hash() != headers[3].Hash() {
   689  			t.Errorf("last header hash mismatch: have: %x, want %x", bc.CurrentHeader().Hash(), headers[3].Hash())
   690  		}
   691  		bc.config.BadHashes = []*BadHash{
   692  			{
   693  				Block: headers[3].Number,
   694  				Hash:  headers[3].Hash(),
   695  			},
   696  		}
   697  		defer func() { bc.config.BadHashes = []*BadHash{} }()
   698  	}
   699  	// Create a new chain manager and check it rolled back the state
   700  	ncm, err := NewBlockChain(db, bc.config, FakePow{}, new(event.TypeMux))
   701  	if err != nil {
   702  		t.Fatalf("failed to create new chain manager: %v", err)
   703  	}
   704  	if full {
   705  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   706  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   707  		}
   708  		if blocks[2].Header().GasLimit.Cmp(ncm.GasLimit()) != 0 {
   709  			t.Errorf("last  block gasLimit mismatch: have: %x, want %x", ncm.GasLimit(), blocks[2].Header().GasLimit)
   710  		}
   711  	} else {
   712  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   713  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   714  		}
   715  	}
   716  }
   717  
   718  // Tests chain insertions in the face of one entity containing an invalid nonce.
   719  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   720  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   721  
   722  func testInsertNonceError(t *testing.T, full bool) {
   723  	for i := 1; i < 25 && !t.Failed(); i++ {
   724  		// Create a pristine chain and database
   725  		db, blockchain, err := newCanonical(testChainConfig(), 0, full)
   726  		if err != nil {
   727  			t.Fatalf("failed to create pristine chain: %v", err)
   728  		}
   729  		// Create and insert a chain with a failing nonce
   730  		var (
   731  			failAt   int
   732  			failRes  int
   733  			failNum  uint64
   734  			failHash common.Hash
   735  		)
   736  		if full {
   737  			blocks := makeBlockChain(blockchain.config, blockchain.CurrentBlock(), i, db, 0)
   738  
   739  			failAt = rand.Int() % len(blocks)
   740  			failNum = blocks[failAt].NumberU64()
   741  			failHash = blocks[failAt].Hash()
   742  
   743  			blockchain.pow = failPow{failNum}
   744  
   745  			res := blockchain.InsertChain(blocks)
   746  			failRes, err = res.Index, res.Error
   747  		} else {
   748  			headers := makeHeaderChain(blockchain.config, blockchain.CurrentHeader(), i, db, 0)
   749  
   750  			failAt = rand.Int() % len(headers)
   751  			failNum = headers[failAt].Number.Uint64()
   752  			failHash = headers[failAt].Hash()
   753  
   754  			blockchain.pow = failPow{failNum}
   755  			blockchain.validator = NewBlockValidator(testChainConfig(), blockchain, failPow{failNum})
   756  
   757  			res := blockchain.InsertHeaderChain(headers, 1)
   758  			failRes, err = res.Index, res.Error
   759  		}
   760  		// Check that the returned error indicates the nonce failure.
   761  		if failRes != failAt {
   762  			t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt)
   763  		}
   764  		if !IsBlockNonceErr(err) {
   765  			t.Fatalf("test %d: error mismatch: have %v, want nonce error %T", i, err, err)
   766  		}
   767  		nerr := err.(*BlockNonceErr)
   768  		if nerr.Number.Uint64() != failNum {
   769  			t.Errorf("test %d: number mismatch: have %v, want %v", i, nerr.Number, failNum)
   770  		}
   771  		if nerr.Hash != failHash {
   772  			t.Errorf("test %d: hash mismatch: have %x, want %x", i, nerr.Hash[:4], failHash[:4])
   773  		}
   774  		// Check that all no blocks after the failing block have been inserted.
   775  		for j := 0; j < i-failAt; j++ {
   776  			if full {
   777  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   778  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   779  				}
   780  			} else {
   781  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   782  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   783  				}
   784  			}
   785  		}
   786  	}
   787  }
   788  
   789  // Tests that fast importing a block chain produces the same chain data as the
   790  // classical full block processing.
   791  func TestFastVsFullChains(t *testing.T) {
   792  	// Configure and generate a sample block chain
   793  	gendb, err := ethdb.NewMemDatabase()
   794  	if err != nil {
   795  		t.Fatal(err)
   796  	}
   797  	key, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   798  	if err != nil {
   799  		t.Fatal(err)
   800  	}
   801  	var (
   802  		address = crypto.PubkeyToAddress(key.PublicKey)
   803  		funds   = big.NewInt(1000000000)
   804  		genesis = GenesisBlockForTesting(gendb, address, funds)
   805  		signer  = types.NewChainIdSigner(big.NewInt(63))
   806  		config  = MakeDiehardChainConfig()
   807  	)
   808  	blocks, receipts := GenerateChain(config, genesis, gendb, 1024, func(i int, block *BlockGen) {
   809  		block.SetCoinbase(common.Address{0x00})
   810  
   811  		// If the block number is multiple of 3, send a few bonus transactions to the miner
   812  		if i%3 == 2 {
   813  			for j := 0; j < i%4+1; j++ {
   814  				tx, err := types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key)
   815  				if err != nil {
   816  					panic(err)
   817  				}
   818  				block.AddTx(tx)
   819  			}
   820  		}
   821  		// If the block number is a multiple of 5, add a few bonus uncles to the block
   822  		if i%5 == 5 {
   823  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   824  		}
   825  	})
   826  	// Import the chain as an archive node for the comparison baseline
   827  	archiveDb, err := ethdb.NewMemDatabase()
   828  	if err != nil {
   829  		t.Fatal(err)
   830  	}
   831  	WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
   832  
   833  	archive, err := NewBlockChain(archiveDb, config, FakePow{}, new(event.TypeMux))
   834  	if err != nil {
   835  		t.Fatal(err)
   836  	}
   837  
   838  	if res := archive.InsertChain(blocks); res.Error != nil {
   839  		t.Fatalf("failed to process block %d: %v", res.Index, res.Error)
   840  	}
   841  	// Fast import the chain as a non-archive node to test
   842  	fastDb, err := ethdb.NewMemDatabase()
   843  	if err != nil {
   844  		t.Fatal(err)
   845  	}
   846  	WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
   847  	fast, err := NewBlockChain(fastDb, config, FakePow{}, new(event.TypeMux))
   848  	if err != nil {
   849  		t.Fatal(err)
   850  	}
   851  
   852  	headers := make([]*types.Header, len(blocks))
   853  	for i, block := range blocks {
   854  		headers[i] = block.Header()
   855  	}
   856  	if res := fast.InsertHeaderChain(headers, 1); res.Error != nil {
   857  		t.Fatalf("failed to insert header %d: %v", res.Index, res.Error)
   858  	}
   859  	if res := fast.InsertReceiptChain(blocks, receipts); res.Error != nil {
   860  		t.Fatalf("failed to insert receipt %d: %v", res.Index, res.Error)
   861  	}
   862  	// Iterate over all chain data components, and cross reference
   863  	for i := 0; i < len(blocks); i++ {
   864  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   865  
   866  		if ftd, atd := fast.GetTd(hash), archive.GetTd(hash); ftd.Cmp(atd) != 0 {
   867  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   868  		}
   869  		if fheader, aheader := fast.GetHeader(hash), archive.GetHeader(hash); fheader.Hash() != aheader.Hash() {
   870  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   871  		}
   872  		if fblock, ablock := fast.GetBlock(hash), archive.GetBlock(hash); fblock.Hash() != ablock.Hash() {
   873  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   874  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   875  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   876  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   877  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   878  		}
   879  		if freceipts, areceipts := GetBlockReceipts(fastDb, hash), GetBlockReceipts(archiveDb, hash); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   880  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   881  		}
   882  	}
   883  	// Check that the canonical chains are the same between the databases
   884  	for i := 0; i < len(blocks)+1; i++ {
   885  		if fhash, ahash := GetCanonicalHash(fastDb, uint64(i)), GetCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   886  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   887  		}
   888  	}
   889  }
   890  
   891  func TestFastVsFullChainsATXI(t *testing.T) {
   892  	archiveDir, e := ioutil.TempDir("", "archive-")
   893  	if e != nil {
   894  		t.Fatal(e)
   895  	}
   896  	fastDir, e := ioutil.TempDir("", "fast-")
   897  	if e != nil {
   898  		t.Fatal(e)
   899  	}
   900  	defer os.RemoveAll(archiveDir)
   901  	defer os.RemoveAll(fastDir)
   902  
   903  	// Create the dbs
   904  	//
   905  	archiveDb, err := ethdb.NewLDBDatabase(archiveDir, 10, 100)
   906  	if err != nil {
   907  		t.Fatal(err)
   908  	}
   909  	fastDb, err := ethdb.NewLDBDatabase(fastDir, 10, 100)
   910  	if err != nil {
   911  		t.Fatal(err)
   912  	}
   913  
   914  	MinGasLimit = big.NewInt(125000)
   915  
   916  	key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   917  	if err != nil {
   918  		t.Fatal(err)
   919  	}
   920  	key2, err := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   921  	if err != nil {
   922  		t.Fatal(err)
   923  	}
   924  
   925  	var (
   926  		addr1  = crypto.PubkeyToAddress(key1.PublicKey)
   927  		addr2  = crypto.PubkeyToAddress(key2.PublicKey)
   928  		signer = types.NewChainIdSigner(big.NewInt(63))
   929  		dbs    = []ethdb.Database{archiveDb, fastDb}
   930  		config = MakeDiehardChainConfig()
   931  	)
   932  
   933  	for i, db := range dbs {
   934  		t1, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
   935  		if err != nil {
   936  			t.Fatal(err)
   937  		}
   938  		t2, err := types.NewTransaction(1, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
   939  		if err != nil {
   940  			t.Fatal(err)
   941  		}
   942  		t3, err := types.NewTransaction(0, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2)
   943  		if err != nil {
   944  			t.Fatal(err)
   945  		}
   946  		genesis := WriteGenesisBlockForTesting(db,
   947  			GenesisAccount{addr1, big.NewInt(1000000)},
   948  			GenesisAccount{addr2, big.NewInt(1000000)},
   949  		)
   950  		blocks, receipts := GenerateChain(config, genesis, db, 3, func(i int, gen *BlockGen) {
   951  			if i == 0 {
   952  				gen.AddTx(t1)
   953  			}
   954  			if i == 1 {
   955  				gen.AddTx(t2)
   956  			}
   957  			if i == 2 {
   958  				gen.AddTx(t3)
   959  			}
   960  		})
   961  
   962  		blockchain, err := NewBlockChain(db, config, FakePow{}, new(event.TypeMux))
   963  		if err != nil {
   964  			t.Fatal(err)
   965  		}
   966  		// turn on atxi
   967  		blockchain.SetAtxi(&AtxiT{Db: db})
   968  		if i == 0 {
   969  			if res := blockchain.InsertChain(blocks); res.Error != nil {
   970  				t.Fatalf("failed to process block %d: %v", res.Index, res.Error)
   971  			}
   972  		} else {
   973  			headers := make([]*types.Header, len(blocks))
   974  			for i, block := range blocks {
   975  				headers[i] = block.Header()
   976  			}
   977  			if res := blockchain.InsertHeaderChain(headers, 1); res.Error != nil {
   978  				t.Fatalf("failed to insert header %d: %v", res.Index, res.Error)
   979  			}
   980  			if res := blockchain.InsertReceiptChain(blocks, receipts); res.Error != nil {
   981  				t.Fatalf("failed to insert receipt %d: %v", res.Index, res.Error)
   982  			}
   983  		}
   984  
   985  		out, _ := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false)
   986  		if len(out) != 3 {
   987  			t.Errorf("[%d] got: %v, want: %v", i, len(out), 3)
   988  		}
   989  
   990  		// method should return an error if pagination params are invalid
   991  		_, err = GetAddrTxs(db, addr1, 0, 0, "", "", 2, 1, false)
   992  		if err == nil {
   993  			t.Errorf("[%d] got: %v, want: %v", i, err, errAtxiInvalidUse)
   994  		}
   995  
   996  		out, _ = GetAddrTxs(db, addr1, 0, 0, "from", "", -1, -1, false)
   997  		if len(out) != 2 {
   998  			t.Errorf("[%d] got: %v, want: %v", i, len(out), 2)
   999  		}
  1000  		out, _ = GetAddrTxs(db, addr1, 0, 0, "to", "", -1, -1, false)
  1001  		if len(out) != 1 {
  1002  			t.Errorf("[%d] got: %v, want: %v", i, len(out), 1)
  1003  		}
  1004  		out, _ = GetAddrTxs(db, addr2, 0, 0, "", "", -1, -1, false)
  1005  		if len(out) != 3 {
  1006  			t.Errorf("[%d] got: %v, want: %v", i, len(out), 3)
  1007  		}
  1008  		out, _ = GetAddrTxs(db, addr2, 3, 3, "", "", -1, -1, false)
  1009  		if len(out) != 1 {
  1010  			t.Errorf("[%d] got: %v, want: %v", i, len(out), 1)
  1011  		}
  1012  	}
  1013  }
  1014  
  1015  func TestRmAddrTx(t *testing.T) {
  1016  	archiveDir, e := ioutil.TempDir("", "archive-")
  1017  	if e != nil {
  1018  		t.Fatal(e)
  1019  	}
  1020  	defer os.RemoveAll(archiveDir)
  1021  
  1022  	// Create the dbs
  1023  	//
  1024  	db, err := ethdb.NewLDBDatabase(archiveDir, 10, 100)
  1025  	if err != nil {
  1026  		t.Fatal(err)
  1027  	}
  1028  
  1029  	MinGasLimit = big.NewInt(125000)
  1030  
  1031  	key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1032  	if err != nil {
  1033  		t.Fatal(err)
  1034  	}
  1035  	key2, err := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1036  	if err != nil {
  1037  		t.Fatal(err)
  1038  	}
  1039  
  1040  	var (
  1041  		addr1  = crypto.PubkeyToAddress(key1.PublicKey)
  1042  		addr2  = crypto.PubkeyToAddress(key2.PublicKey)
  1043  		signer = types.NewChainIdSigner(big.NewInt(63))
  1044  		config = MakeDiehardChainConfig()
  1045  	)
  1046  
  1047  	t1, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
  1048  	if err != nil {
  1049  		t.Fatal(err)
  1050  	}
  1051  	t2, err := types.NewTransaction(1, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
  1052  	if err != nil {
  1053  		t.Fatal(err)
  1054  	}
  1055  	t3, err := types.NewTransaction(0, addr1, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2)
  1056  	if err != nil {
  1057  		t.Fatal(err)
  1058  	}
  1059  	genesis := WriteGenesisBlockForTesting(db,
  1060  		GenesisAccount{addr1, big.NewInt(1000000)},
  1061  		GenesisAccount{addr2, big.NewInt(1000000)},
  1062  	)
  1063  	blocks, _ := GenerateChain(config, genesis, db, 3, func(i int, gen *BlockGen) {
  1064  		if i == 0 {
  1065  			gen.AddTx(t1)
  1066  		}
  1067  		if i == 1 {
  1068  			gen.AddTx(t2)
  1069  		}
  1070  		if i == 2 {
  1071  			gen.AddTx(t3)
  1072  		}
  1073  	})
  1074  
  1075  	blockchain, err := NewBlockChain(db, config, FakePow{}, new(event.TypeMux))
  1076  	if err != nil {
  1077  		t.Fatal(err)
  1078  	}
  1079  	// turn on atxi
  1080  	blockchain.SetAtxi(&AtxiT{Db: db})
  1081  
  1082  	if res := blockchain.InsertChain(blocks); res.Error != nil {
  1083  		t.Fatalf("failed to process block %d: %v", res.Index, res.Error)
  1084  	}
  1085  
  1086  	out, _ := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false)
  1087  	if len(out) != 3 {
  1088  		t.Errorf("got: %v, want: %v", len(out), 3)
  1089  	}
  1090  	if err := RmAddrTx(db, t1); err != nil {
  1091  		t.Fatal(err)
  1092  	}
  1093  	out, _ = GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false)
  1094  	if len(out) != 2 {
  1095  		t.Errorf("got: %v, want: %v", len(out), 2)
  1096  	}
  1097  }
  1098  
  1099  // Tests that various import methods move the chain head pointers to the correct
  1100  // positions.
  1101  func TestLightVsFastVsFullChainHeads(t *testing.T) {
  1102  	// Configure and generate a sample block chain
  1103  	gendb, err := ethdb.NewMemDatabase()
  1104  	if err != nil {
  1105  		t.Fatal(err)
  1106  	}
  1107  	key, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1108  	if err != nil {
  1109  		t.Fatal(err)
  1110  	}
  1111  	var (
  1112  		address = crypto.PubkeyToAddress(key.PublicKey)
  1113  		funds   = big.NewInt(1000000000)
  1114  		genesis = GenesisBlockForTesting(gendb, address, funds)
  1115  	)
  1116  	height := uint64(1024)
  1117  	blocks, receipts := GenerateChain(MakeChainConfig(), genesis, gendb, int(height), nil)
  1118  
  1119  	// Configure a subchain to roll back
  1120  	remove := []common.Hash{}
  1121  	for _, block := range blocks[height/2:] {
  1122  		remove = append(remove, block.Hash())
  1123  	}
  1124  	// Create a small assertion method to check the three heads
  1125  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
  1126  		if num := chain.CurrentBlock().NumberU64(); num != block {
  1127  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
  1128  		}
  1129  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
  1130  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
  1131  		}
  1132  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
  1133  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
  1134  		}
  1135  	}
  1136  	// Import the chain as an archive node and ensure all pointers are updated
  1137  	archiveDb, err := ethdb.NewMemDatabase()
  1138  	if err != nil {
  1139  		t.Fatal(err)
  1140  	}
  1141  	WriteGenesisBlockForTesting(archiveDb, GenesisAccount{address, funds})
  1142  
  1143  	archive, err := NewBlockChain(archiveDb, testChainConfig(), FakePow{}, new(event.TypeMux))
  1144  	if err != nil {
  1145  		t.Fatal(err)
  1146  	}
  1147  
  1148  	if res := archive.InsertChain(blocks); res.Error != nil {
  1149  		t.Fatalf("failed to process block %d: %v", res.Index, res.Error)
  1150  	}
  1151  	assert(t, "archive", archive, height, height, height)
  1152  	archive.Rollback(remove)
  1153  	assert(t, "archive", archive, height/2, height/2, height/2)
  1154  
  1155  	// Import the chain as a non-archive node and ensure all pointers are updated
  1156  	fastDb, err := ethdb.NewMemDatabase()
  1157  	if err != nil {
  1158  		t.Fatal(err)
  1159  	}
  1160  	WriteGenesisBlockForTesting(fastDb, GenesisAccount{address, funds})
  1161  	fast, err := NewBlockChain(fastDb, testChainConfig(), FakePow{}, new(event.TypeMux))
  1162  	if err != nil {
  1163  		t.Fatal(err)
  1164  	}
  1165  
  1166  	headers := make([]*types.Header, len(blocks))
  1167  	for i, block := range blocks {
  1168  		headers[i] = block.Header()
  1169  	}
  1170  	if res := fast.InsertHeaderChain(headers, 1); res.Error != nil {
  1171  		t.Fatalf("failed to insert header %d: %v", res.Index, res.Error)
  1172  	}
  1173  	if res := fast.InsertReceiptChain(blocks, receipts); res.Error != nil {
  1174  		t.Fatalf("failed to insert receipt %d: %v", res.Index, res.Error)
  1175  	}
  1176  	assert(t, "fast", fast, height, height, 0)
  1177  	fast.Rollback(remove)
  1178  	assert(t, "fast", fast, height/2, height/2, 0)
  1179  
  1180  	// Import the chain as a light node and ensure all pointers are updated
  1181  	lightDb, err := ethdb.NewMemDatabase()
  1182  	if err != nil {
  1183  		t.Fatal(err)
  1184  	}
  1185  	WriteGenesisBlockForTesting(lightDb, GenesisAccount{address, funds})
  1186  	light, err := NewBlockChain(lightDb, testChainConfig(), FakePow{}, new(event.TypeMux))
  1187  	if err != nil {
  1188  		t.Fatal(err)
  1189  	}
  1190  
  1191  	if res := light.InsertHeaderChain(headers, 1); res.Error != nil {
  1192  		t.Fatalf("failed to insert header %d: %v", res.Index, res.Error)
  1193  	}
  1194  	assert(t, "light", light, height, 0, 0)
  1195  	light.Rollback(remove)
  1196  	assert(t, "light", light, height/2, 0, 0)
  1197  }
  1198  
  1199  // Tests that chain reorganisations handle transaction removals and reinsertions.
  1200  func TestChainTxReorgs(t *testing.T) {
  1201  	db, err := ethdb.NewMemDatabase()
  1202  	if err != nil {
  1203  		t.Fatal(err)
  1204  	}
  1205  	testChainTxReorgs(t, db, false)
  1206  }
  1207  
  1208  func TestChainTxReorgsAtxi(t *testing.T) {
  1209  	p, err := ioutil.TempDir("", "test-reorg-atxi-")
  1210  	if err != nil {
  1211  		t.Fatal(err)
  1212  	}
  1213  	defer os.RemoveAll(p)
  1214  
  1215  	db, err := ethdb.NewLDBDatabase(p, 10, 100)
  1216  	if err != nil {
  1217  		t.Fatal(err)
  1218  	}
  1219  	testChainTxReorgs(t, db, true)
  1220  }
  1221  
  1222  func testChainTxReorgs(t *testing.T, db ethdb.Database, withATXI bool) {
  1223  	MinGasLimit = big.NewInt(125000)
  1224  
  1225  	key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1226  	if err != nil {
  1227  		t.Fatal(err)
  1228  	}
  1229  	key2, err := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
  1230  	if err != nil {
  1231  		t.Fatal(err)
  1232  	}
  1233  	key3, err := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
  1234  	if err != nil {
  1235  		t.Fatal(err)
  1236  	}
  1237  
  1238  	var (
  1239  		addr1  = crypto.PubkeyToAddress(key1.PublicKey)
  1240  		addr2  = crypto.PubkeyToAddress(key2.PublicKey)
  1241  		addr3  = crypto.PubkeyToAddress(key3.PublicKey)
  1242  		signer = types.NewChainIdSigner(big.NewInt(63))
  1243  	)
  1244  	genesis := WriteGenesisBlockForTesting(db,
  1245  		GenesisAccount{addr1, big.NewInt(1000000)},
  1246  		GenesisAccount{addr2, big.NewInt(1000000)},
  1247  		GenesisAccount{addr3, big.NewInt(1000000)},
  1248  	)
  1249  	// Create two transactions shared between the chains:
  1250  	// addr1 -> addr2
  1251  	//  - postponed: transaction included at a later block in the forked chain
  1252  	//  - swapped: transaction included at the same block number in the forked chain
  1253  	postponed, err := types.NewTransaction(0, addr2, big.NewInt(1000), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
  1254  	if err != nil {
  1255  		t.Fatal(err)
  1256  	}
  1257  	swapped, err := types.NewTransaction(1, addr2, big.NewInt(1001), TxGas, nil, nil).WithSigner(signer).SignECDSA(key1)
  1258  	if err != nil {
  1259  		t.Fatal(err)
  1260  	}
  1261  
  1262  	// Create two transactions that will be dropped by the forked chain:
  1263  	// addr2 -> addr3
  1264  	//  - pastDrop: transaction dropped retroactively from a past block
  1265  	//  - freshDrop: transaction dropped exactly at the block where the reorg is detected
  1266  	var pastDrop, freshDrop *types.Transaction
  1267  
  1268  	// Create three transactions that will be added in the forked chain:
  1269  	// addr3 -> addr1
  1270  	//  - pastAdd:   transaction added before the reorganization is detected
  1271  	//  - freshAdd:  transaction added at the exact block the reorg is detected
  1272  	//  - futureAdd: transaction added after the reorg has already finished
  1273  	var pastAdd, freshAdd, futureAdd *types.Transaction
  1274  
  1275  	// ATXI tallies, (means) will be removed
  1276  	// addr1: 2f+3t
  1277  	// addr2: 2t+(2f)
  1278  	// addr3: (2t)+3f
  1279  
  1280  	chainConfig := MakeDiehardChainConfig()
  1281  	chain, _ := GenerateChain(chainConfig, genesis, db, 3, func(i int, gen *BlockGen) {
  1282  		switch i {
  1283  		case 0:
  1284  			pastDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1002), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2)
  1285  
  1286  			gen.AddTx(pastDrop)  // This transaction will be dropped in the fork from below the split point
  1287  			gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork
  1288  
  1289  		case 2:
  1290  			freshDrop, _ = types.NewTransaction(gen.TxNonce(addr2), addr3, big.NewInt(1003), TxGas, nil, nil).WithSigner(signer).SignECDSA(key2)
  1291  
  1292  			gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point
  1293  			gen.AddTx(swapped)   // This transaction will be swapped out at the exact height
  1294  
  1295  			gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain
  1296  		}
  1297  	})
  1298  
  1299  	// Import the chain. This runs all block validation rules.
  1300  	evmux := &event.TypeMux{}
  1301  	blockchain, err := NewBlockChain(db, chainConfig, FakePow{}, evmux)
  1302  	if err != nil {
  1303  		t.Fatal(err)
  1304  	}
  1305  	if withATXI {
  1306  		blockchain.SetAtxi(&AtxiT{Db: db})
  1307  	}
  1308  	if res := blockchain.InsertChain(chain); res.Error != nil {
  1309  		t.Fatalf("failed to insert original chain[%d]: %v", res.Index, res.Error)
  1310  	}
  1311  
  1312  	// overwrite the old chain
  1313  	chain, _ = GenerateChain(chainConfig, genesis, db, 5, func(i int, gen *BlockGen) {
  1314  		switch i {
  1315  		case 0:
  1316  			pastAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1004), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3)
  1317  			gen.AddTx(pastAdd) // This transaction needs to be injected during reorg
  1318  
  1319  		case 2:
  1320  			gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain
  1321  			gen.AddTx(swapped)   // This transaction was swapped from the exact current spot in the original chain
  1322  
  1323  			freshAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1005), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3)
  1324  			gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time
  1325  
  1326  		case 3:
  1327  			futureAdd, _ = types.NewTransaction(gen.TxNonce(addr3), addr1, big.NewInt(1006), TxGas, nil, nil).WithSigner(signer).SignECDSA(key3)
  1328  			gen.AddTx(futureAdd) // This transaction will be added after a full reorg
  1329  		}
  1330  	})
  1331  	if res := blockchain.InsertChain(chain); res.Error != nil {
  1332  		t.Fatalf("failed to insert forked chain: %v", res.Error)
  1333  	}
  1334  
  1335  	// Conveniently grouped
  1336  	txsRemoved := types.Transactions{pastDrop, freshDrop}
  1337  	txsAdded := types.Transactions{pastAdd, freshAdd, futureAdd}
  1338  	txsShared := types.Transactions{postponed, swapped}
  1339  	txsAll := types.Transactions{pastDrop, freshDrop, pastAdd, freshAdd, futureAdd, postponed, swapped}
  1340  
  1341  	// removed tx
  1342  	for i, tx := range txsRemoved {
  1343  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn != nil {
  1344  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
  1345  		}
  1346  		if GetReceipt(db, tx.Hash()) != nil {
  1347  			t.Errorf("drop %d: receipt found while shouldn't have been", i)
  1348  		}
  1349  	}
  1350  	// added tx
  1351  	for i, tx := range txsAdded {
  1352  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
  1353  			t.Errorf("add %d: expected tx to be found", i)
  1354  		}
  1355  		if GetReceipt(db, tx.Hash()) == nil {
  1356  			t.Errorf("add %d: expected receipt to be found", i)
  1357  		}
  1358  	}
  1359  	// shared tx
  1360  	for i, tx := range txsShared {
  1361  		if txn, _, _, _ := GetTransaction(db, tx.Hash()); txn == nil {
  1362  			t.Errorf("share %d: expected tx to be found", i)
  1363  		}
  1364  		if GetReceipt(db, tx.Hash()) == nil {
  1365  			t.Errorf("share %d: expected receipt to be found", i)
  1366  		}
  1367  	}
  1368  
  1369  	// ATXI checks
  1370  	if !withATXI {
  1371  		return
  1372  	}
  1373  	txsh1, _ := GetAddrTxs(db, addr1, 0, 0, "", "", -1, -1, false)
  1374  	txsh2, _ := GetAddrTxs(db, addr2, 0, 0, "", "", -1, -1, false)
  1375  	txsh3, _ := GetAddrTxs(db, addr3, 0, 0, "", "", -1, -1, false)
  1376  
  1377  	allAtxis := txsh1
  1378  	allAtxis = append(allAtxis, txsh2...)
  1379  	allAtxis = append(allAtxis, txsh3...)
  1380  
  1381  	// Ensure a transaction exists for each atxi hash
  1382  	for _, x := range allAtxis {
  1383  		if tx, _, _, _ := GetTransaction(db, common.HexToHash(x)); tx == nil {
  1384  			t.Error("atxi not removed")
  1385  		}
  1386  	}
  1387  
  1388  	// Ensure no duplicate tx hashes returned
  1389  DUPECHECK:
  1390  	for i, l := range [][]string{txsh1, txsh2, txsh3} {
  1391  		j := strings.Join(l, "")
  1392  		for _, h := range l {
  1393  			if strings.Count(j, h[:8]) > 1 {
  1394  				// show offending tx
  1395  				offendingTxN := new(big.Int)
  1396  				for _, x := range txsAll {
  1397  					if x.Hash().Hex() == h {
  1398  						offendingTxN.Set(x.Value()) // use unique value as a way to identify offender
  1399  						break
  1400  					}
  1401  				}
  1402  				t.Log(strings.Join(l, "\n"))
  1403  				t.Errorf("[%d] duplicate tx hash (%v)", i, offendingTxN)
  1404  				break DUPECHECK
  1405  			}
  1406  		}
  1407  
  1408  	}
  1409  
  1410  	// Check magnitude; 2 atxis per canonical tx (to & from)
  1411  	wantMag := (len(txsAdded) + len(txsShared)) * 2
  1412  	if len(allAtxis) != wantMag {
  1413  		t.Errorf("got: %v, want: %v", len(allAtxis), wantMag)
  1414  	}
  1415  }
  1416  
  1417  func TestLogReorgs(t *testing.T) {
  1418  	// This test itself is a little bit incorrect. Below,
  1419  	// MakeDiehardChainConfig would make a chain configuration that
  1420  	// only contains EIP160, and bypass EIP150 and Homestead. We never
  1421  	// have any chain like this exist in real world, so SputnikVM does
  1422  	// not contain a patch for this. As a result, it cannot figure out
  1423  	// a correct patch to run. So we bypass this test when running
  1424  	// with `UseSputnikVM`.
  1425  	if UseSputnikVM == "true" {
  1426  		return
  1427  	}
  1428  
  1429  	MinGasLimit = big.NewInt(125000)
  1430  
  1431  	key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1432  	if err != nil {
  1433  		t.Fatal(err)
  1434  	}
  1435  	addr1 := crypto.PubkeyToAddress(key1.PublicKey)
  1436  	// this code generates a log
  1437  	code := common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
  1438  	signer := types.NewChainIdSigner(big.NewInt(63))
  1439  	db, err := ethdb.NewMemDatabase()
  1440  	if err != nil {
  1441  		t.Fatal(err)
  1442  	}
  1443  	genesis := WriteGenesisBlockForTesting(db,
  1444  		GenesisAccount{addr1, big.NewInt(10000000000000)},
  1445  	)
  1446  	chainConfig := MakeDiehardChainConfig()
  1447  
  1448  	evmux := &event.TypeMux{}
  1449  	blockchain, err := NewBlockChain(db, chainConfig, FakePow{}, evmux)
  1450  	if err != nil {
  1451  		t.Fatal(err)
  1452  	}
  1453  
  1454  	subs := evmux.Subscribe(RemovedLogsEvent{})
  1455  	chain, _ := GenerateChain(chainConfig, genesis, db, 2, func(i int, gen *BlockGen) {
  1456  		if i == 1 {
  1457  			tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), code).WithSigner(signer).SignECDSA(key1)
  1458  			if err != nil {
  1459  				t.Fatalf("failed to create tx: %v", err)
  1460  			}
  1461  			gen.AddTx(tx)
  1462  		}
  1463  	})
  1464  	if res := blockchain.InsertChain(chain); res.Error != nil {
  1465  		t.Fatalf("failed to insert chain: %v", res.Error)
  1466  	}
  1467  
  1468  	chain, _ = GenerateChain(chainConfig, genesis, db, 3, func(i int, gen *BlockGen) {})
  1469  	if res := blockchain.InsertChain(chain); res.Error != nil {
  1470  		t.Fatalf("failed to insert forked chain: %v", res.Error)
  1471  	}
  1472  
  1473  	ev := <-subs.Chan()
  1474  	if len(ev.Data.(RemovedLogsEvent).Logs) == 0 {
  1475  		t.Error("expected logs")
  1476  	}
  1477  }
  1478  
  1479  func TestReorgSideEvent(t *testing.T) {
  1480  	// This test itself is a little bit incorrect. Below,
  1481  	// MakeDiehardChainConfig would make a chain configuration that
  1482  	// only contains EIP160, and bypass EIP150 and Homestead. We never
  1483  	// have any chain like this exist in real world, so SputnikVM does
  1484  	// not contain a patch for this. As a result, it cannot figure out
  1485  	// a correct patch to run. So we bypass this test when running
  1486  	// with `UseSputnikVM`.
  1487  	if UseSputnikVM == "true" {
  1488  		return
  1489  	}
  1490  
  1491  	key1, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1492  	if err != nil {
  1493  		t.Fatal(err)
  1494  	}
  1495  	addr1 := crypto.PubkeyToAddress(key1.PublicKey)
  1496  	db, err := ethdb.NewMemDatabase()
  1497  	if err != nil {
  1498  		t.Fatal(err)
  1499  	}
  1500  	genesis := WriteGenesisBlockForTesting(db, GenesisAccount{addr1, big.NewInt(10000000000000)})
  1501  	signer := types.NewChainIdSigner(big.NewInt(63))
  1502  	chainConfig := MakeDiehardChainConfig()
  1503  
  1504  	evmux := &event.TypeMux{}
  1505  	blockchain, err := NewBlockChain(db, chainConfig, FakePow{}, evmux)
  1506  	if err != nil {
  1507  		t.Fatal(err)
  1508  	}
  1509  
  1510  	chain, _ := GenerateChain(blockchain.config, genesis, db, 3, func(i int, gen *BlockGen) {})
  1511  	if res := blockchain.InsertChain(chain); res.Error != nil {
  1512  		t.Fatalf("failed to insert chain: %v", res.Error)
  1513  	}
  1514  
  1515  	replacementBlocks, _ := GenerateChain(blockchain.config, genesis, db, 4, func(i int, gen *BlockGen) {
  1516  		tx, err := types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), big.NewInt(1000000), new(big.Int), nil).WithSigner(signer).SignECDSA(key1)
  1517  		if i == 2 {
  1518  			gen.OffsetTime(-1)
  1519  		}
  1520  		if err != nil {
  1521  			t.Fatalf("failed to create tx: %v", err)
  1522  		}
  1523  		gen.AddTx(tx)
  1524  	})
  1525  
  1526  	subs := evmux.Subscribe(ChainSideEvent{})
  1527  	if res := blockchain.InsertChain(replacementBlocks); res.Error != nil {
  1528  		t.Fatalf("failed to insert chain: %v", res.Error)
  1529  	}
  1530  
  1531  	// first two block of the secondary chain are for a brief moment considered
  1532  	// side chains because up to that point the first one is considered the
  1533  	// heavier chain.
  1534  	expectedSideHashes := map[common.Hash]bool{
  1535  		replacementBlocks[0].Hash(): true,
  1536  		replacementBlocks[1].Hash(): true,
  1537  		chain[0].Hash():             true,
  1538  		chain[1].Hash():             true,
  1539  		chain[2].Hash():             true,
  1540  	}
  1541  
  1542  	i := 0
  1543  
  1544  	const timeoutDura = 10 * time.Second
  1545  	timeout := time.NewTimer(timeoutDura)
  1546  done:
  1547  	for {
  1548  		select {
  1549  		case ev := <-subs.Chan():
  1550  			block := ev.Data.(ChainSideEvent).Block
  1551  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
  1552  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
  1553  			}
  1554  			i++
  1555  
  1556  			if i == len(expectedSideHashes) {
  1557  				timeout.Stop()
  1558  
  1559  				break done
  1560  			}
  1561  			timeout.Reset(timeoutDura)
  1562  
  1563  		case <-timeout.C:
  1564  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1565  		}
  1566  	}
  1567  
  1568  	// make sure no more events are fired
  1569  	select {
  1570  	case e := <-subs.Chan():
  1571  		t.Errorf("unexpected event fired: %v", e)
  1572  	case <-time.After(250 * time.Millisecond):
  1573  	}
  1574  
  1575  }
  1576  
  1577  // Tests if the canonical block can be fetched from the database during chain insertion.
  1578  func TestCanonicalBlockRetrieval(t *testing.T) {
  1579  	t.Skip("Skipped: needs updating")
  1580  	db, err := ethdb.NewMemDatabase()
  1581  	if err != nil {
  1582  		t.Fatal(err)
  1583  	}
  1584  	genesis := WriteGenesisBlockForTesting(db)
  1585  
  1586  	evmux := &event.TypeMux{}
  1587  	blockchain, err := NewBlockChain(db, testChainConfig(), FakePow{}, evmux)
  1588  	if err != nil {
  1589  		t.Fatal(err)
  1590  	}
  1591  
  1592  	chain, _ := GenerateChain(MakeChainConfig(), genesis, db, 10, func(i int, gen *BlockGen) {})
  1593  
  1594  	for i := range chain {
  1595  		go func(block *types.Block) {
  1596  			// try to retrieve a block by its canonical hash and see if the block data can be retrieved.
  1597  			for {
  1598  				ch := GetCanonicalHash(db, block.NumberU64())
  1599  				if ch == (common.Hash{}) {
  1600  					continue // busy wait for canonical hash to be written
  1601  				}
  1602  				if ch != block.Hash() {
  1603  					t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1604  				}
  1605  				fb := GetBlock(db, ch)
  1606  				if fb == nil {
  1607  					t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1608  				}
  1609  				if fb.Hash() != block.Hash() {
  1610  					t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1611  				}
  1612  				return
  1613  			}
  1614  		}(chain[i])
  1615  
  1616  		blockchain.InsertChain(types.Blocks{chain[i]})
  1617  	}
  1618  }
  1619  
  1620  func TestEIP155Transition(t *testing.T) {
  1621  	// Configure and generate a sample block chain
  1622  	db, err := ethdb.NewMemDatabase()
  1623  	if err != nil {
  1624  		t.Fatal(err)
  1625  	}
  1626  	key, err := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1627  	if err != nil {
  1628  		t.Fatal(err)
  1629  	}
  1630  	var (
  1631  		address = crypto.PubkeyToAddress(key.PublicKey)
  1632  		funds   = big.NewInt(1000000000)
  1633  		genesis = WriteGenesisBlockForTesting(db, GenesisAccount{address, funds})
  1634  		config  = &ChainConfig{
  1635  			Forks: []*Fork{
  1636  				{
  1637  					Name:  "Homestead",
  1638  					Block: big.NewInt(0),
  1639  					Features: []*ForkFeature{
  1640  						{
  1641  							ID: "difficulty",
  1642  							Options: ChainFeatureConfigOptions{
  1643  								"type": "homestead",
  1644  							},
  1645  						},
  1646  						{
  1647  							ID: "gastable",
  1648  							Options: ChainFeatureConfigOptions{
  1649  								"type": "homestead",
  1650  							},
  1651  						},
  1652  					},
  1653  				},
  1654  				{
  1655  					Name:  "Diehard",
  1656  					Block: big.NewInt(2),
  1657  					Features: []*ForkFeature{
  1658  						{
  1659  							ID: "eip155",
  1660  							Options: ChainFeatureConfigOptions{
  1661  								"chainID": 1,
  1662  							},
  1663  						},
  1664  						{ // ecip1010 bomb delay
  1665  							ID: "gastable",
  1666  							Options: ChainFeatureConfigOptions{
  1667  								"type": "eip160",
  1668  							},
  1669  						},
  1670  						{ // ecip1010 bomb delay
  1671  							ID: "difficulty",
  1672  							Options: ChainFeatureConfigOptions{
  1673  								"type":   "ecip1010",
  1674  								"length": 2000000,
  1675  							},
  1676  						},
  1677  					},
  1678  				},
  1679  			},
  1680  		}
  1681  		mux event.TypeMux
  1682  	)
  1683  
  1684  	blockchain, err := NewBlockChain(db, config, FakePow{}, &mux)
  1685  	if err != nil {
  1686  		t.Fatal(err)
  1687  	}
  1688  	blocks, _ := GenerateChain(config, genesis, db, 4, func(i int, block *BlockGen) {
  1689  		var (
  1690  			tx      *types.Transaction
  1691  			err     error
  1692  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1693  				tx := types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil)
  1694  				tx.SetSigner(signer)
  1695  				return tx.SignECDSA(key)
  1696  			}
  1697  		)
  1698  		switch i {
  1699  		case 0:
  1700  			tx, err = basicTx(types.BasicSigner{})
  1701  			if err != nil {
  1702  				t.Fatal(err)
  1703  			}
  1704  			block.AddTx(tx)
  1705  		case 2:
  1706  			tx, err = basicTx(types.BasicSigner{})
  1707  			if err != nil {
  1708  				t.Fatal(err)
  1709  			}
  1710  			block.AddTx(tx)
  1711  
  1712  			tx, err = basicTx(types.NewChainIdSigner(config.GetChainID()))
  1713  			if err != nil {
  1714  				t.Fatal(err)
  1715  			}
  1716  			block.AddTx(tx)
  1717  		case 3:
  1718  			tx, err = basicTx(types.BasicSigner{})
  1719  			if err != nil {
  1720  				t.Fatal(err)
  1721  			}
  1722  			block.AddTx(tx)
  1723  
  1724  			tx, err = basicTx(types.NewChainIdSigner(config.GetChainID()))
  1725  			if err != nil {
  1726  				t.Fatal(err)
  1727  			}
  1728  			block.AddTx(tx)
  1729  		}
  1730  	})
  1731  
  1732  	if res := blockchain.InsertChain(blocks); res.Error != nil {
  1733  		t.Fatal(res.Error)
  1734  	}
  1735  	block := blockchain.GetBlockByNumber(1)
  1736  	if block.Transactions()[0].Protected() {
  1737  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1738  	}
  1739  
  1740  	block = blockchain.GetBlockByNumber(3)
  1741  	if block.Transactions()[0].Protected() {
  1742  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1743  	}
  1744  	if !block.Transactions()[1].Protected() {
  1745  		t.Error("Expected block[3].txs[1] to be replay protected")
  1746  	}
  1747  	if res := blockchain.InsertChain(blocks[4:]); res.Error != nil {
  1748  		t.Fatal(res.Error)
  1749  	}
  1750  
  1751  	// generate an invalid chain id transaction
  1752  	config = &ChainConfig{
  1753  		Forks: []*Fork{
  1754  			{
  1755  				Name:  "Homestead",
  1756  				Block: big.NewInt(0),
  1757  				Features: []*ForkFeature{
  1758  					{
  1759  						ID: "difficulty",
  1760  						Options: ChainFeatureConfigOptions{
  1761  							"type": "homestead",
  1762  						},
  1763  					},
  1764  					{
  1765  						ID: "gastable",
  1766  						Options: ChainFeatureConfigOptions{
  1767  							"type": "homestead",
  1768  						},
  1769  					},
  1770  				},
  1771  			},
  1772  			{
  1773  				Name:  "Diehard",
  1774  				Block: big.NewInt(2),
  1775  				Features: []*ForkFeature{
  1776  					{
  1777  						ID: "eip155",
  1778  						Options: ChainFeatureConfigOptions{
  1779  							"chainID": 2,
  1780  						},
  1781  					},
  1782  					{ // ecip1010 bomb delay
  1783  						ID: "gastable",
  1784  						Options: ChainFeatureConfigOptions{
  1785  							"type": "eip160",
  1786  						},
  1787  					},
  1788  					{ // ecip1010 bomb delay
  1789  						ID: "difficulty",
  1790  						Options: ChainFeatureConfigOptions{
  1791  							"type":   "ecip1010",
  1792  							"length": 2000000,
  1793  						},
  1794  					},
  1795  				},
  1796  			},
  1797  		},
  1798  	}
  1799  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], db, 4, func(i int, block *BlockGen) {
  1800  		var (
  1801  			tx      *types.Transaction
  1802  			err     error
  1803  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1804  				tx := types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), big.NewInt(21000), new(big.Int), nil)
  1805  				tx.SetSigner(signer)
  1806  				return tx.SignECDSA(key)
  1807  			}
  1808  		)
  1809  		switch i {
  1810  		case 0:
  1811  			tx, err = basicTx(types.NewChainIdSigner(config.GetChainID()))
  1812  			if err != nil {
  1813  				t.Fatal(err)
  1814  			}
  1815  			block.AddTx(tx)
  1816  		}
  1817  	})
  1818  	errExp := "Invalid transaction chain id. Current chain id: 1 tx chain id: 2"
  1819  	res := blockchain.InsertChain(blocks)
  1820  	if res.Error == nil {
  1821  		t.Error("expected transaction chain id error")
  1822  	} else if res.Error.Error() != errExp {
  1823  		t.Error("expected:", errExp, "got:", res.Error)
  1824  	}
  1825  }
  1826  
  1827  func TestBlockChain_BlockIsGenesis(t *testing.T) {
  1828  	// Make chain starting from genesis
  1829  	_, blockchain, err := newCanonical(testChainConfig(), 10, false)
  1830  	if err != nil {
  1831  		t.Fatalf("failed to make new canonical chain: %v", err)
  1832  	}
  1833  
  1834  	if !blockchain.blockIsGenesis(blockchain.GetBlockByNumber(0)) {
  1835  		t.Errorf("expected: is genesis block")
  1836  	}
  1837  	if blockchain.blockIsGenesis(blockchain.GetBlockByNumber(1)) {
  1838  		t.Errorf("expected: is not genesis block")
  1839  	}
  1840  }