github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/blockchain_test.go (about)

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