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

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"math/big"
    21  	"testing"
    22  
    23  	"github.com/ethereumproject/ethash"
    24  
    25  	"github.com/ethereumproject/go-ethereum/common"
    26  	"github.com/ethereumproject/go-ethereum/core/state"
    27  	"github.com/ethereumproject/go-ethereum/core/types"
    28  	"github.com/ethereumproject/go-ethereum/core/vm"
    29  	"github.com/ethereumproject/go-ethereum/ethdb"
    30  	"github.com/ethereumproject/go-ethereum/event"
    31  )
    32  
    33  func testChainConfig() *ChainConfig {
    34  	return &ChainConfig{
    35  		Forks: []*Fork{
    36  			{
    37  				Name:  "Homestead",
    38  				Block: big.NewInt(0),
    39  				Features: []*ForkFeature{
    40  					{
    41  						ID: "gastable",
    42  						Options: ChainFeatureConfigOptions{
    43  							"type": "homestead",
    44  						},
    45  					},
    46  					{
    47  						ID: "difficulty",
    48  						Options: ChainFeatureConfigOptions{
    49  							"type": "homestead",
    50  						},
    51  					},
    52  				},
    53  			},
    54  			{
    55  				Name:  "Diehard",
    56  				Block: big.NewInt(5),
    57  				Features: []*ForkFeature{
    58  					{
    59  						ID: "eip155",
    60  						Options: ChainFeatureConfigOptions{
    61  							"chainID": 62,
    62  						},
    63  					},
    64  					{ // ecip1010 bomb delay
    65  						ID: "gastable",
    66  						Options: ChainFeatureConfigOptions{
    67  							"type": "eip160",
    68  						},
    69  					},
    70  					{ // ecip1010 bomb delay
    71  						ID: "difficulty",
    72  						Options: ChainFeatureConfigOptions{
    73  							"type":   "ecip1010",
    74  							"length": 2000000,
    75  						},
    76  					},
    77  				},
    78  			},
    79  		},
    80  	}
    81  }
    82  
    83  func proc(t testing.TB) (Validator, *BlockChain) {
    84  	db, err := ethdb.NewMemDatabase()
    85  	if err != nil {
    86  		t.Fatal(err)
    87  	}
    88  	_, err = WriteGenesisBlock(db, DefaultConfigMorden.Genesis)
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  
    93  	pow, err := ethash.NewForTesting()
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  
    98  	var mux event.TypeMux
    99  	blockchain, err := NewBlockChain(db, testChainConfig(), pow, &mux)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	return blockchain.validator, blockchain
   104  }
   105  
   106  func TestNumber(t *testing.T) {
   107  	_, chain := proc(t)
   108  
   109  	statedb, err := state.New(chain.Genesis().Root(), state.NewDatabase(chain.chainDb))
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	header := makeHeader(chain.config, chain.Genesis(), statedb)
   114  	header.Number = big.NewInt(3)
   115  	cfg := testChainConfig()
   116  	err = ValidateHeader(cfg, nil, header, chain.Genesis().Header(), false, false)
   117  	if err != BlockNumberErr {
   118  		t.Errorf("expected block number error, got %q", err)
   119  	}
   120  
   121  	header = makeHeader(chain.config, chain.Genesis(), statedb)
   122  	err = ValidateHeader(cfg, nil, header, chain.Genesis().Header(), false, false)
   123  	if err == BlockNumberErr {
   124  		t.Errorf("didn't expect block number error")
   125  	}
   126  }
   127  
   128  func TestPutReceipt(t *testing.T) {
   129  	db, err := ethdb.NewMemDatabase()
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  
   134  	var addr common.Address
   135  	addr[0] = 1
   136  	var hash common.Hash
   137  	hash[0] = 2
   138  
   139  	receipt := new(types.Receipt)
   140  	receipt.Logs = vm.Logs{&vm.Log{
   141  		Address:     addr,
   142  		Topics:      []common.Hash{hash},
   143  		Data:        []byte("hi"),
   144  		BlockNumber: 42,
   145  		TxHash:      hash,
   146  		TxIndex:     0,
   147  		BlockHash:   hash,
   148  		Index:       0,
   149  	}}
   150  
   151  	WriteReceipts(db, types.Receipts{receipt})
   152  	receipt = GetReceipt(db, common.Hash{})
   153  	if receipt == nil {
   154  		t.Error("expected to get 1 receipt, got none.")
   155  	}
   156  }
   157  
   158  func TestDifficultyBombFreeze(t *testing.T) {
   159  	diehardBlock := big.NewInt(3000000)
   160  	var parentTime uint64
   161  
   162  	// 20 seconds, parent diff 7654414978364
   163  	parentTime = 1452838500
   164  	act := calcDifficultyDiehard(parentTime+20, parentTime, big.NewInt(7654414978364), diehardBlock)
   165  	exp := big.NewInt(7650945906507)
   166  	if exp.Cmp(act) != 0 {
   167  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   168  			exp, act, big.NewInt(0).Sub(act, exp))
   169  	}
   170  
   171  	// 5 seconds, parent diff 7654414978364
   172  	act = calcDifficultyDiehard(parentTime+5, parentTime, big.NewInt(7654414978364), diehardBlock)
   173  	exp = big.NewInt(7658420921133)
   174  	if exp.Cmp(act) != 0 {
   175  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   176  			exp, act, big.NewInt(0).Sub(act, exp))
   177  	}
   178  
   179  	// 80 seconds, parent diff 7654414978364
   180  	act = calcDifficultyDiehard(parentTime+80, parentTime, big.NewInt(7654414978364), diehardBlock)
   181  	exp = big.NewInt(7628520862629)
   182  	if exp.Cmp(act) != 0 {
   183  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   184  			exp, act, big.NewInt(0).Sub(act, exp))
   185  	}
   186  
   187  	// 76 seconds, parent diff 12657404717367
   188  	parentTime = 1469081721
   189  	act = calcDifficultyDiehard(parentTime+76, parentTime, big.NewInt(12657404717367), diehardBlock)
   190  	exp = big.NewInt(12620590912441)
   191  	if exp.Cmp(act) != 0 {
   192  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   193  			exp, act, big.NewInt(0).Sub(act, exp))
   194  	}
   195  
   196  	// 1 second, parent diff 12620590912441
   197  	parentTime = 1469164521
   198  	act = calcDifficultyDiehard(parentTime+1, parentTime, big.NewInt(12620590912441), diehardBlock)
   199  	exp = big.NewInt(12627021745803)
   200  	if exp.Cmp(act) != 0 {
   201  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   202  			exp, act, big.NewInt(0).Sub(act, exp))
   203  	}
   204  
   205  	// 10 seconds, parent diff 12627021745803
   206  	parentTime = 1469164522
   207  	act = calcDifficultyDiehard(parentTime+10, parentTime, big.NewInt(12627021745803), diehardBlock)
   208  	exp = big.NewInt(12627290181259)
   209  	if exp.Cmp(act) != 0 {
   210  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   211  			exp, act, big.NewInt(0).Sub(act, exp))
   212  	}
   213  
   214  }
   215  
   216  func TestDifficultyBombFreezeTestnet(t *testing.T) {
   217  	diehardBlock := big.NewInt(1915000)
   218  
   219  	act := calcDifficultyDiehard(1481895639, 1481850947, big.NewInt(28670444), diehardBlock)
   220  	exp := big.NewInt(27415615)
   221  	if exp.Cmp(act) != 0 {
   222  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   223  			exp, act, big.NewInt(0).Sub(act, exp))
   224  	}
   225  }
   226  
   227  func TestDifficultyBombExplode(t *testing.T) {
   228  	diehardBlock := big.NewInt(3000000)
   229  	explosionBlock := big.NewInt(5000000)
   230  
   231  	var parentTime uint64
   232  
   233  	// 6 seconds, blocks in 5m
   234  	num := big.NewInt(5000102)
   235  	parentTime = 1513175023
   236  	act := calcDifficultyExplosion(parentTime+6, parentTime, num, big.NewInt(22627021745803), diehardBlock, explosionBlock)
   237  	exp := big.NewInt(22638338531720)
   238  	if exp.Cmp(act) != 0 {
   239  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   240  			exp, act, big.NewInt(0).Sub(act, exp))
   241  	}
   242  
   243  	num = big.NewInt(5001105)
   244  	parentTime = 1513189406
   245  	act = calcDifficultyExplosion(parentTime+29, parentTime, num, big.NewInt(22727021745803), diehardBlock, explosionBlock)
   246  	exp = big.NewInt(22716193002673)
   247  	if exp.Cmp(act) != 0 {
   248  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   249  			exp, act, big.NewInt(0).Sub(act, exp))
   250  	}
   251  
   252  	num = big.NewInt(5100123)
   253  	parentTime = 1514609324
   254  	act = calcDifficultyExplosion(parentTime+41, parentTime, num, big.NewInt(22893437765583), diehardBlock, explosionBlock)
   255  	exp = big.NewInt(22860439327271)
   256  	if exp.Cmp(act) != 0 {
   257  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   258  			exp, act, big.NewInt(0).Sub(act, exp))
   259  	}
   260  
   261  	num = big.NewInt(6150001)
   262  	parentTime = 1529664575
   263  	act = calcDifficultyExplosion(parentTime+105, parentTime, num, big.NewInt(53134780363303), diehardBlock, explosionBlock)
   264  	exp = big.NewInt(53451033724425)
   265  	if exp.Cmp(act) != 0 {
   266  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   267  			exp, act, big.NewInt(0).Sub(act, exp))
   268  	}
   269  
   270  	num = big.NewInt(6550001)
   271  	parentTime = 1535431724
   272  	act = calcDifficultyExplosion(parentTime+60, parentTime, num, big.NewInt(82893437765583), diehardBlock, explosionBlock)
   273  	exp = big.NewInt(91487154230751)
   274  	if exp.Cmp(act) != 0 {
   275  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   276  			exp, act, big.NewInt(0).Sub(act, exp))
   277  	}
   278  
   279  	num = big.NewInt(7000000)
   280  	parentTime = 1535431724
   281  	act = calcDifficultyExplosion(parentTime+180, parentTime, num, big.NewInt(304334879167015), diehardBlock, explosionBlock)
   282  	exp = big.NewInt(583283638618965)
   283  	if exp.Cmp(act) != 0 {
   284  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   285  			exp, act, big.NewInt(0).Sub(act, exp))
   286  	}
   287  
   288  	num = big.NewInt(8000000)
   289  	parentTime = 1535431724
   290  	act = calcDifficultyExplosion(parentTime+420, parentTime, num, big.NewInt(78825323605416810), diehardBlock, explosionBlock)
   291  	exp = big.NewInt(365477653727918567)
   292  	if exp.Cmp(act) != 0 {
   293  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   294  			exp, act, big.NewInt(0).Sub(act, exp))
   295  	}
   296  
   297  	num = big.NewInt(9000000)
   298  	parentTime = 1535431724
   299  	act = calcDifficultyExplosion(parentTime+2040, parentTime, num, big.NewInt(288253236054168103), diehardBlock, explosionBlock)
   300  	exp = big.NewInt(0)
   301  	exp.SetString("295422224299015703633", 10)
   302  	if exp.Cmp(act) != 0 {
   303  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   304  			exp, act, big.NewInt(0).Sub(act, exp))
   305  	}
   306  }
   307  
   308  func TestDifficultyBombExplodeTestnet(t *testing.T) {
   309  	diehardBlock := big.NewInt(1915000)
   310  	explosionBlock := big.NewInt(3415000)
   311  
   312  	var parentTime uint64
   313  	parentTime = 1513175023
   314  	act := calcDifficultyExplosion(parentTime+20, parentTime, big.NewInt(5200000), big.NewInt(28670444), diehardBlock, explosionBlock)
   315  	exp := big.NewInt(34388394813)
   316  	if exp.Cmp(act) != 0 {
   317  		t.Errorf("Expected to have %d difficulty, got %d (difference: %d)",
   318  			exp, act, big.NewInt(0).Sub(act, exp))
   319  	}
   320  }
   321  
   322  // Compare expected difficulties on edges of forks.
   323  func TestCalcDifficulty1Mainnet(t *testing.T) {
   324  	config := DefaultConfigMainnet.ChainConfig
   325  
   326  	parentTime := uint64(1513175023)
   327  	time := parentTime + 20
   328  	parentDiff := big.NewInt(28670444)
   329  
   330  	dhB := config.ForkByName("Diehard").Block
   331  	if dhB == nil {
   332  		t.Error("missing Diehard fork block")
   333  	}
   334  
   335  	feat, dhFork, configured := config.GetFeature(dhB, "difficulty")
   336  	if !configured {
   337  		t.Errorf("difficulty not configured for diehard block: %v", dhB)
   338  	}
   339  	if val, ok := feat.GetString("type"); !ok || val != "ecip1010" {
   340  		t.Errorf("ecip1010 not configured as difficulty for diehard block: %v", dhB)
   341  	}
   342  	delay, ok := feat.GetBigInt("length")
   343  	if !ok {
   344  		t.Error("ecip1010 bomb delay length not configured")
   345  	}
   346  
   347  	// Paradise
   348  	defuseBlock := config.ForkByName("Defuse Difficulty Bomb").Block
   349  	if defuseBlock == nil {
   350  		t.Error("missing Defuse Difficulty Bomb fork block")
   351  	}
   352  
   353  	defuseFeat, _, defuseConfigured := config.GetFeature(defuseBlock, "difficulty")
   354  	if !defuseConfigured {
   355  		t.Errorf("difficulty not configured for Defuse Difficulty Bomb block: %v", dhB)
   356  	}
   357  	if val, ok := defuseFeat.GetString("type"); !ok || val != "defused" {
   358  		t.Errorf("diffusion not configured as difficulty for Defuse Difficulty Bomb block: %v", dhB)
   359  	}
   360  
   361  	explosionBlock := big.NewInt(0).Add(dhB, delay)
   362  
   363  	//parentBlocks to compare with expected equality
   364  	table := map[*big.Int]*big.Int{
   365  
   366  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-2)): calcDifficultyFrontier(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-2)), parentDiff),
   367  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-1)), parentDiff),
   368  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(0)), parentDiff),
   369  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(1)), parentDiff),
   370  
   371  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-2)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-2)), parentDiff),
   372  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-1)), parentDiff),
   373  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(0)), parentDiff),
   374  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(1)), parentDiff),
   375  
   376  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-2)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-2)), parentDiff),
   377  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-1)), parentDiff),
   378  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(0)), parentDiff),
   379  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(1)), parentDiff),
   380  
   381  		big.NewInt(0).Add(dhB, big.NewInt(-1)): calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 2999999
   382  		big.NewInt(0).Add(dhB, big.NewInt(0)):  calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 3000000
   383  		big.NewInt(0).Add(dhB, big.NewInt(1)):  calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 3000001
   384  		big.NewInt(-2).Add(dhB, delay):         calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 4999998
   385  
   386  		big.NewInt(-1).Add(dhB, delay): calcDifficultyExplosion(time, parentTime, big.NewInt(-1).Add(dhB, delay), parentDiff, dhFork.Block, explosionBlock), // 4999999
   387  		big.NewInt(0).Add(dhB, delay):  calcDifficultyExplosion(time, parentTime, big.NewInt(0).Add(dhB, delay), parentDiff, dhFork.Block, explosionBlock),  // 5000000
   388  		big.NewInt(1).Add(dhB, delay):  calcDifficultyExplosion(time, parentTime, big.NewInt(1).Add(dhB, delay), parentDiff, dhFork.Block, explosionBlock),  // 5000001
   389  
   390  		new(big.Int).Add(defuseBlock, big.NewInt(-1)): calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(-1)), parentDiff),
   391  		new(big.Int).Add(defuseBlock, big.NewInt(0)):  calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(0)), parentDiff),
   392  		new(big.Int).Add(defuseBlock, big.NewInt(1)):  calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(1)), parentDiff),
   393  
   394  		big.NewInt(10000000): calcDifficultyDefused(time, parentTime, big.NewInt(10000000), parentDiff),
   395  	}
   396  
   397  	for parentNum, expected := range table {
   398  		difficulty := CalcDifficulty(config, time, parentTime, parentNum, parentDiff)
   399  		if difficulty.Cmp(expected) != 0 {
   400  			t.Errorf("config: %v, got: %v, want: %v, with parentBlock: %v", "mainnet", difficulty, expected, parentNum)
   401  		}
   402  	}
   403  }
   404  
   405  // Compare expected difficulties on edges of forks.
   406  func TestCalcDifficulty1Morden(t *testing.T) {
   407  	config := DefaultConfigMainnet.ChainConfig
   408  
   409  	parentTime := uint64(1513175023)
   410  	time := parentTime + 20
   411  	parentDiff := big.NewInt(28670444)
   412  
   413  	dhB := config.ForkByName("Diehard").Block
   414  	if dhB == nil {
   415  		t.Error("missing Diehard fork block")
   416  	}
   417  
   418  	feat, dhFork, configured := config.GetFeature(dhB, "difficulty")
   419  	if !configured {
   420  		t.Errorf("difficulty not configured for diehard block: %v", dhB)
   421  	}
   422  	if val, ok := feat.GetString("type"); !ok || val != "ecip1010" {
   423  		t.Errorf("ecip1010 not configured as difficulty for diehard block: %v", dhB)
   424  	}
   425  
   426  	// Paradise
   427  	defuseBlock := config.ForkByName("Defuse Difficulty Bomb").Block
   428  	if defuseBlock == nil {
   429  		t.Error("missing Defuse Difficulty Bomb fork block")
   430  	}
   431  
   432  	defuseFeat, _, defuseConfigured := config.GetFeature(defuseBlock, "difficulty")
   433  	if !defuseConfigured {
   434  		t.Errorf("difficulty not configured for Defuse Difficulty Bomb block: %v", dhB)
   435  	}
   436  	if val, ok := defuseFeat.GetString("type"); !ok || val != "defused" {
   437  		t.Errorf("diffusion not configured as difficulty for Defuse Difficulty Bomb block: %v", dhB)
   438  	}
   439  
   440  	//parentBlocks to compare with expected equality
   441  	table := map[*big.Int]*big.Int{
   442  
   443  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-2)): calcDifficultyFrontier(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-2)), parentDiff),
   444  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(-1)), parentDiff),
   445  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(0)), parentDiff),
   446  		big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("Homestead").Block, big.NewInt(1)), parentDiff),
   447  
   448  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-2)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-2)), parentDiff),
   449  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(-1)), parentDiff),
   450  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(0)), parentDiff),
   451  		big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("The DAO Hard Fork").Block, big.NewInt(1)), parentDiff),
   452  
   453  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-2)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-2)), parentDiff),
   454  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-1)): calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(-1)), parentDiff),
   455  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(0)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(0)), parentDiff),
   456  		big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(1)):  calcDifficultyHomestead(time, parentTime, big.NewInt(0).Add(config.ForkByName("GasReprice").Block, big.NewInt(1)), parentDiff),
   457  
   458  		big.NewInt(0).Add(dhB, big.NewInt(-1)): calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 2999999
   459  		big.NewInt(0).Add(dhB, big.NewInt(0)):  calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 3000000
   460  		big.NewInt(0).Add(dhB, big.NewInt(1)):  calcDifficultyDiehard(time, parentTime, parentDiff, dhFork.Block), // 3000001
   461  
   462  		new(big.Int).Add(defuseBlock, big.NewInt(-1)): calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(-1)), parentDiff),
   463  		new(big.Int).Add(defuseBlock, big.NewInt(0)):  calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(0)), parentDiff),
   464  		new(big.Int).Add(defuseBlock, big.NewInt(1)):  calcDifficultyDefused(time, parentTime, new(big.Int).Add(defuseBlock, big.NewInt(1)), parentDiff),
   465  
   466  		big.NewInt(10000000): calcDifficultyDefused(time, parentTime, big.NewInt(10000000), parentDiff),
   467  	}
   468  
   469  	for parentNum, expected := range table {
   470  		difficulty := CalcDifficulty(config, time, parentTime, parentNum, parentDiff)
   471  		if difficulty.Cmp(expected) != 0 {
   472  			t.Errorf("config: %v, got: %v, want: %v, with parentBlock: %v", "mainnet", difficulty, expected, parentNum)
   473  		}
   474  	}
   475  }