github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/core/blockchain_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:35</date>
    10  //</624450077707997184>
    11  
    12  
    13  package core
    14  
    15  import (
    16  	"fmt"
    17  	"math/big"
    18  	"math/rand"
    19  	"sync"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/consensus"
    25  	"github.com/ethereum/go-ethereum/consensus/ethash"
    26  	"github.com/ethereum/go-ethereum/core/rawdb"
    27  	"github.com/ethereum/go-ethereum/core/state"
    28  	"github.com/ethereum/go-ethereum/core/types"
    29  	"github.com/ethereum/go-ethereum/core/vm"
    30  	"github.com/ethereum/go-ethereum/crypto"
    31  	"github.com/ethereum/go-ethereum/ethdb"
    32  	"github.com/ethereum/go-ethereum/params"
    33  )
    34  
    35  //所以我们可以确定地植入不同的区块链
    36  var (
    37  	canonicalSeed = 1
    38  	forkSeed      = 2
    39  )
    40  
    41  //newcanonical创建一个链数据库,并注入一个确定性canonical
    42  //链。根据完整标志,如果创建完整的区块链或
    43  //仅限收割台链条。
    44  func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
    45  	var (
    46  		db      = ethdb.NewMemDatabase()
    47  		genesis = new(Genesis).MustCommit(db)
    48  	)
    49  
    50  //仅使用Genesis块初始化新链
    51  	blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil)
    52  //创建并注入请求的链
    53  	if n == 0 {
    54  		return db, blockchain, nil
    55  	}
    56  	if full {
    57  //请求完整的区块链
    58  		blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed)
    59  		_, err := blockchain.InsertChain(blocks)
    60  		return db, blockchain, err
    61  	}
    62  //仅请求头链
    63  	headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed)
    64  	_, err := blockchain.InsertHeaderChain(headers, 1)
    65  	return db, blockchain, err
    66  }
    67  
    68  //从I区开始的长度为n的测试叉
    69  func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) {
    70  //将旧链复制到新数据库中
    71  	db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full)
    72  	if err != nil {
    73  		t.Fatal("could not make new canonical in testFork", err)
    74  	}
    75  	defer blockchain2.Stop()
    76  
    77  //断言链在i处具有相同的头/块
    78  	var hash1, hash2 common.Hash
    79  	if full {
    80  		hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash()
    81  		hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash()
    82  	} else {
    83  		hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash()
    84  		hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash()
    85  	}
    86  	if hash1 != hash2 {
    87  		t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1)
    88  	}
    89  //扩展新创建的链
    90  	var (
    91  		blockChainB  []*types.Block
    92  		headerChainB []*types.Header
    93  	)
    94  	if full {
    95  		blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed)
    96  		if _, err := blockchain2.InsertChain(blockChainB); err != nil {
    97  			t.Fatalf("failed to insert forking chain: %v", err)
    98  		}
    99  	} else {
   100  		headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed)
   101  		if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil {
   102  			t.Fatalf("failed to insert forking chain: %v", err)
   103  		}
   104  	}
   105  //健全性检查叉链是否可以导入原始
   106  	var tdPre, tdPost *big.Int
   107  
   108  	if full {
   109  		tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash())
   110  		if err := testBlockChainImport(blockChainB, blockchain); err != nil {
   111  			t.Fatalf("failed to import forked block chain: %v", err)
   112  		}
   113  		tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash())
   114  	} else {
   115  		tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash())
   116  		if err := testHeaderChainImport(headerChainB, blockchain); err != nil {
   117  			t.Fatalf("failed to import forked header chain: %v", err)
   118  		}
   119  		tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash())
   120  	}
   121  //比较链条的总难度
   122  	comparator(tdPre, tdPost)
   123  }
   124  
   125  func printChain(bc *BlockChain) {
   126  	for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- {
   127  		b := bc.GetBlockByNumber(uint64(i))
   128  		fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty())
   129  	}
   130  }
   131  
   132  //TestBlockChainImport尝试处理一系列块,将它们写入
   133  //如果成功,则返回数据库。
   134  func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
   135  	for _, block := range chain {
   136  //尝试并处理块
   137  		err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true)
   138  		if err == nil {
   139  			err = blockchain.validator.ValidateBody(block)
   140  		}
   141  		if err != nil {
   142  			if err == ErrKnownBlock {
   143  				continue
   144  			}
   145  			return err
   146  		}
   147  		statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache)
   148  		if err != nil {
   149  			return err
   150  		}
   151  		receipts, _, usedGas, err := blockchain.Processor().Process(block, statedb, vm.Config{})
   152  		if err != nil {
   153  			blockchain.reportBlock(block, receipts, err)
   154  			return err
   155  		}
   156  		err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas)
   157  		if err != nil {
   158  			blockchain.reportBlock(block, receipts, err)
   159  			return err
   160  		}
   161  		blockchain.chainmu.Lock()
   162  		rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
   163  		rawdb.WriteBlock(blockchain.db, block)
   164  		statedb.Commit(false)
   165  		blockchain.chainmu.Unlock()
   166  	}
   167  	return nil
   168  }
   169  
   170  //testHeaderChainimport尝试处理一个头链,将其写入
   171  //如果成功,则返回数据库。
   172  func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error {
   173  	for _, header := range chain {
   174  //尝试验证标题
   175  		if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil {
   176  			return err
   177  		}
   178  //手动将头插入数据库,但不重新组织(允许后续测试)
   179  		blockchain.chainmu.Lock()
   180  		rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash)))
   181  		rawdb.WriteHeader(blockchain.db, header)
   182  		blockchain.chainmu.Unlock()
   183  	}
   184  	return nil
   185  }
   186  
   187  func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) {
   188  	_, err := blockchain.InsertChain(chain)
   189  	if err != nil {
   190  		fmt.Println(err)
   191  		t.FailNow()
   192  	}
   193  	done <- true
   194  }
   195  
   196  func TestLastBlock(t *testing.T) {
   197  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
   198  	if err != nil {
   199  		t.Fatalf("failed to create pristine chain: %v", err)
   200  	}
   201  	defer blockchain.Stop()
   202  
   203  	blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0)
   204  	if _, err := blockchain.InsertChain(blocks); err != nil {
   205  		t.Fatalf("Failed to insert block: %v", err)
   206  	}
   207  	if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) {
   208  		t.Fatalf("Write/Get HeadBlockHash failed")
   209  	}
   210  }
   211  
   212  //测试给定一个给定大小的起始规范链,它可以被扩展
   213  //有各种长度的链条。
   214  func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) }
   215  func TestExtendCanonicalBlocks(t *testing.T)  { testExtendCanonical(t, true) }
   216  
   217  func testExtendCanonical(t *testing.T, full bool) {
   218  	length := 5
   219  
   220  //从创世纪开始制造第一条链条
   221  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   222  	if err != nil {
   223  		t.Fatalf("failed to make new canonical chain: %v", err)
   224  	}
   225  	defer processor.Stop()
   226  
   227  //定义难度比较器
   228  	better := func(td1, td2 *big.Int) {
   229  		if td2.Cmp(td1) <= 0 {
   230  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   231  		}
   232  	}
   233  //从当前高度开始拨叉
   234  	testFork(t, processor, length, 1, full, better)
   235  	testFork(t, processor, length, 2, full, better)
   236  	testFork(t, processor, length, 5, full, better)
   237  	testFork(t, processor, length, 10, full, better)
   238  }
   239  
   240  //测试给定给定大小的起始规范链,创建较短的
   241  //forks不具有规范的所有权。
   242  func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) }
   243  func TestShorterForkBlocks(t *testing.T)  { testShorterFork(t, true) }
   244  
   245  func testShorterFork(t *testing.T, full bool) {
   246  	length := 10
   247  
   248  //从创世纪开始制造第一条链条
   249  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   250  	if err != nil {
   251  		t.Fatalf("failed to make new canonical chain: %v", err)
   252  	}
   253  	defer processor.Stop()
   254  
   255  //定义难度比较器
   256  	worse := func(td1, td2 *big.Int) {
   257  		if td2.Cmp(td1) >= 0 {
   258  			t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1)
   259  		}
   260  	}
   261  //数字之和必须小于“length”,才能成为较短的分叉
   262  	testFork(t, processor, 0, 3, full, worse)
   263  	testFork(t, processor, 0, 7, full, worse)
   264  	testFork(t, processor, 1, 1, full, worse)
   265  	testFork(t, processor, 1, 7, full, worse)
   266  	testFork(t, processor, 5, 3, full, worse)
   267  	testFork(t, processor, 5, 4, full, worse)
   268  }
   269  
   270  //测试给定给定大小的起始规范链,创建更长的
   271  //forks确实拥有规范的所有权。
   272  func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) }
   273  func TestLongerForkBlocks(t *testing.T)  { testLongerFork(t, true) }
   274  
   275  func testLongerFork(t *testing.T, full bool) {
   276  	length := 10
   277  
   278  //从创世纪开始制造第一条链条
   279  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   280  	if err != nil {
   281  		t.Fatalf("failed to make new canonical chain: %v", err)
   282  	}
   283  	defer processor.Stop()
   284  
   285  //定义难度比较器
   286  	better := func(td1, td2 *big.Int) {
   287  		if td2.Cmp(td1) <= 0 {
   288  			t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1)
   289  		}
   290  	}
   291  //数字之和必须大于“length”,才能成为较长的分叉
   292  	testFork(t, processor, 0, 11, full, better)
   293  	testFork(t, processor, 0, 15, full, better)
   294  	testFork(t, processor, 1, 10, full, better)
   295  	testFork(t, processor, 1, 12, full, better)
   296  	testFork(t, processor, 5, 6, full, better)
   297  	testFork(t, processor, 5, 8, full, better)
   298  }
   299  
   300  //测试给定给定大小的起始规范链,创建相等的
   301  //forks确实拥有规范的所有权。
   302  func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) }
   303  func TestEqualForkBlocks(t *testing.T)  { testEqualFork(t, true) }
   304  
   305  func testEqualFork(t *testing.T, full bool) {
   306  	length := 10
   307  
   308  //从创世纪开始制造第一条链条
   309  	_, processor, err := newCanonical(ethash.NewFaker(), length, full)
   310  	if err != nil {
   311  		t.Fatalf("failed to make new canonical chain: %v", err)
   312  	}
   313  	defer processor.Stop()
   314  
   315  //定义难度比较器
   316  	equal := func(td1, td2 *big.Int) {
   317  		if td2.Cmp(td1) != 0 {
   318  			t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1)
   319  		}
   320  	}
   321  //数字之和必须等于“length”,才能成为相等的叉
   322  	testFork(t, processor, 0, 10, full, equal)
   323  	testFork(t, processor, 1, 9, full, equal)
   324  	testFork(t, processor, 2, 8, full, equal)
   325  	testFork(t, processor, 5, 5, full, equal)
   326  	testFork(t, processor, 6, 4, full, equal)
   327  	testFork(t, processor, 9, 1, full, equal)
   328  }
   329  
   330  //处理器不接受链接缺失的测试。
   331  func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) }
   332  func TestBrokenBlockChain(t *testing.T)  { testBrokenChain(t, true) }
   333  
   334  func testBrokenChain(t *testing.T, full bool) {
   335  //从Genesis开始制作链条
   336  	db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full)
   337  	if err != nil {
   338  		t.Fatalf("failed to make new canonical chain: %v", err)
   339  	}
   340  	defer blockchain.Stop()
   341  
   342  //创建分叉链,并尝试插入缺少的链接
   343  	if full {
   344  		chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   345  		if err := testBlockChainImport(chain, blockchain); err == nil {
   346  			t.Errorf("broken block chain not reported")
   347  		}
   348  	} else {
   349  		chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:]
   350  		if err := testHeaderChainImport(chain, blockchain); err == nil {
   351  			t.Errorf("broken header chain not reported")
   352  		}
   353  	}
   354  }
   355  
   356  //在短而容易的链条之后对长而难的链条进行重组的测试
   357  //覆盖数据库中的规范数字和链接。
   358  func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) }
   359  func TestReorgLongBlocks(t *testing.T)  { testReorgLong(t, true) }
   360  
   361  func testReorgLong(t *testing.T, full bool) {
   362  	testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full)
   363  }
   364  
   365  //在一个长而容易的链之后重新组织一个短而难的链的测试
   366  //覆盖数据库中的规范数字和链接。
   367  func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) }
   368  func TestReorgShortBlocks(t *testing.T)  { testReorgShort(t, true) }
   369  
   370  func testReorgShort(t *testing.T, full bool) {
   371  //创建一个长而容易的链条与短而重的链条。由于调整困难
   372  //我们需要一个相当长的、有不同困难的区块链。
   373  //比长的更重。96是一个经验值。
   374  	easy := make([]int64, 96)
   375  	for i := 0; i < len(easy); i++ {
   376  		easy[i] = 60
   377  	}
   378  	diff := make([]int64, len(easy)-1)
   379  	for i := 0; i < len(diff); i++ {
   380  		diff[i] = -9
   381  	}
   382  	testReorg(t, easy, diff, 12615120, full)
   383  }
   384  
   385  func testReorg(t *testing.T, first, second []int64, td int64, full bool) {
   386  //创建原始链和数据库
   387  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   388  	if err != nil {
   389  		t.Fatalf("failed to create pristine chain: %v", err)
   390  	}
   391  	defer blockchain.Stop()
   392  
   393  //然后插入一个容易和困难的链条
   394  	easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) {
   395  		b.OffsetTime(first[i])
   396  	})
   397  	diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) {
   398  		b.OffsetTime(second[i])
   399  	})
   400  	if full {
   401  		if _, err := blockchain.InsertChain(easyBlocks); err != nil {
   402  			t.Fatalf("failed to insert easy chain: %v", err)
   403  		}
   404  		if _, err := blockchain.InsertChain(diffBlocks); err != nil {
   405  			t.Fatalf("failed to insert difficult chain: %v", err)
   406  		}
   407  	} else {
   408  		easyHeaders := make([]*types.Header, len(easyBlocks))
   409  		for i, block := range easyBlocks {
   410  			easyHeaders[i] = block.Header()
   411  		}
   412  		diffHeaders := make([]*types.Header, len(diffBlocks))
   413  		for i, block := range diffBlocks {
   414  			diffHeaders[i] = block.Header()
   415  		}
   416  		if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil {
   417  			t.Fatalf("failed to insert easy chain: %v", err)
   418  		}
   419  		if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil {
   420  			t.Fatalf("failed to insert difficult chain: %v", err)
   421  		}
   422  	}
   423  //检查链条是否为有效的数字和链接方式
   424  	if full {
   425  		prev := blockchain.CurrentBlock()
   426  		for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) {
   427  			if prev.ParentHash() != block.Hash() {
   428  				t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash())
   429  			}
   430  		}
   431  	} else {
   432  		prev := blockchain.CurrentHeader()
   433  		for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) {
   434  			if prev.ParentHash != header.Hash() {
   435  				t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash())
   436  			}
   437  		}
   438  	}
   439  //确保链条的总难度是正确的。
   440  	want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td))
   441  	if full {
   442  		if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 {
   443  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   444  		}
   445  	} else {
   446  		if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 {
   447  			t.Errorf("total difficulty mismatch: have %v, want %v", have, want)
   448  		}
   449  	}
   450  }
   451  
   452  //测试插入函数是否检测禁止的哈希。
   453  func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) }
   454  func TestBadBlockHashes(t *testing.T)  { testBadHashes(t, true) }
   455  
   456  func testBadHashes(t *testing.T, full bool) {
   457  //创建原始链和数据库
   458  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   459  	if err != nil {
   460  		t.Fatalf("failed to create pristine chain: %v", err)
   461  	}
   462  	defer blockchain.Stop()
   463  
   464  //创建链,禁止散列并尝试导入
   465  	if full {
   466  		blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10)
   467  
   468  		BadHashes[blocks[2].Header().Hash()] = true
   469  		defer func() { delete(BadHashes, blocks[2].Header().Hash()) }()
   470  
   471  		_, err = blockchain.InsertChain(blocks)
   472  	} else {
   473  		headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10)
   474  
   475  		BadHashes[headers[2].Hash()] = true
   476  		defer func() { delete(BadHashes, headers[2].Hash()) }()
   477  
   478  		_, err = blockchain.InsertHeaderChain(headers, 1)
   479  	}
   480  	if err != ErrBlacklistedHash {
   481  		t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash)
   482  	}
   483  }
   484  
   485  //测试在引导时检测到错误的哈希,并将链回滚到
   486  //坏哈希前的良好状态。
   487  func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) }
   488  func TestReorgBadBlockHashes(t *testing.T)  { testReorgBadHashes(t, true) }
   489  
   490  func testReorgBadHashes(t *testing.T, full bool) {
   491  //创建原始链和数据库
   492  	db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   493  	if err != nil {
   494  		t.Fatalf("failed to create pristine chain: %v", err)
   495  	}
   496  //创建一个链,然后导入和禁止
   497  	headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10)
   498  	blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10)
   499  
   500  	if full {
   501  		if _, err = blockchain.InsertChain(blocks); err != nil {
   502  			t.Errorf("failed to import blocks: %v", err)
   503  		}
   504  		if blockchain.CurrentBlock().Hash() != blocks[3].Hash() {
   505  			t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash())
   506  		}
   507  		BadHashes[blocks[3].Header().Hash()] = true
   508  		defer func() { delete(BadHashes, blocks[3].Header().Hash()) }()
   509  	} else {
   510  		if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil {
   511  			t.Errorf("failed to import headers: %v", err)
   512  		}
   513  		if blockchain.CurrentHeader().Hash() != headers[3].Hash() {
   514  			t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash())
   515  		}
   516  		BadHashes[headers[3].Hash()] = true
   517  		defer func() { delete(BadHashes, headers[3].Hash()) }()
   518  	}
   519  	blockchain.Stop()
   520  
   521  //创建一个新的区块链并检查它是否回滚状态。
   522  	ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil)
   523  	if err != nil {
   524  		t.Fatalf("failed to create new chain manager: %v", err)
   525  	}
   526  	if full {
   527  		if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() {
   528  			t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash())
   529  		}
   530  		if blocks[2].Header().GasLimit != ncm.GasLimit() {
   531  			t.Errorf("last  block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit)
   532  		}
   533  	} else {
   534  		if ncm.CurrentHeader().Hash() != headers[2].Hash() {
   535  			t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash())
   536  		}
   537  	}
   538  	ncm.Stop()
   539  }
   540  
   541  //在包含无效nonce的实体的面上测试链插入。
   542  func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) }
   543  func TestBlocksInsertNonceError(t *testing.T)  { testInsertNonceError(t, true) }
   544  
   545  func testInsertNonceError(t *testing.T, full bool) {
   546  	for i := 1; i < 25 && !t.Failed(); i++ {
   547  //创建原始链和数据库
   548  		db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full)
   549  		if err != nil {
   550  			t.Fatalf("failed to create pristine chain: %v", err)
   551  		}
   552  		defer blockchain.Stop()
   553  
   554  //创建并插入带有失败的nonce的链
   555  		var (
   556  			failAt  int
   557  			failRes int
   558  			failNum uint64
   559  		)
   560  		if full {
   561  			blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0)
   562  
   563  			failAt = rand.Int() % len(blocks)
   564  			failNum = blocks[failAt].NumberU64()
   565  
   566  			blockchain.engine = ethash.NewFakeFailer(failNum)
   567  			failRes, err = blockchain.InsertChain(blocks)
   568  		} else {
   569  			headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0)
   570  
   571  			failAt = rand.Int() % len(headers)
   572  			failNum = headers[failAt].Number.Uint64()
   573  
   574  			blockchain.engine = ethash.NewFakeFailer(failNum)
   575  			blockchain.hc.engine = blockchain.engine
   576  			failRes, err = blockchain.InsertHeaderChain(headers, 1)
   577  		}
   578  //检查返回的错误是否指示故障
   579  		if failRes != failAt {
   580  			t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt)
   581  		}
   582  //检查插入故障块后的所有块
   583  		for j := 0; j < i-failAt; j++ {
   584  			if full {
   585  				if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil {
   586  					t.Errorf("test %d: invalid block in chain: %v", i, block)
   587  				}
   588  			} else {
   589  				if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil {
   590  					t.Errorf("test %d: invalid header in chain: %v", i, header)
   591  				}
   592  			}
   593  		}
   594  	}
   595  }
   596  
   597  //测试快速导入块链是否产生与
   598  //经典的全块处理。
   599  func TestFastVsFullChains(t *testing.T) {
   600  //配置并生成示例区块链
   601  	var (
   602  		gendb   = ethdb.NewMemDatabase()
   603  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   604  		address = crypto.PubkeyToAddress(key.PublicKey)
   605  		funds   = big.NewInt(1000000000)
   606  		gspec   = &Genesis{
   607  			Config: params.TestChainConfig,
   608  			Alloc:  GenesisAlloc{address: {Balance: funds}},
   609  		}
   610  		genesis = gspec.MustCommit(gendb)
   611  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   612  	)
   613  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) {
   614  		block.SetCoinbase(common.Address{0x00})
   615  
   616  //如果区块号是3的倍数,则向矿工发送一些奖金交易。
   617  		if i%3 == 2 {
   618  			for j := 0; j < i%4+1; j++ {
   619  				tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key)
   620  				if err != nil {
   621  					panic(err)
   622  				}
   623  				block.AddTx(tx)
   624  			}
   625  		}
   626  //如果区块编号是5的倍数,则在区块中添加一些奖金叔叔。
   627  		if i%5 == 5 {
   628  			block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))})
   629  		}
   630  	})
   631  //将链作为比较基准的存档节点导入
   632  	archiveDb := ethdb.NewMemDatabase()
   633  	gspec.MustCommit(archiveDb)
   634  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   635  	defer archive.Stop()
   636  
   637  	if n, err := archive.InsertChain(blocks); err != nil {
   638  		t.Fatalf("failed to process block %d: %v", n, err)
   639  	}
   640  //将链快速导入为要测试的非存档节点
   641  	fastDb := ethdb.NewMemDatabase()
   642  	gspec.MustCommit(fastDb)
   643  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   644  	defer fast.Stop()
   645  
   646  	headers := make([]*types.Header, len(blocks))
   647  	for i, block := range blocks {
   648  		headers[i] = block.Header()
   649  	}
   650  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   651  		t.Fatalf("failed to insert header %d: %v", n, err)
   652  	}
   653  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   654  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   655  	}
   656  //遍历所有链数据组件,并交叉引用
   657  	for i := 0; i < len(blocks); i++ {
   658  		num, hash := blocks[i].NumberU64(), blocks[i].Hash()
   659  
   660  		if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 {
   661  			t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd)
   662  		}
   663  		if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() {
   664  			t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader)
   665  		}
   666  		if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() {
   667  			t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock)
   668  		} else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) {
   669  			t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions())
   670  		} else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) {
   671  			t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles())
   672  		}
   673  		if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) {
   674  			t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts)
   675  		}
   676  	}
   677  //检查数据库之间的规范链是否相同
   678  	for i := 0; i < len(blocks)+1; i++ {
   679  		if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash {
   680  			t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash)
   681  		}
   682  	}
   683  }
   684  
   685  //测试各种导入方法是否将链头指针移动到正确的
   686  //位置。
   687  func TestLightVsFastVsFullChainHeads(t *testing.T) {
   688  //配置并生成示例区块链
   689  	var (
   690  		gendb   = ethdb.NewMemDatabase()
   691  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   692  		address = crypto.PubkeyToAddress(key.PublicKey)
   693  		funds   = big.NewInt(1000000000)
   694  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}}
   695  		genesis = gspec.MustCommit(gendb)
   696  	)
   697  	height := uint64(1024)
   698  	blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil)
   699  
   700  //配置子链以回滚
   701  	remove := []common.Hash{}
   702  	for _, block := range blocks[height/2:] {
   703  		remove = append(remove, block.Hash())
   704  	}
   705  //创建一个小断言方法来检查三个头
   706  	assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) {
   707  		if num := chain.CurrentBlock().NumberU64(); num != block {
   708  			t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block)
   709  		}
   710  		if num := chain.CurrentFastBlock().NumberU64(); num != fast {
   711  			t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast)
   712  		}
   713  		if num := chain.CurrentHeader().Number.Uint64(); num != header {
   714  			t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header)
   715  		}
   716  	}
   717  //将链作为存档节点导入,并确保更新所有指针
   718  	archiveDb := ethdb.NewMemDatabase()
   719  	gspec.MustCommit(archiveDb)
   720  
   721  	archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   722  	if n, err := archive.InsertChain(blocks); err != nil {
   723  		t.Fatalf("failed to process block %d: %v", n, err)
   724  	}
   725  	defer archive.Stop()
   726  
   727  	assert(t, "archive", archive, height, height, height)
   728  	archive.Rollback(remove)
   729  	assert(t, "archive", archive, height/2, height/2, height/2)
   730  
   731  //将链作为非存档节点导入,并确保更新所有指针
   732  	fastDb := ethdb.NewMemDatabase()
   733  	gspec.MustCommit(fastDb)
   734  	fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   735  	defer fast.Stop()
   736  
   737  	headers := make([]*types.Header, len(blocks))
   738  	for i, block := range blocks {
   739  		headers[i] = block.Header()
   740  	}
   741  	if n, err := fast.InsertHeaderChain(headers, 1); err != nil {
   742  		t.Fatalf("failed to insert header %d: %v", n, err)
   743  	}
   744  	if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil {
   745  		t.Fatalf("failed to insert receipt %d: %v", n, err)
   746  	}
   747  	assert(t, "fast", fast, height, height, 0)
   748  	fast.Rollback(remove)
   749  	assert(t, "fast", fast, height/2, height/2, 0)
   750  
   751  //将链作为轻型节点导入,并确保更新所有指针
   752  	lightDb := ethdb.NewMemDatabase()
   753  	gspec.MustCommit(lightDb)
   754  
   755  	light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   756  	if n, err := light.InsertHeaderChain(headers, 1); err != nil {
   757  		t.Fatalf("failed to insert header %d: %v", n, err)
   758  	}
   759  	defer light.Stop()
   760  
   761  	assert(t, "light", light, height, 0, 0)
   762  	light.Rollback(remove)
   763  	assert(t, "light", light, height/2, 0, 0)
   764  }
   765  
   766  //链重组处理事务移除和重新插入的测试。
   767  func TestChainTxReorgs(t *testing.T) {
   768  	var (
   769  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   770  		key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
   771  		key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
   772  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   773  		addr2   = crypto.PubkeyToAddress(key2.PublicKey)
   774  		addr3   = crypto.PubkeyToAddress(key3.PublicKey)
   775  		db      = ethdb.NewMemDatabase()
   776  		gspec   = &Genesis{
   777  			Config:   params.TestChainConfig,
   778  			GasLimit: 3141592,
   779  			Alloc: GenesisAlloc{
   780  				addr1: {Balance: big.NewInt(1000000)},
   781  				addr2: {Balance: big.NewInt(1000000)},
   782  				addr3: {Balance: big.NewInt(1000000)},
   783  			},
   784  		}
   785  		genesis = gspec.MustCommit(db)
   786  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   787  	)
   788  
   789  //创建链之间共享的两个事务:
   790  //-延期:在分叉链的后一个块中包含事务
   791  //-交换:在分叉链中同一个块编号处包含的事务
   792  	postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   793  	swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1)
   794  
   795  //创建将由分叉链删除的两个事务:
   796  //-pastdrop:从上一个块追溯删除的事务
   797  //-freshdrop:事务正好在检测到REORG的块上删除
   798  	var pastDrop, freshDrop *types.Transaction
   799  
   800  //创建将添加到分叉链中的三个事务:
   801  //-pastadd:在检测到重组之前添加的事务
   802  //-freshadd:在检测到REORG的确切块处添加的事务
   803  //-futureread:在REORG完成后添加的事务
   804  	var pastAdd, freshAdd, futureAdd *types.Transaction
   805  
   806  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {
   807  		switch i {
   808  		case 0:
   809  			pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   810  
   811  gen.AddTx(pastDrop)  //此事务将从拆分点下方放到分叉中。
   812  gen.AddTx(postponed) //此交易将推迟到fork的block 3
   813  
   814  		case 2:
   815  			freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2)
   816  
   817  gen.AddTx(freshDrop) //此事务将从拆分点完全删除到分叉中。
   818  gen.AddTx(swapped)   //此事务将在准确的高度交换出去
   819  
   820  gen.OffsetTime(9) //降低块难度以模拟较弱的链
   821  		}
   822  	})
   823  //导入链。这将运行所有块验证规则。
   824  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   825  	if i, err := blockchain.InsertChain(chain); err != nil {
   826  		t.Fatalf("failed to insert original chain[%d]: %v", i, err)
   827  	}
   828  	defer blockchain.Stop()
   829  
   830  //覆盖旧链
   831  	chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) {
   832  		switch i {
   833  		case 0:
   834  			pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   835  gen.AddTx(pastAdd) //此事务需要在REORG期间注入
   836  
   837  		case 2:
   838  gen.AddTx(postponed) //此交易从原始链中的块1推迟。
   839  gen.AddTx(swapped)   //此交易是从原始链中的确切当前点交换的
   840  
   841  			freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   842  gen.AddTx(freshAdd) //此事务将在REORG时完全添加
   843  
   844  		case 3:
   845  			futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3)
   846  gen.AddTx(futureAdd) //此事务将在完全重新排序后添加
   847  		}
   848  	})
   849  	if _, err := blockchain.InsertChain(chain); err != nil {
   850  		t.Fatalf("failed to insert forked chain: %v", err)
   851  	}
   852  
   853  //移除TX
   854  	for i, tx := range (types.Transactions{pastDrop, freshDrop}) {
   855  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
   856  			t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
   857  		}
   858  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil {
   859  			t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
   860  		}
   861  	}
   862  //添加TX
   863  	for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) {
   864  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   865  			t.Errorf("add %d: expected tx to be found", i)
   866  		}
   867  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   868  			t.Errorf("add %d: expected receipt to be found", i)
   869  		}
   870  	}
   871  //共享TX
   872  	for i, tx := range (types.Transactions{postponed, swapped}) {
   873  		if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
   874  			t.Errorf("share %d: expected tx to be found", i)
   875  		}
   876  		if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil {
   877  			t.Errorf("share %d: expected receipt to be found", i)
   878  		}
   879  	}
   880  }
   881  
   882  func TestLogReorgs(t *testing.T) {
   883  
   884  	var (
   885  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   886  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   887  		db      = ethdb.NewMemDatabase()
   888  //此代码生成日志
   889  		code    = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00")
   890  		gspec   = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}}
   891  		genesis = gspec.MustCommit(db)
   892  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   893  	)
   894  
   895  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   896  	defer blockchain.Stop()
   897  
   898  	rmLogsCh := make(chan RemovedLogsEvent)
   899  	blockchain.SubscribeRemovedLogsEvent(rmLogsCh)
   900  	chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) {
   901  		if i == 1 {
   902  			tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1)
   903  			if err != nil {
   904  				t.Fatalf("failed to create tx: %v", err)
   905  			}
   906  			gen.AddTx(tx)
   907  		}
   908  	})
   909  	if _, err := blockchain.InsertChain(chain); err != nil {
   910  		t.Fatalf("failed to insert chain: %v", err)
   911  	}
   912  
   913  	chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   914  	if _, err := blockchain.InsertChain(chain); err != nil {
   915  		t.Fatalf("failed to insert forked chain: %v", err)
   916  	}
   917  
   918  	timeout := time.NewTimer(1 * time.Second)
   919  	select {
   920  	case ev := <-rmLogsCh:
   921  		if len(ev.Logs) == 0 {
   922  			t.Error("expected logs")
   923  		}
   924  	case <-timeout.C:
   925  		t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.")
   926  	}
   927  }
   928  
   929  func TestReorgSideEvent(t *testing.T) {
   930  	var (
   931  		db      = ethdb.NewMemDatabase()
   932  		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   933  		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
   934  		gspec   = &Genesis{
   935  			Config: params.TestChainConfig,
   936  			Alloc:  GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}},
   937  		}
   938  		genesis = gspec.MustCommit(db)
   939  		signer  = types.NewEIP155Signer(gspec.Config.ChainID)
   940  	)
   941  
   942  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
   943  	defer blockchain.Stop()
   944  
   945  	chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {})
   946  	if _, err := blockchain.InsertChain(chain); err != nil {
   947  		t.Fatalf("failed to insert chain: %v", err)
   948  	}
   949  
   950  	replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) {
   951  		tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1)
   952  		if i == 2 {
   953  			gen.OffsetTime(-9)
   954  		}
   955  		if err != nil {
   956  			t.Fatalf("failed to create tx: %v", err)
   957  		}
   958  		gen.AddTx(tx)
   959  	})
   960  	chainSideCh := make(chan ChainSideEvent, 64)
   961  	blockchain.SubscribeChainSideEvent(chainSideCh)
   962  	if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
   963  		t.Fatalf("failed to insert chain: %v", err)
   964  	}
   965  
   966  //第二链的前两个区块被考虑了一小段时间。
   967  //侧链,因为在这一点上,第一个被认为是
   968  //较重的链。
   969  	expectedSideHashes := map[common.Hash]bool{
   970  		replacementBlocks[0].Hash(): true,
   971  		replacementBlocks[1].Hash(): true,
   972  		chain[0].Hash():             true,
   973  		chain[1].Hash():             true,
   974  		chain[2].Hash():             true,
   975  	}
   976  
   977  	i := 0
   978  
   979  	const timeoutDura = 10 * time.Second
   980  	timeout := time.NewTimer(timeoutDura)
   981  done:
   982  	for {
   983  		select {
   984  		case ev := <-chainSideCh:
   985  			block := ev.Block
   986  			if _, ok := expectedSideHashes[block.Hash()]; !ok {
   987  				t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
   988  			}
   989  			i++
   990  
   991  			if i == len(expectedSideHashes) {
   992  				timeout.Stop()
   993  
   994  				break done
   995  			}
   996  			timeout.Reset(timeoutDura)
   997  
   998  		case <-timeout.C:
   999  			t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
  1000  		}
  1001  	}
  1002  
  1003  //确保不再触发事件
  1004  	select {
  1005  	case e := <-chainSideCh:
  1006  		t.Errorf("unexpected event fired: %v", e)
  1007  	case <-time.After(250 * time.Millisecond):
  1008  	}
  1009  
  1010  }
  1011  
  1012  //测试在链插入期间是否可以从数据库中提取规范块。
  1013  func TestCanonicalBlockRetrieval(t *testing.T) {
  1014  	_, blockchain, err := newCanonical(ethash.NewFaker(), 0, true)
  1015  	if err != nil {
  1016  		t.Fatalf("failed to create pristine chain: %v", err)
  1017  	}
  1018  	defer blockchain.Stop()
  1019  
  1020  	chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {})
  1021  
  1022  	var pend sync.WaitGroup
  1023  	pend.Add(len(chain))
  1024  
  1025  	for i := range chain {
  1026  		go func(block *types.Block) {
  1027  			defer pend.Done()
  1028  
  1029  //尝试通过其规范哈希检索块,并查看是否可以检索块数据。
  1030  			for {
  1031  				ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64())
  1032  				if ch == (common.Hash{}) {
  1033  continue //正忙等待规范哈希被写入
  1034  				}
  1035  				if ch != block.Hash() {
  1036  					t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
  1037  				}
  1038  				fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
  1039  				if fb == nil {
  1040  					t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
  1041  				}
  1042  				if fb.Hash() != block.Hash() {
  1043  					t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
  1044  				}
  1045  				return
  1046  			}
  1047  		}(chain[i])
  1048  
  1049  		if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil {
  1050  			t.Fatalf("failed to insert block %d: %v", i, err)
  1051  		}
  1052  	}
  1053  	pend.Wait()
  1054  }
  1055  
  1056  func TestEIP155Transition(t *testing.T) {
  1057  //配置并生成示例区块链
  1058  	var (
  1059  		db         = ethdb.NewMemDatabase()
  1060  		key, _     = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1061  		address    = crypto.PubkeyToAddress(key.PublicKey)
  1062  		funds      = big.NewInt(1000000000)
  1063  		deleteAddr = common.Address{1}
  1064  		gspec      = &Genesis{
  1065  			Config: &params.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)},
  1066  			Alloc:  GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}},
  1067  		}
  1068  		genesis = gspec.MustCommit(db)
  1069  	)
  1070  
  1071  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1072  	defer blockchain.Stop()
  1073  
  1074  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1075  		var (
  1076  			tx      *types.Transaction
  1077  			err     error
  1078  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1079  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1080  			}
  1081  		)
  1082  		switch i {
  1083  		case 0:
  1084  			tx, err = basicTx(types.HomesteadSigner{})
  1085  			if err != nil {
  1086  				t.Fatal(err)
  1087  			}
  1088  			block.AddTx(tx)
  1089  		case 2:
  1090  			tx, err = basicTx(types.HomesteadSigner{})
  1091  			if err != nil {
  1092  				t.Fatal(err)
  1093  			}
  1094  			block.AddTx(tx)
  1095  
  1096  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1097  			if err != nil {
  1098  				t.Fatal(err)
  1099  			}
  1100  			block.AddTx(tx)
  1101  		case 3:
  1102  			tx, err = basicTx(types.HomesteadSigner{})
  1103  			if err != nil {
  1104  				t.Fatal(err)
  1105  			}
  1106  			block.AddTx(tx)
  1107  
  1108  			tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID))
  1109  			if err != nil {
  1110  				t.Fatal(err)
  1111  			}
  1112  			block.AddTx(tx)
  1113  		}
  1114  	})
  1115  
  1116  	if _, err := blockchain.InsertChain(blocks); err != nil {
  1117  		t.Fatal(err)
  1118  	}
  1119  	block := blockchain.GetBlockByNumber(1)
  1120  	if block.Transactions()[0].Protected() {
  1121  		t.Error("Expected block[0].txs[0] to not be replay protected")
  1122  	}
  1123  
  1124  	block = blockchain.GetBlockByNumber(3)
  1125  	if block.Transactions()[0].Protected() {
  1126  		t.Error("Expected block[3].txs[0] to not be replay protected")
  1127  	}
  1128  	if !block.Transactions()[1].Protected() {
  1129  		t.Error("Expected block[3].txs[1] to be replay protected")
  1130  	}
  1131  	if _, err := blockchain.InsertChain(blocks[4:]); err != nil {
  1132  		t.Fatal(err)
  1133  	}
  1134  
  1135  //生成无效的链ID事务
  1136  	config := &params.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}
  1137  	blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
  1138  		var (
  1139  			tx      *types.Transaction
  1140  			err     error
  1141  			basicTx = func(signer types.Signer) (*types.Transaction, error) {
  1142  				return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1143  			}
  1144  		)
  1145  		if i == 0 {
  1146  			tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2)))
  1147  			if err != nil {
  1148  				t.Fatal(err)
  1149  			}
  1150  			block.AddTx(tx)
  1151  		}
  1152  	})
  1153  	_, err := blockchain.InsertChain(blocks)
  1154  	if err != types.ErrInvalidChainId {
  1155  		t.Error("expected error:", types.ErrInvalidChainId)
  1156  	}
  1157  }
  1158  
  1159  func TestEIP161AccountRemoval(t *testing.T) {
  1160  //配置并生成示例区块链
  1161  	var (
  1162  		db      = ethdb.NewMemDatabase()
  1163  		key, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1164  		address = crypto.PubkeyToAddress(key.PublicKey)
  1165  		funds   = big.NewInt(1000000000)
  1166  		theAddr = common.Address{1}
  1167  		gspec   = &Genesis{
  1168  			Config: &params.ChainConfig{
  1169  				ChainID:        big.NewInt(1),
  1170  				HomesteadBlock: new(big.Int),
  1171  				EIP155Block:    new(big.Int),
  1172  				EIP158Block:    big.NewInt(2),
  1173  			},
  1174  			Alloc: GenesisAlloc{address: {Balance: funds}},
  1175  		}
  1176  		genesis = gspec.MustCommit(db)
  1177  	)
  1178  	blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil)
  1179  	defer blockchain.Stop()
  1180  
  1181  	blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
  1182  		var (
  1183  			tx     *types.Transaction
  1184  			err    error
  1185  			signer = types.NewEIP155Signer(gspec.Config.ChainID)
  1186  		)
  1187  		switch i {
  1188  		case 0:
  1189  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1190  		case 1:
  1191  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1192  		case 2:
  1193  			tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key)
  1194  		}
  1195  		if err != nil {
  1196  			t.Fatal(err)
  1197  		}
  1198  		block.AddTx(tx)
  1199  	})
  1200  //账户必须存在于EIP 161之前
  1201  	if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil {
  1202  		t.Fatal(err)
  1203  	}
  1204  	if st, _ := blockchain.State(); !st.Exist(theAddr) {
  1205  		t.Error("expected account to exist")
  1206  	}
  1207  
  1208  //在EIP 161之后需要删除帐户
  1209  	if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil {
  1210  		t.Fatal(err)
  1211  	}
  1212  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1213  		t.Error("account should not exist")
  1214  	}
  1215  
  1216  //不能在EIP 161后创建帐户库
  1217  	if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil {
  1218  		t.Fatal(err)
  1219  	}
  1220  	if st, _ := blockchain.State(); st.Exist(theAddr) {
  1221  		t.Error("account should not exist")
  1222  	}
  1223  }
  1224  
  1225  //这是一个回归测试(也就是说,尽管很奇怪,但永远不要删除它),它
  1226  //测试在奇怪的重组条件下,区块链及其内部头段-
  1227  //链返回相同的最新块/头。
  1228  //
  1229  //https://github.com/ethereum/go-ethereum/pull/15941
  1230  func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
  1231  //生成规范链作为主数据集
  1232  	engine := ethash.NewFaker()
  1233  
  1234  	db := ethdb.NewMemDatabase()
  1235  	genesis := new(Genesis).MustCommit(db)
  1236  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1237  
  1238  //生成一组分叉块,每侧都从规范链分叉
  1239  	forks := make([]*types.Block, len(blocks))
  1240  	for i := 0; i < len(forks); i++ {
  1241  		parent := genesis
  1242  		if i > 0 {
  1243  			parent = blocks[i-1]
  1244  		}
  1245  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1246  		forks[i] = fork[0]
  1247  	}
  1248  //并排导入规范链和叉链,验证当前块
  1249  //和当前标题一致性
  1250  	diskdb := ethdb.NewMemDatabase()
  1251  	new(Genesis).MustCommit(diskdb)
  1252  
  1253  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1254  	if err != nil {
  1255  		t.Fatalf("failed to create tester chain: %v", err)
  1256  	}
  1257  	for i := 0; i < len(blocks); i++ {
  1258  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1259  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1260  		}
  1261  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1262  			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])
  1263  		}
  1264  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1265  			t.Fatalf(" fork %d: failed to insert into chain: %v", i, err)
  1266  		}
  1267  		if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() {
  1268  			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])
  1269  		}
  1270  	}
  1271  }
  1272  
  1273  //测试导入小型侧叉不会在trie数据库中留下垃圾
  1274  //缓存(最终会导致内存问题)。
  1275  func TestTrieForkGC(t *testing.T) {
  1276  //生成规范链作为主数据集
  1277  	engine := ethash.NewFaker()
  1278  
  1279  	db := ethdb.NewMemDatabase()
  1280  	genesis := new(Genesis).MustCommit(db)
  1281  	blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1282  
  1283  //生成一组分叉块,每侧都从规范链分叉
  1284  	forks := make([]*types.Block, len(blocks))
  1285  	for i := 0; i < len(forks); i++ {
  1286  		parent := genesis
  1287  		if i > 0 {
  1288  			parent = blocks[i-1]
  1289  		}
  1290  		fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1291  		forks[i] = fork[0]
  1292  	}
  1293  //并排导入规范链和分叉链,强制trie缓存同时缓存
  1294  	diskdb := ethdb.NewMemDatabase()
  1295  	new(Genesis).MustCommit(diskdb)
  1296  
  1297  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1298  	if err != nil {
  1299  		t.Fatalf("failed to create tester chain: %v", err)
  1300  	}
  1301  	for i := 0; i < len(blocks); i++ {
  1302  		if _, err := chain.InsertChain(blocks[i : i+1]); err != nil {
  1303  			t.Fatalf("block %d: failed to insert into chain: %v", i, err)
  1304  		}
  1305  		if _, err := chain.InsertChain(forks[i : i+1]); err != nil {
  1306  			t.Fatalf("fork %d: failed to insert into chain: %v", i, err)
  1307  		}
  1308  	}
  1309  //取消引用所有最近的尝试,并确保没有留下过去的trie
  1310  	for i := 0; i < triesInMemory; i++ {
  1311  		chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root())
  1312  		chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root())
  1313  	}
  1314  	if len(chain.stateCache.TrieDB().Nodes()) > 0 {
  1315  		t.Fatalf("stale tries still alive after garbase collection")
  1316  	}
  1317  }
  1318  
  1319  //即使状态与
  1320  //分叉点不再可用。
  1321  func TestLargeReorgTrieGC(t *testing.T) {
  1322  //生成原始的公共链段和两个竞争分支
  1323  	engine := ethash.NewFaker()
  1324  
  1325  	db := ethdb.NewMemDatabase()
  1326  	genesis := new(Genesis).MustCommit(db)
  1327  
  1328  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
  1329  	original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) })
  1330  	competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) })
  1331  
  1332  //导入共享链和原始规范链
  1333  	diskdb := ethdb.NewMemDatabase()
  1334  	new(Genesis).MustCommit(diskdb)
  1335  
  1336  	chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1337  	if err != nil {
  1338  		t.Fatalf("failed to create tester chain: %v", err)
  1339  	}
  1340  	if _, err := chain.InsertChain(shared); err != nil {
  1341  		t.Fatalf("failed to insert shared chain: %v", err)
  1342  	}
  1343  	if _, err := chain.InsertChain(original); err != nil {
  1344  		t.Fatalf("failed to insert original chain: %v", err)
  1345  	}
  1346  //确保修剪掉与分叉点关联的状态
  1347  	if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil {
  1348  		t.Fatalf("common-but-old ancestor still cache")
  1349  	}
  1350  //在不超过canonical的td的情况下导入竞争对手链并确保
  1351  //我们没有处理任何块(防止恶意块)
  1352  	if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil {
  1353  		t.Fatalf("failed to insert competitor chain: %v", err)
  1354  	}
  1355  	for i, block := range competitor[:len(competitor)-2] {
  1356  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1357  			t.Fatalf("competitor %d: low TD chain became processed", i)
  1358  		}
  1359  	}
  1360  //导入竞争对手链的负责人,触发REORG并确保
  1361  //成功地重新处理所有隐藏的块。
  1362  	if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil {
  1363  		t.Fatalf("failed to finalize competitor chain: %v", err)
  1364  	}
  1365  	for i, block := range competitor[:len(competitor)-triesInMemory] {
  1366  		if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil {
  1367  			t.Fatalf("competitor %d: competing chain state missing", i)
  1368  		}
  1369  	}
  1370  }
  1371  
  1372  //将价值转移到非现有账户的大型区块作为基准
  1373  func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) {
  1374  	var (
  1375  		signer          = types.HomesteadSigner{}
  1376  		testBankKey, _  = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
  1377  		testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey)
  1378  		bankFunds       = big.NewInt(100000000000000000)
  1379  		gspec           = Genesis{
  1380  			Config: params.TestChainConfig,
  1381  			Alloc: GenesisAlloc{
  1382  				testBankAddress: {Balance: bankFunds},
  1383  				common.HexToAddress("0xc0de"): {
  1384  					Code:    []byte{0x60, 0x01, 0x50},
  1385  					Balance: big.NewInt(0),
  1386  }, //推1,流行
  1387  			},
  1388  GasLimit: 100e6, //100米
  1389  		}
  1390  	)
  1391  //生成原始的公共链段和两个竞争分支
  1392  	engine := ethash.NewFaker()
  1393  	db := ethdb.NewMemDatabase()
  1394  	genesis := gspec.MustCommit(db)
  1395  
  1396  	blockGenerator := func(i int, block *BlockGen) {
  1397  		block.SetCoinbase(common.Address{1})
  1398  		for txi := 0; txi < numTxs; txi++ {
  1399  			uniq := uint64(i*numTxs + txi)
  1400  			recipient := recipientFn(uniq)
  1401  //收件人:=common.bigtoAddress(big.newint(0).setuint64(1337+uniq))
  1402  			tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey)
  1403  			if err != nil {
  1404  				b.Error(err)
  1405  			}
  1406  			block.AddTx(tx)
  1407  		}
  1408  	}
  1409  
  1410  	shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator)
  1411  	b.StopTimer()
  1412  	b.ResetTimer()
  1413  	for i := 0; i < b.N; i++ {
  1414  //导入共享链和原始规范链
  1415  		diskdb := ethdb.NewMemDatabase()
  1416  		gspec.MustCommit(diskdb)
  1417  
  1418  		chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil)
  1419  		if err != nil {
  1420  			b.Fatalf("failed to create tester chain: %v", err)
  1421  		}
  1422  		b.StartTimer()
  1423  		if _, err := chain.InsertChain(shared); err != nil {
  1424  			b.Fatalf("failed to insert shared chain: %v", err)
  1425  		}
  1426  		b.StopTimer()
  1427  		if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks {
  1428  			b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got)
  1429  
  1430  		}
  1431  	}
  1432  }
  1433  func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) {
  1434  	var (
  1435  		numTxs    = 1000
  1436  		numBlocks = 1
  1437  	)
  1438  
  1439  	recipientFn := func(nonce uint64) common.Address {
  1440  		return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce))
  1441  	}
  1442  	dataFn := func(nonce uint64) []byte {
  1443  		return nil
  1444  	}
  1445  
  1446  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1447  }
  1448  func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) {
  1449  	var (
  1450  		numTxs    = 1000
  1451  		numBlocks = 1
  1452  	)
  1453  	b.StopTimer()
  1454  	b.ResetTimer()
  1455  
  1456  	recipientFn := func(nonce uint64) common.Address {
  1457  		return common.BigToAddress(big.NewInt(0).SetUint64(1337))
  1458  	}
  1459  	dataFn := func(nonce uint64) []byte {
  1460  		return nil
  1461  	}
  1462  
  1463  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1464  }
  1465  func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
  1466  	var (
  1467  		numTxs    = 1000
  1468  		numBlocks = 1
  1469  	)
  1470  	b.StopTimer()
  1471  	b.ResetTimer()
  1472  
  1473  	recipientFn := func(nonce uint64) common.Address {
  1474  		return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de))
  1475  	}
  1476  	dataFn := func(nonce uint64) []byte {
  1477  		return nil
  1478  	}
  1479  
  1480  	benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn)
  1481  }
  1482