github.com/tirogen/go-ethereum@v1.10.12-0.20221226051715-250cfede41b6/core/blockchain_test.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 "math/rand" 24 "os" 25 "sync" 26 "testing" 27 "time" 28 29 "github.com/tirogen/go-ethereum/common" 30 "github.com/tirogen/go-ethereum/common/math" 31 "github.com/tirogen/go-ethereum/consensus" 32 "github.com/tirogen/go-ethereum/consensus/beacon" 33 "github.com/tirogen/go-ethereum/consensus/ethash" 34 "github.com/tirogen/go-ethereum/core/rawdb" 35 "github.com/tirogen/go-ethereum/core/state" 36 "github.com/tirogen/go-ethereum/core/types" 37 "github.com/tirogen/go-ethereum/core/vm" 38 "github.com/tirogen/go-ethereum/crypto" 39 "github.com/tirogen/go-ethereum/eth/tracers/logger" 40 "github.com/tirogen/go-ethereum/ethdb" 41 "github.com/tirogen/go-ethereum/params" 42 "github.com/tirogen/go-ethereum/trie" 43 ) 44 45 // So we can deterministically seed different blockchains 46 var ( 47 canonicalSeed = 1 48 forkSeed = 2 49 ) 50 51 // newCanonical creates a chain database, and injects a deterministic canonical 52 // chain. Depending on the full flag, if creates either a full block chain or a 53 // header only chain. The database and genesis specification for block generation 54 // are also returned in case more test blocks are needed later. 55 func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *Genesis, *BlockChain, error) { 56 var ( 57 genesis = &Genesis{ 58 BaseFee: big.NewInt(params.InitialBaseFee), 59 Config: params.AllEthashProtocolChanges, 60 } 61 ) 62 // Initialize a fresh chain with only a genesis block 63 blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 64 65 // Create and inject the requested chain 66 if n == 0 { 67 return rawdb.NewMemoryDatabase(), genesis, blockchain, nil 68 } 69 if full { 70 // Full block-chain requested 71 genDb, blocks := makeBlockChainWithGenesis(genesis, n, engine, canonicalSeed) 72 _, err := blockchain.InsertChain(blocks) 73 return genDb, genesis, blockchain, err 74 } 75 // Header-only chain requested 76 genDb, headers := makeHeaderChainWithGenesis(genesis, n, engine, canonicalSeed) 77 _, err := blockchain.InsertHeaderChain(headers, 1) 78 return genDb, genesis, blockchain, err 79 } 80 81 func newGwei(n int64) *big.Int { 82 return new(big.Int).Mul(big.NewInt(n), big.NewInt(params.GWei)) 83 } 84 85 // Test fork of length N starting from block i 86 func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) { 87 // Copy old chain up to #i into a new db 88 genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full) 89 if err != nil { 90 t.Fatal("could not make new canonical in testFork", err) 91 } 92 defer blockchain2.Stop() 93 94 // Assert the chains have the same header/block at #i 95 var hash1, hash2 common.Hash 96 if full { 97 hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash() 98 hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash() 99 } else { 100 hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash() 101 hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash() 102 } 103 if hash1 != hash2 { 104 t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1) 105 } 106 // Extend the newly created chain 107 var ( 108 blockChainB []*types.Block 109 headerChainB []*types.Header 110 ) 111 if full { 112 blockChainB = makeBlockChain(blockchain2.chainConfig, blockchain2.CurrentBlock(), n, ethash.NewFaker(), genDb, forkSeed) 113 if _, err := blockchain2.InsertChain(blockChainB); err != nil { 114 t.Fatalf("failed to insert forking chain: %v", err) 115 } 116 } else { 117 headerChainB = makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed) 118 if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil { 119 t.Fatalf("failed to insert forking chain: %v", err) 120 } 121 } 122 // Sanity check that the forked chain can be imported into the original 123 var tdPre, tdPost *big.Int 124 125 if full { 126 cur := blockchain.CurrentBlock() 127 tdPre = blockchain.GetTd(cur.Hash(), cur.NumberU64()) 128 if err := testBlockChainImport(blockChainB, blockchain); err != nil { 129 t.Fatalf("failed to import forked block chain: %v", err) 130 } 131 last := blockChainB[len(blockChainB)-1] 132 tdPost = blockchain.GetTd(last.Hash(), last.NumberU64()) 133 } else { 134 cur := blockchain.CurrentHeader() 135 tdPre = blockchain.GetTd(cur.Hash(), cur.Number.Uint64()) 136 if err := testHeaderChainImport(headerChainB, blockchain); err != nil { 137 t.Fatalf("failed to import forked header chain: %v", err) 138 } 139 last := headerChainB[len(headerChainB)-1] 140 tdPost = blockchain.GetTd(last.Hash(), last.Number.Uint64()) 141 } 142 // Compare the total difficulties of the chains 143 comparator(tdPre, tdPost) 144 } 145 146 // testBlockChainImport tries to process a chain of blocks, writing them into 147 // the database if successful. 148 func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { 149 for _, block := range chain { 150 // Try and process the block 151 err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true) 152 if err == nil { 153 err = blockchain.validator.ValidateBody(block) 154 } 155 if err != nil { 156 if err == ErrKnownBlock { 157 continue 158 } 159 return err 160 } 161 statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil) 162 if err != nil { 163 return err 164 } 165 receipts, _, usedGas, err := blockchain.processor.Process(block, statedb, vm.Config{}) 166 if err != nil { 167 blockchain.reportBlock(block, receipts, err) 168 return err 169 } 170 err = blockchain.validator.ValidateState(block, statedb, receipts, usedGas) 171 if err != nil { 172 blockchain.reportBlock(block, receipts, err) 173 return err 174 } 175 176 blockchain.chainmu.MustLock() 177 rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTd(block.ParentHash(), block.NumberU64()-1))) 178 rawdb.WriteBlock(blockchain.db, block) 179 statedb.Commit(false) 180 blockchain.chainmu.Unlock() 181 } 182 return nil 183 } 184 185 // testHeaderChainImport tries to process a chain of header, writing them into 186 // the database if successful. 187 func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error { 188 for _, header := range chain { 189 // Try and validate the header 190 if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil { 191 return err 192 } 193 // Manually insert the header into the database, but don't reorganise (allows subsequent testing) 194 blockchain.chainmu.MustLock() 195 rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTd(header.ParentHash, header.Number.Uint64()-1))) 196 rawdb.WriteHeader(blockchain.db, header) 197 blockchain.chainmu.Unlock() 198 } 199 return nil 200 } 201 202 func TestLastBlock(t *testing.T) { 203 genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, true) 204 if err != nil { 205 t.Fatalf("failed to create pristine chain: %v", err) 206 } 207 defer blockchain.Stop() 208 209 blocks := makeBlockChain(blockchain.chainConfig, blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), genDb, 0) 210 if _, err := blockchain.InsertChain(blocks); err != nil { 211 t.Fatalf("Failed to insert block: %v", err) 212 } 213 if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) { 214 t.Fatalf("Write/Get HeadBlockHash failed") 215 } 216 } 217 218 // Test inserts the blocks/headers after the fork choice rule is changed. 219 // The chain is reorged to whatever specified. 220 func testInsertAfterMerge(t *testing.T, blockchain *BlockChain, i, n int, full bool) { 221 // Copy old chain up to #i into a new db 222 genDb, _, blockchain2, err := newCanonical(ethash.NewFaker(), i, full) 223 if err != nil { 224 t.Fatal("could not make new canonical in testFork", err) 225 } 226 defer blockchain2.Stop() 227 228 // Assert the chains have the same header/block at #i 229 var hash1, hash2 common.Hash 230 if full { 231 hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash() 232 hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash() 233 } else { 234 hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash() 235 hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash() 236 } 237 if hash1 != hash2 { 238 t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1) 239 } 240 241 // Extend the newly created chain 242 if full { 243 blockChainB := makeBlockChain(blockchain2.chainConfig, blockchain2.CurrentBlock(), n, ethash.NewFaker(), genDb, forkSeed) 244 if _, err := blockchain2.InsertChain(blockChainB); err != nil { 245 t.Fatalf("failed to insert forking chain: %v", err) 246 } 247 if blockchain2.CurrentBlock().NumberU64() != blockChainB[len(blockChainB)-1].NumberU64() { 248 t.Fatalf("failed to reorg to the given chain") 249 } 250 if blockchain2.CurrentBlock().Hash() != blockChainB[len(blockChainB)-1].Hash() { 251 t.Fatalf("failed to reorg to the given chain") 252 } 253 } else { 254 headerChainB := makeHeaderChain(blockchain2.chainConfig, blockchain2.CurrentHeader(), n, ethash.NewFaker(), genDb, forkSeed) 255 if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil { 256 t.Fatalf("failed to insert forking chain: %v", err) 257 } 258 if blockchain2.CurrentHeader().Number.Uint64() != headerChainB[len(headerChainB)-1].Number.Uint64() { 259 t.Fatalf("failed to reorg to the given chain") 260 } 261 if blockchain2.CurrentHeader().Hash() != headerChainB[len(headerChainB)-1].Hash() { 262 t.Fatalf("failed to reorg to the given chain") 263 } 264 } 265 } 266 267 // Tests that given a starting canonical chain of a given size, it can be extended 268 // with various length chains. 269 func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) } 270 func TestExtendCanonicalBlocks(t *testing.T) { testExtendCanonical(t, true) } 271 272 func testExtendCanonical(t *testing.T, full bool) { 273 length := 5 274 275 // Make first chain starting from genesis 276 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 277 if err != nil { 278 t.Fatalf("failed to make new canonical chain: %v", err) 279 } 280 defer processor.Stop() 281 282 // Define the difficulty comparator 283 better := func(td1, td2 *big.Int) { 284 if td2.Cmp(td1) <= 0 { 285 t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) 286 } 287 } 288 // Start fork from current height 289 testFork(t, processor, length, 1, full, better) 290 testFork(t, processor, length, 2, full, better) 291 testFork(t, processor, length, 5, full, better) 292 testFork(t, processor, length, 10, full, better) 293 } 294 295 // Tests that given a starting canonical chain of a given size, it can be extended 296 // with various length chains. 297 func TestExtendCanonicalHeadersAfterMerge(t *testing.T) { testExtendCanonicalAfterMerge(t, false) } 298 func TestExtendCanonicalBlocksAfterMerge(t *testing.T) { testExtendCanonicalAfterMerge(t, true) } 299 300 func testExtendCanonicalAfterMerge(t *testing.T, full bool) { 301 length := 5 302 303 // Make first chain starting from genesis 304 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 305 if err != nil { 306 t.Fatalf("failed to make new canonical chain: %v", err) 307 } 308 defer processor.Stop() 309 310 testInsertAfterMerge(t, processor, length, 1, full) 311 testInsertAfterMerge(t, processor, length, 10, full) 312 } 313 314 // Tests that given a starting canonical chain of a given size, creating shorter 315 // forks do not take canonical ownership. 316 func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) } 317 func TestShorterForkBlocks(t *testing.T) { testShorterFork(t, true) } 318 319 func testShorterFork(t *testing.T, full bool) { 320 length := 10 321 322 // Make first chain starting from genesis 323 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 324 if err != nil { 325 t.Fatalf("failed to make new canonical chain: %v", err) 326 } 327 defer processor.Stop() 328 329 // Define the difficulty comparator 330 worse := func(td1, td2 *big.Int) { 331 if td2.Cmp(td1) >= 0 { 332 t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1) 333 } 334 } 335 // Sum of numbers must be less than `length` for this to be a shorter fork 336 testFork(t, processor, 0, 3, full, worse) 337 testFork(t, processor, 0, 7, full, worse) 338 testFork(t, processor, 1, 1, full, worse) 339 testFork(t, processor, 1, 7, full, worse) 340 testFork(t, processor, 5, 3, full, worse) 341 testFork(t, processor, 5, 4, full, worse) 342 } 343 344 // Tests that given a starting canonical chain of a given size, creating shorter 345 // forks do not take canonical ownership. 346 func TestShorterForkHeadersAfterMerge(t *testing.T) { testShorterForkAfterMerge(t, false) } 347 func TestShorterForkBlocksAfterMerge(t *testing.T) { testShorterForkAfterMerge(t, true) } 348 349 func testShorterForkAfterMerge(t *testing.T, full bool) { 350 length := 10 351 352 // Make first chain starting from genesis 353 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 354 if err != nil { 355 t.Fatalf("failed to make new canonical chain: %v", err) 356 } 357 defer processor.Stop() 358 359 testInsertAfterMerge(t, processor, 0, 3, full) 360 testInsertAfterMerge(t, processor, 0, 7, full) 361 testInsertAfterMerge(t, processor, 1, 1, full) 362 testInsertAfterMerge(t, processor, 1, 7, full) 363 testInsertAfterMerge(t, processor, 5, 3, full) 364 testInsertAfterMerge(t, processor, 5, 4, full) 365 } 366 367 // Tests that given a starting canonical chain of a given size, creating longer 368 // forks do take canonical ownership. 369 func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) } 370 func TestLongerForkBlocks(t *testing.T) { testLongerFork(t, true) } 371 372 func testLongerFork(t *testing.T, full bool) { 373 length := 10 374 375 // Make first chain starting from genesis 376 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 377 if err != nil { 378 t.Fatalf("failed to make new canonical chain: %v", err) 379 } 380 defer processor.Stop() 381 382 testInsertAfterMerge(t, processor, 0, 11, full) 383 testInsertAfterMerge(t, processor, 0, 15, full) 384 testInsertAfterMerge(t, processor, 1, 10, full) 385 testInsertAfterMerge(t, processor, 1, 12, full) 386 testInsertAfterMerge(t, processor, 5, 6, full) 387 testInsertAfterMerge(t, processor, 5, 8, full) 388 } 389 390 // Tests that given a starting canonical chain of a given size, creating longer 391 // forks do take canonical ownership. 392 func TestLongerForkHeadersAfterMerge(t *testing.T) { testLongerForkAfterMerge(t, false) } 393 func TestLongerForkBlocksAfterMerge(t *testing.T) { testLongerForkAfterMerge(t, true) } 394 395 func testLongerForkAfterMerge(t *testing.T, full bool) { 396 length := 10 397 398 // Make first chain starting from genesis 399 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 400 if err != nil { 401 t.Fatalf("failed to make new canonical chain: %v", err) 402 } 403 defer processor.Stop() 404 405 testInsertAfterMerge(t, processor, 0, 11, full) 406 testInsertAfterMerge(t, processor, 0, 15, full) 407 testInsertAfterMerge(t, processor, 1, 10, full) 408 testInsertAfterMerge(t, processor, 1, 12, full) 409 testInsertAfterMerge(t, processor, 5, 6, full) 410 testInsertAfterMerge(t, processor, 5, 8, full) 411 } 412 413 // Tests that given a starting canonical chain of a given size, creating equal 414 // forks do take canonical ownership. 415 func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) } 416 func TestEqualForkBlocks(t *testing.T) { testEqualFork(t, true) } 417 418 func testEqualFork(t *testing.T, full bool) { 419 length := 10 420 421 // Make first chain starting from genesis 422 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 423 if err != nil { 424 t.Fatalf("failed to make new canonical chain: %v", err) 425 } 426 defer processor.Stop() 427 428 // Define the difficulty comparator 429 equal := func(td1, td2 *big.Int) { 430 if td2.Cmp(td1) != 0 { 431 t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1) 432 } 433 } 434 // Sum of numbers must be equal to `length` for this to be an equal fork 435 testFork(t, processor, 0, 10, full, equal) 436 testFork(t, processor, 1, 9, full, equal) 437 testFork(t, processor, 2, 8, full, equal) 438 testFork(t, processor, 5, 5, full, equal) 439 testFork(t, processor, 6, 4, full, equal) 440 testFork(t, processor, 9, 1, full, equal) 441 } 442 443 // Tests that given a starting canonical chain of a given size, creating equal 444 // forks do take canonical ownership. 445 func TestEqualForkHeadersAfterMerge(t *testing.T) { testEqualForkAfterMerge(t, false) } 446 func TestEqualForkBlocksAfterMerge(t *testing.T) { testEqualForkAfterMerge(t, true) } 447 448 func testEqualForkAfterMerge(t *testing.T, full bool) { 449 length := 10 450 451 // Make first chain starting from genesis 452 _, _, processor, err := newCanonical(ethash.NewFaker(), length, full) 453 if err != nil { 454 t.Fatalf("failed to make new canonical chain: %v", err) 455 } 456 defer processor.Stop() 457 458 testInsertAfterMerge(t, processor, 0, 10, full) 459 testInsertAfterMerge(t, processor, 1, 9, full) 460 testInsertAfterMerge(t, processor, 2, 8, full) 461 testInsertAfterMerge(t, processor, 5, 5, full) 462 testInsertAfterMerge(t, processor, 6, 4, full) 463 testInsertAfterMerge(t, processor, 9, 1, full) 464 } 465 466 // Tests that chains missing links do not get accepted by the processor. 467 func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) } 468 func TestBrokenBlockChain(t *testing.T) { testBrokenChain(t, true) } 469 470 func testBrokenChain(t *testing.T, full bool) { 471 // Make chain starting from genesis 472 genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 10, full) 473 if err != nil { 474 t.Fatalf("failed to make new canonical chain: %v", err) 475 } 476 defer blockchain.Stop() 477 478 // Create a forked chain, and try to insert with a missing link 479 if full { 480 chain := makeBlockChain(blockchain.chainConfig, blockchain.CurrentBlock(), 5, ethash.NewFaker(), genDb, forkSeed)[1:] 481 if err := testBlockChainImport(chain, blockchain); err == nil { 482 t.Errorf("broken block chain not reported") 483 } 484 } else { 485 chain := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 5, ethash.NewFaker(), genDb, forkSeed)[1:] 486 if err := testHeaderChainImport(chain, blockchain); err == nil { 487 t.Errorf("broken header chain not reported") 488 } 489 } 490 } 491 492 // Tests that reorganising a long difficult chain after a short easy one 493 // overwrites the canonical numbers and links in the database. 494 func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) } 495 func TestReorgLongBlocks(t *testing.T) { testReorgLong(t, true) } 496 497 func testReorgLong(t *testing.T, full bool) { 498 testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280+params.GenesisDifficulty.Int64(), full) 499 } 500 501 // Tests that reorganising a short difficult chain after a long easy one 502 // overwrites the canonical numbers and links in the database. 503 func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) } 504 func TestReorgShortBlocks(t *testing.T) { testReorgShort(t, true) } 505 506 func testReorgShort(t *testing.T, full bool) { 507 // Create a long easy chain vs. a short heavy one. Due to difficulty adjustment 508 // we need a fairly long chain of blocks with different difficulties for a short 509 // one to become heavier than a long one. The 96 is an empirical value. 510 easy := make([]int64, 96) 511 for i := 0; i < len(easy); i++ { 512 easy[i] = 60 513 } 514 diff := make([]int64, len(easy)-1) 515 for i := 0; i < len(diff); i++ { 516 diff[i] = -9 517 } 518 testReorg(t, easy, diff, 12615120+params.GenesisDifficulty.Int64(), full) 519 } 520 521 func testReorg(t *testing.T, first, second []int64, td int64, full bool) { 522 // Create a pristine chain and database 523 genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 524 if err != nil { 525 t.Fatalf("failed to create pristine chain: %v", err) 526 } 527 defer blockchain.Stop() 528 529 // Insert an easy and a difficult chain afterwards 530 easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), genDb, len(first), func(i int, b *BlockGen) { 531 b.OffsetTime(first[i]) 532 }) 533 diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), genDb, len(second), func(i int, b *BlockGen) { 534 b.OffsetTime(second[i]) 535 }) 536 if full { 537 if _, err := blockchain.InsertChain(easyBlocks); err != nil { 538 t.Fatalf("failed to insert easy chain: %v", err) 539 } 540 if _, err := blockchain.InsertChain(diffBlocks); err != nil { 541 t.Fatalf("failed to insert difficult chain: %v", err) 542 } 543 } else { 544 easyHeaders := make([]*types.Header, len(easyBlocks)) 545 for i, block := range easyBlocks { 546 easyHeaders[i] = block.Header() 547 } 548 diffHeaders := make([]*types.Header, len(diffBlocks)) 549 for i, block := range diffBlocks { 550 diffHeaders[i] = block.Header() 551 } 552 if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil { 553 t.Fatalf("failed to insert easy chain: %v", err) 554 } 555 if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil { 556 t.Fatalf("failed to insert difficult chain: %v", err) 557 } 558 } 559 // Check that the chain is valid number and link wise 560 if full { 561 prev := blockchain.CurrentBlock() 562 for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) { 563 if prev.ParentHash() != block.Hash() { 564 t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash()) 565 } 566 } 567 } else { 568 prev := blockchain.CurrentHeader() 569 for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) { 570 if prev.ParentHash != header.Hash() { 571 t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash()) 572 } 573 } 574 } 575 // Make sure the chain total difficulty is the correct one 576 want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td)) 577 if full { 578 cur := blockchain.CurrentBlock() 579 if have := blockchain.GetTd(cur.Hash(), cur.NumberU64()); have.Cmp(want) != 0 { 580 t.Errorf("total difficulty mismatch: have %v, want %v", have, want) 581 } 582 } else { 583 cur := blockchain.CurrentHeader() 584 if have := blockchain.GetTd(cur.Hash(), cur.Number.Uint64()); have.Cmp(want) != 0 { 585 t.Errorf("total difficulty mismatch: have %v, want %v", have, want) 586 } 587 } 588 } 589 590 // Tests that the insertion functions detect banned hashes. 591 func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) } 592 func TestBadBlockHashes(t *testing.T) { testBadHashes(t, true) } 593 594 func testBadHashes(t *testing.T, full bool) { 595 // Create a pristine chain and database 596 genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 597 if err != nil { 598 t.Fatalf("failed to create pristine chain: %v", err) 599 } 600 defer blockchain.Stop() 601 602 // Create a chain, ban a hash and try to import 603 if full { 604 blocks := makeBlockChain(blockchain.chainConfig, blockchain.CurrentBlock(), 3, ethash.NewFaker(), genDb, 10) 605 606 BadHashes[blocks[2].Header().Hash()] = true 607 defer func() { delete(BadHashes, blocks[2].Header().Hash()) }() 608 609 _, err = blockchain.InsertChain(blocks) 610 } else { 611 headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 3, ethash.NewFaker(), genDb, 10) 612 613 BadHashes[headers[2].Hash()] = true 614 defer func() { delete(BadHashes, headers[2].Hash()) }() 615 616 _, err = blockchain.InsertHeaderChain(headers, 1) 617 } 618 if !errors.Is(err, ErrBannedHash) { 619 t.Errorf("error mismatch: have: %v, want: %v", err, ErrBannedHash) 620 } 621 } 622 623 // Tests that bad hashes are detected on boot, and the chain rolled back to a 624 // good state prior to the bad hash. 625 func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) } 626 func TestReorgBadBlockHashes(t *testing.T) { testReorgBadHashes(t, true) } 627 628 func testReorgBadHashes(t *testing.T, full bool) { 629 // Create a pristine chain and database 630 genDb, gspec, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 631 if err != nil { 632 t.Fatalf("failed to create pristine chain: %v", err) 633 } 634 // Create a chain, import and ban afterwards 635 headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), 4, ethash.NewFaker(), genDb, 10) 636 blocks := makeBlockChain(blockchain.chainConfig, blockchain.CurrentBlock(), 4, ethash.NewFaker(), genDb, 10) 637 638 if full { 639 if _, err = blockchain.InsertChain(blocks); err != nil { 640 t.Errorf("failed to import blocks: %v", err) 641 } 642 if blockchain.CurrentBlock().Hash() != blocks[3].Hash() { 643 t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash()) 644 } 645 BadHashes[blocks[3].Header().Hash()] = true 646 defer func() { delete(BadHashes, blocks[3].Header().Hash()) }() 647 } else { 648 if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil { 649 t.Errorf("failed to import headers: %v", err) 650 } 651 if blockchain.CurrentHeader().Hash() != headers[3].Hash() { 652 t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash()) 653 } 654 BadHashes[headers[3].Hash()] = true 655 defer func() { delete(BadHashes, headers[3].Hash()) }() 656 } 657 blockchain.Stop() 658 659 // Create a new BlockChain and check that it rolled back the state. 660 ncm, err := NewBlockChain(blockchain.db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 661 if err != nil { 662 t.Fatalf("failed to create new chain manager: %v", err) 663 } 664 if full { 665 if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { 666 t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) 667 } 668 if blocks[2].Header().GasLimit != ncm.GasLimit() { 669 t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit) 670 } 671 } else { 672 if ncm.CurrentHeader().Hash() != headers[2].Hash() { 673 t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash()) 674 } 675 } 676 ncm.Stop() 677 } 678 679 // Tests chain insertions in the face of one entity containing an invalid nonce. 680 func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) } 681 func TestBlocksInsertNonceError(t *testing.T) { testInsertNonceError(t, true) } 682 683 func testInsertNonceError(t *testing.T, full bool) { 684 doTest := func(i int) { 685 // Create a pristine chain and database 686 genDb, _, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 687 if err != nil { 688 t.Fatalf("failed to create pristine chain: %v", err) 689 } 690 defer blockchain.Stop() 691 692 // Create and insert a chain with a failing nonce 693 var ( 694 failAt int 695 failRes int 696 failNum uint64 697 ) 698 if full { 699 blocks := makeBlockChain(blockchain.chainConfig, blockchain.CurrentBlock(), i, ethash.NewFaker(), genDb, 0) 700 701 failAt = rand.Int() % len(blocks) 702 failNum = blocks[failAt].NumberU64() 703 704 blockchain.engine = ethash.NewFakeFailer(failNum) 705 failRes, err = blockchain.InsertChain(blocks) 706 } else { 707 headers := makeHeaderChain(blockchain.chainConfig, blockchain.CurrentHeader(), i, ethash.NewFaker(), genDb, 0) 708 709 failAt = rand.Int() % len(headers) 710 failNum = headers[failAt].Number.Uint64() 711 712 blockchain.engine = ethash.NewFakeFailer(failNum) 713 blockchain.hc.engine = blockchain.engine 714 failRes, err = blockchain.InsertHeaderChain(headers, 1) 715 } 716 // Check that the returned error indicates the failure 717 if failRes != failAt { 718 t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt) 719 } 720 // Check that all blocks after the failing block have been inserted 721 for j := 0; j < i-failAt; j++ { 722 if full { 723 if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil { 724 t.Errorf("test %d: invalid block in chain: %v", i, block) 725 } 726 } else { 727 if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil { 728 t.Errorf("test %d: invalid header in chain: %v", i, header) 729 } 730 } 731 } 732 } 733 for i := 1; i < 25 && !t.Failed(); i++ { 734 doTest(i) 735 } 736 } 737 738 // Tests that fast importing a block chain produces the same chain data as the 739 // classical full block processing. 740 func TestFastVsFullChains(t *testing.T) { 741 // Configure and generate a sample block chain 742 var ( 743 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 744 address = crypto.PubkeyToAddress(key.PublicKey) 745 funds = big.NewInt(1000000000000000) 746 gspec = &Genesis{ 747 Config: params.TestChainConfig, 748 Alloc: GenesisAlloc{address: {Balance: funds}}, 749 BaseFee: big.NewInt(params.InitialBaseFee), 750 } 751 signer = types.LatestSigner(gspec.Config) 752 ) 753 _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 1024, func(i int, block *BlockGen) { 754 block.SetCoinbase(common.Address{0x00}) 755 756 // If the block number is multiple of 3, send a few bonus transactions to the miner 757 if i%3 == 2 { 758 for j := 0; j < i%4+1; j++ { 759 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) 760 if err != nil { 761 panic(err) 762 } 763 block.AddTx(tx) 764 } 765 } 766 // If the block number is a multiple of 5, add an uncle to the block 767 if i%5 == 4 { 768 block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 2).Hash(), Number: big.NewInt(int64(i))}) 769 } 770 }) 771 // Import the chain as an archive node for the comparison baseline 772 archiveDb := rawdb.NewMemoryDatabase() 773 archive, _ := NewBlockChain(archiveDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 774 defer archive.Stop() 775 776 if n, err := archive.InsertChain(blocks); err != nil { 777 t.Fatalf("failed to process block %d: %v", n, err) 778 } 779 // Fast import the chain as a non-archive node to test 780 fastDb := rawdb.NewMemoryDatabase() 781 fast, _ := NewBlockChain(fastDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 782 defer fast.Stop() 783 784 headers := make([]*types.Header, len(blocks)) 785 for i, block := range blocks { 786 headers[i] = block.Header() 787 } 788 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 789 t.Fatalf("failed to insert header %d: %v", n, err) 790 } 791 if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { 792 t.Fatalf("failed to insert receipt %d: %v", n, err) 793 } 794 // Freezer style fast import the chain. 795 ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 796 if err != nil { 797 t.Fatalf("failed to create temp freezer db: %v", err) 798 } 799 defer ancientDb.Close() 800 ancient, _ := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 801 defer ancient.Stop() 802 803 if n, err := ancient.InsertHeaderChain(headers, 1); err != nil { 804 t.Fatalf("failed to insert header %d: %v", n, err) 805 } 806 if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(len(blocks)/2)); err != nil { 807 t.Fatalf("failed to insert receipt %d: %v", n, err) 808 } 809 810 // Iterate over all chain data components, and cross reference 811 for i := 0; i < len(blocks); i++ { 812 num, hash := blocks[i].NumberU64(), blocks[i].Hash() 813 814 if ftd, atd := fast.GetTd(hash, num), archive.GetTd(hash, num); ftd.Cmp(atd) != 0 { 815 t.Errorf("block #%d [%x]: td mismatch: fastdb %v, archivedb %v", num, hash, ftd, atd) 816 } 817 if antd, artd := ancient.GetTd(hash, num), archive.GetTd(hash, num); antd.Cmp(artd) != 0 { 818 t.Errorf("block #%d [%x]: td mismatch: ancientdb %v, archivedb %v", num, hash, antd, artd) 819 } 820 if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() { 821 t.Errorf("block #%d [%x]: header mismatch: fastdb %v, archivedb %v", num, hash, fheader, aheader) 822 } 823 if anheader, arheader := ancient.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); anheader.Hash() != arheader.Hash() { 824 t.Errorf("block #%d [%x]: header mismatch: ancientdb %v, archivedb %v", num, hash, anheader, arheader) 825 } 826 if fblock, arblock, anblock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash), ancient.GetBlockByHash(hash); fblock.Hash() != arblock.Hash() || anblock.Hash() != arblock.Hash() { 827 t.Errorf("block #%d [%x]: block mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock, anblock, arblock) 828 } else if types.DeriveSha(fblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) || types.DeriveSha(anblock.Transactions(), trie.NewStackTrie(nil)) != types.DeriveSha(arblock.Transactions(), trie.NewStackTrie(nil)) { 829 t.Errorf("block #%d [%x]: transactions mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Transactions(), anblock.Transactions(), arblock.Transactions()) 830 } else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) || types.CalcUncleHash(anblock.Uncles()) != types.CalcUncleHash(arblock.Uncles()) { 831 t.Errorf("block #%d [%x]: uncles mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, fblock.Uncles(), anblock, arblock.Uncles()) 832 } 833 834 // Check receipts. 835 freceipts := rawdb.ReadReceipts(fastDb, hash, num, fast.Config()) 836 anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, fast.Config()) 837 areceipts := rawdb.ReadReceipts(archiveDb, hash, num, fast.Config()) 838 if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) { 839 t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts) 840 } 841 842 // Check that hash-to-number mappings are present in all databases. 843 if m := rawdb.ReadHeaderNumber(fastDb, hash); m == nil || *m != num { 844 t.Errorf("block #%d [%x]: wrong hash-to-number mapping in fastdb: %v", num, hash, m) 845 } 846 if m := rawdb.ReadHeaderNumber(ancientDb, hash); m == nil || *m != num { 847 t.Errorf("block #%d [%x]: wrong hash-to-number mapping in ancientdb: %v", num, hash, m) 848 } 849 if m := rawdb.ReadHeaderNumber(archiveDb, hash); m == nil || *m != num { 850 t.Errorf("block #%d [%x]: wrong hash-to-number mapping in archivedb: %v", num, hash, m) 851 } 852 } 853 854 // Check that the canonical chains are the same between the databases 855 for i := 0; i < len(blocks)+1; i++ { 856 if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash { 857 t.Errorf("block #%d: canonical hash mismatch: fastdb %v, archivedb %v", i, fhash, ahash) 858 } 859 if anhash, arhash := rawdb.ReadCanonicalHash(ancientDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); anhash != arhash { 860 t.Errorf("block #%d: canonical hash mismatch: ancientdb %v, archivedb %v", i, anhash, arhash) 861 } 862 } 863 } 864 865 // Tests that various import methods move the chain head pointers to the correct 866 // positions. 867 func TestLightVsFastVsFullChainHeads(t *testing.T) { 868 // Configure and generate a sample block chain 869 var ( 870 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 871 address = crypto.PubkeyToAddress(key.PublicKey) 872 funds = big.NewInt(1000000000000000) 873 gspec = &Genesis{ 874 Config: params.TestChainConfig, 875 Alloc: GenesisAlloc{address: {Balance: funds}}, 876 BaseFee: big.NewInt(params.InitialBaseFee), 877 } 878 ) 879 height := uint64(1024) 880 _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) 881 882 // makeDb creates a db instance for testing. 883 makeDb := func() ethdb.Database { 884 db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 885 if err != nil { 886 t.Fatalf("failed to create temp freezer db: %v", err) 887 } 888 return db 889 } 890 // Configure a subchain to roll back 891 remove := blocks[height/2].NumberU64() 892 893 // Create a small assertion method to check the three heads 894 assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) { 895 t.Helper() 896 897 if num := chain.CurrentBlock().NumberU64(); num != block { 898 t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block) 899 } 900 if num := chain.CurrentFastBlock().NumberU64(); num != fast { 901 t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast) 902 } 903 if num := chain.CurrentHeader().Number.Uint64(); num != header { 904 t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header) 905 } 906 } 907 // Import the chain as an archive node and ensure all pointers are updated 908 archiveDb := makeDb() 909 defer archiveDb.Close() 910 911 archiveCaching := *defaultCacheConfig 912 archiveCaching.TrieDirtyDisabled = true 913 914 archive, _ := NewBlockChain(archiveDb, &archiveCaching, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 915 if n, err := archive.InsertChain(blocks); err != nil { 916 t.Fatalf("failed to process block %d: %v", n, err) 917 } 918 defer archive.Stop() 919 920 assert(t, "archive", archive, height, height, height) 921 archive.SetHead(remove - 1) 922 assert(t, "archive", archive, height/2, height/2, height/2) 923 924 // Import the chain as a non-archive node and ensure all pointers are updated 925 fastDb := makeDb() 926 defer fastDb.Close() 927 fast, _ := NewBlockChain(fastDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 928 defer fast.Stop() 929 930 headers := make([]*types.Header, len(blocks)) 931 for i, block := range blocks { 932 headers[i] = block.Header() 933 } 934 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 935 t.Fatalf("failed to insert header %d: %v", n, err) 936 } 937 if n, err := fast.InsertReceiptChain(blocks, receipts, 0); err != nil { 938 t.Fatalf("failed to insert receipt %d: %v", n, err) 939 } 940 assert(t, "fast", fast, height, height, 0) 941 fast.SetHead(remove - 1) 942 assert(t, "fast", fast, height/2, height/2, 0) 943 944 // Import the chain as a ancient-first node and ensure all pointers are updated 945 ancientDb := makeDb() 946 defer ancientDb.Close() 947 ancient, _ := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 948 defer ancient.Stop() 949 950 if n, err := ancient.InsertHeaderChain(headers, 1); err != nil { 951 t.Fatalf("failed to insert header %d: %v", n, err) 952 } 953 if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { 954 t.Fatalf("failed to insert receipt %d: %v", n, err) 955 } 956 assert(t, "ancient", ancient, height, height, 0) 957 ancient.SetHead(remove - 1) 958 assert(t, "ancient", ancient, 0, 0, 0) 959 960 if frozen, err := ancientDb.Ancients(); err != nil || frozen != 1 { 961 t.Fatalf("failed to truncate ancient store, want %v, have %v", 1, frozen) 962 } 963 // Import the chain as a light node and ensure all pointers are updated 964 lightDb := makeDb() 965 defer lightDb.Close() 966 light, _ := NewBlockChain(lightDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 967 if n, err := light.InsertHeaderChain(headers, 1); err != nil { 968 t.Fatalf("failed to insert header %d: %v", n, err) 969 } 970 defer light.Stop() 971 972 assert(t, "light", light, height, 0, 0) 973 light.SetHead(remove - 1) 974 assert(t, "light", light, height/2, 0, 0) 975 } 976 977 // Tests that chain reorganisations handle transaction removals and reinsertions. 978 func TestChainTxReorgs(t *testing.T) { 979 var ( 980 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 981 key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 982 key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") 983 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 984 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 985 addr3 = crypto.PubkeyToAddress(key3.PublicKey) 986 gspec = &Genesis{ 987 Config: params.TestChainConfig, 988 GasLimit: 3141592, 989 Alloc: GenesisAlloc{ 990 addr1: {Balance: big.NewInt(1000000000000000)}, 991 addr2: {Balance: big.NewInt(1000000000000000)}, 992 addr3: {Balance: big.NewInt(1000000000000000)}, 993 }, 994 } 995 signer = types.LatestSigner(gspec.Config) 996 ) 997 998 // Create two transactions shared between the chains: 999 // - postponed: transaction included at a later block in the forked chain 1000 // - swapped: transaction included at the same block number in the forked chain 1001 postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1) 1002 swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key1) 1003 1004 // Create two transactions that will be dropped by the forked chain: 1005 // - pastDrop: transaction dropped retroactively from a past block 1006 // - freshDrop: transaction dropped exactly at the block where the reorg is detected 1007 var pastDrop, freshDrop *types.Transaction 1008 1009 // Create three transactions that will be added in the forked chain: 1010 // - pastAdd: transaction added before the reorganization is detected 1011 // - freshAdd: transaction added at the exact block the reorg is detected 1012 // - futureAdd: transaction added after the reorg has already finished 1013 var pastAdd, freshAdd, futureAdd *types.Transaction 1014 1015 _, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) { 1016 switch i { 1017 case 0: 1018 pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2) 1019 1020 gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point 1021 gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork 1022 1023 case 2: 1024 freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key2) 1025 1026 gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point 1027 gen.AddTx(swapped) // This transaction will be swapped out at the exact height 1028 1029 gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain 1030 } 1031 }) 1032 // Import the chain. This runs all block validation rules. 1033 db := rawdb.NewMemoryDatabase() 1034 blockchain, _ := NewBlockChain(db, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1035 if i, err := blockchain.InsertChain(chain); err != nil { 1036 t.Fatalf("failed to insert original chain[%d]: %v", i, err) 1037 } 1038 defer blockchain.Stop() 1039 1040 // overwrite the old chain 1041 _, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 5, func(i int, gen *BlockGen) { 1042 switch i { 1043 case 0: 1044 pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3) 1045 gen.AddTx(pastAdd) // This transaction needs to be injected during reorg 1046 1047 case 2: 1048 gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain 1049 gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain 1050 1051 freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3) 1052 gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time 1053 1054 case 3: 1055 futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key3) 1056 gen.AddTx(futureAdd) // This transaction will be added after a full reorg 1057 } 1058 }) 1059 if _, err := blockchain.InsertChain(chain); err != nil { 1060 t.Fatalf("failed to insert forked chain: %v", err) 1061 } 1062 1063 // removed tx 1064 for i, tx := range (types.Transactions{pastDrop, freshDrop}) { 1065 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil { 1066 t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) 1067 } 1068 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil { 1069 t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt) 1070 } 1071 } 1072 // added tx 1073 for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { 1074 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 1075 t.Errorf("add %d: expected tx to be found", i) 1076 } 1077 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil { 1078 t.Errorf("add %d: expected receipt to be found", i) 1079 } 1080 } 1081 // shared tx 1082 for i, tx := range (types.Transactions{postponed, swapped}) { 1083 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 1084 t.Errorf("share %d: expected tx to be found", i) 1085 } 1086 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil { 1087 t.Errorf("share %d: expected receipt to be found", i) 1088 } 1089 } 1090 } 1091 1092 func TestLogReorgs(t *testing.T) { 1093 var ( 1094 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1095 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1096 1097 // this code generates a log 1098 code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 1099 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} 1100 signer = types.LatestSigner(gspec.Config) 1101 ) 1102 1103 blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1104 defer blockchain.Stop() 1105 1106 rmLogsCh := make(chan RemovedLogsEvent) 1107 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 1108 _, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) { 1109 if i == 1 { 1110 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, code), signer, key1) 1111 if err != nil { 1112 t.Fatalf("failed to create tx: %v", err) 1113 } 1114 gen.AddTx(tx) 1115 } 1116 }) 1117 if _, err := blockchain.InsertChain(chain); err != nil { 1118 t.Fatalf("failed to insert chain: %v", err) 1119 } 1120 1121 _, chain, _ = GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {}) 1122 done := make(chan struct{}) 1123 go func() { 1124 ev := <-rmLogsCh 1125 if len(ev.Logs) == 0 { 1126 t.Error("expected logs") 1127 } 1128 close(done) 1129 }() 1130 if _, err := blockchain.InsertChain(chain); err != nil { 1131 t.Fatalf("failed to insert forked chain: %v", err) 1132 } 1133 timeout := time.NewTimer(1 * time.Second) 1134 defer timeout.Stop() 1135 select { 1136 case <-done: 1137 case <-timeout.C: 1138 t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") 1139 } 1140 } 1141 1142 // This EVM code generates a log when the contract is created. 1143 var logCode = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 1144 1145 // This test checks that log events and RemovedLogsEvent are sent 1146 // when the chain reorganizes. 1147 func TestLogRebirth(t *testing.T) { 1148 var ( 1149 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1150 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1151 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} 1152 signer = types.LatestSigner(gspec.Config) 1153 engine = ethash.NewFaker() 1154 blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 1155 ) 1156 defer blockchain.Stop() 1157 1158 // The event channels. 1159 newLogCh := make(chan []*types.Log, 10) 1160 rmLogsCh := make(chan RemovedLogsEvent, 10) 1161 blockchain.SubscribeLogsEvent(newLogCh) 1162 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 1163 1164 // This chain contains 10 logs. 1165 genDb, chain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) { 1166 if i < 2 { 1167 for ii := 0; ii < 5; ii++ { 1168 tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{ 1169 Nonce: gen.TxNonce(addr1), 1170 GasPrice: gen.header.BaseFee, 1171 Gas: uint64(1000001), 1172 Data: logCode, 1173 }) 1174 if err != nil { 1175 t.Fatalf("failed to create tx: %v", err) 1176 } 1177 gen.AddTx(tx) 1178 } 1179 } 1180 }) 1181 if _, err := blockchain.InsertChain(chain); err != nil { 1182 t.Fatalf("failed to insert chain: %v", err) 1183 } 1184 checkLogEvents(t, newLogCh, rmLogsCh, 10, 0) 1185 1186 // Generate long reorg chain containing more logs. Inserting the 1187 // chain removes one log and adds four. 1188 _, forkChain, _ := GenerateChainWithGenesis(gspec, engine, 3, func(i int, gen *BlockGen) { 1189 if i == 2 { 1190 // The last (head) block is not part of the reorg-chain, we can ignore it 1191 return 1192 } 1193 for ii := 0; ii < 5; ii++ { 1194 tx, err := types.SignNewTx(key1, signer, &types.LegacyTx{ 1195 Nonce: gen.TxNonce(addr1), 1196 GasPrice: gen.header.BaseFee, 1197 Gas: uint64(1000000), 1198 Data: logCode, 1199 }) 1200 if err != nil { 1201 t.Fatalf("failed to create tx: %v", err) 1202 } 1203 gen.AddTx(tx) 1204 } 1205 gen.OffsetTime(-9) // higher block difficulty 1206 }) 1207 if _, err := blockchain.InsertChain(forkChain); err != nil { 1208 t.Fatalf("failed to insert forked chain: %v", err) 1209 } 1210 checkLogEvents(t, newLogCh, rmLogsCh, 10, 10) 1211 1212 // This chain segment is rooted in the original chain, but doesn't contain any logs. 1213 // When inserting it, the canonical chain switches away from forkChain and re-emits 1214 // the log event for the old chain, as well as a RemovedLogsEvent for forkChain. 1215 newBlocks, _ := GenerateChain(gspec.Config, chain[len(chain)-1], engine, genDb, 1, func(i int, gen *BlockGen) {}) 1216 if _, err := blockchain.InsertChain(newBlocks); err != nil { 1217 t.Fatalf("failed to insert forked chain: %v", err) 1218 } 1219 checkLogEvents(t, newLogCh, rmLogsCh, 10, 10) 1220 } 1221 1222 // This test is a variation of TestLogRebirth. It verifies that log events are emitted 1223 // when a side chain containing log events overtakes the canonical chain. 1224 func TestSideLogRebirth(t *testing.T) { 1225 var ( 1226 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1227 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1228 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}} 1229 signer = types.LatestSigner(gspec.Config) 1230 blockchain, _ = NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1231 ) 1232 defer blockchain.Stop() 1233 1234 newLogCh := make(chan []*types.Log, 10) 1235 rmLogsCh := make(chan RemovedLogsEvent, 10) 1236 blockchain.SubscribeLogsEvent(newLogCh) 1237 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 1238 1239 _, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) { 1240 if i == 1 { 1241 gen.OffsetTime(-9) // higher block difficulty 1242 } 1243 }) 1244 if _, err := blockchain.InsertChain(chain); err != nil { 1245 t.Fatalf("failed to insert forked chain: %v", err) 1246 } 1247 checkLogEvents(t, newLogCh, rmLogsCh, 0, 0) 1248 1249 // Generate side chain with lower difficulty 1250 genDb, sideChain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 2, func(i int, gen *BlockGen) { 1251 if i == 1 { 1252 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, logCode), signer, key1) 1253 if err != nil { 1254 t.Fatalf("failed to create tx: %v", err) 1255 } 1256 gen.AddTx(tx) 1257 } 1258 }) 1259 if _, err := blockchain.InsertChain(sideChain); err != nil { 1260 t.Fatalf("failed to insert forked chain: %v", err) 1261 } 1262 checkLogEvents(t, newLogCh, rmLogsCh, 0, 0) 1263 1264 // Generate a new block based on side chain. 1265 newBlocks, _ := GenerateChain(gspec.Config, sideChain[len(sideChain)-1], ethash.NewFaker(), genDb, 1, func(i int, gen *BlockGen) {}) 1266 if _, err := blockchain.InsertChain(newBlocks); err != nil { 1267 t.Fatalf("failed to insert forked chain: %v", err) 1268 } 1269 checkLogEvents(t, newLogCh, rmLogsCh, 1, 0) 1270 } 1271 1272 func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan RemovedLogsEvent, wantNew, wantRemoved int) { 1273 t.Helper() 1274 var ( 1275 countNew int 1276 countRm int 1277 prev int 1278 ) 1279 // Drain events. 1280 for len(logsCh) > 0 { 1281 x := <-logsCh 1282 countNew += len(x) 1283 for _, log := range x { 1284 // We expect added logs to be in ascending order: 0:0, 0:1, 1:0 ... 1285 have := 100*int(log.BlockNumber) + int(log.TxIndex) 1286 if have < prev { 1287 t.Fatalf("Expected new logs to arrive in ascending order (%d < %d)", have, prev) 1288 } 1289 prev = have 1290 } 1291 } 1292 prev = 0 1293 for len(rmLogsCh) > 0 { 1294 x := <-rmLogsCh 1295 countRm += len(x.Logs) 1296 for _, log := range x.Logs { 1297 // We expect removed logs to be in ascending order: 0:0, 0:1, 1:0 ... 1298 have := 100*int(log.BlockNumber) + int(log.TxIndex) 1299 if have < prev { 1300 t.Fatalf("Expected removed logs to arrive in ascending order (%d < %d)", have, prev) 1301 } 1302 prev = have 1303 } 1304 } 1305 1306 if countNew != wantNew { 1307 t.Fatalf("wrong number of log events: got %d, want %d", countNew, wantNew) 1308 } 1309 if countRm != wantRemoved { 1310 t.Fatalf("wrong number of removed log events: got %d, want %d", countRm, wantRemoved) 1311 } 1312 } 1313 1314 func TestReorgSideEvent(t *testing.T) { 1315 var ( 1316 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1317 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1318 gspec = &Genesis{ 1319 Config: params.TestChainConfig, 1320 Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}}, 1321 } 1322 signer = types.LatestSigner(gspec.Config) 1323 ) 1324 blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1325 defer blockchain.Stop() 1326 1327 _, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {}) 1328 if _, err := blockchain.InsertChain(chain); err != nil { 1329 t.Fatalf("failed to insert chain: %v", err) 1330 } 1331 1332 _, replacementBlocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, gen *BlockGen) { 1333 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1) 1334 if i == 2 { 1335 gen.OffsetTime(-9) 1336 } 1337 if err != nil { 1338 t.Fatalf("failed to create tx: %v", err) 1339 } 1340 gen.AddTx(tx) 1341 }) 1342 chainSideCh := make(chan ChainSideEvent, 64) 1343 blockchain.SubscribeChainSideEvent(chainSideCh) 1344 if _, err := blockchain.InsertChain(replacementBlocks); err != nil { 1345 t.Fatalf("failed to insert chain: %v", err) 1346 } 1347 1348 // first two block of the secondary chain are for a brief moment considered 1349 // side chains because up to that point the first one is considered the 1350 // heavier chain. 1351 expectedSideHashes := map[common.Hash]bool{ 1352 replacementBlocks[0].Hash(): true, 1353 replacementBlocks[1].Hash(): true, 1354 chain[0].Hash(): true, 1355 chain[1].Hash(): true, 1356 chain[2].Hash(): true, 1357 } 1358 1359 i := 0 1360 1361 const timeoutDura = 10 * time.Second 1362 timeout := time.NewTimer(timeoutDura) 1363 done: 1364 for { 1365 select { 1366 case ev := <-chainSideCh: 1367 block := ev.Block 1368 if _, ok := expectedSideHashes[block.Hash()]; !ok { 1369 t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) 1370 } 1371 i++ 1372 1373 if i == len(expectedSideHashes) { 1374 timeout.Stop() 1375 1376 break done 1377 } 1378 timeout.Reset(timeoutDura) 1379 1380 case <-timeout.C: 1381 t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") 1382 } 1383 } 1384 1385 // make sure no more events are fired 1386 select { 1387 case e := <-chainSideCh: 1388 t.Errorf("unexpected event fired: %v", e) 1389 case <-time.After(250 * time.Millisecond): 1390 } 1391 } 1392 1393 // Tests if the canonical block can be fetched from the database during chain insertion. 1394 func TestCanonicalBlockRetrieval(t *testing.T) { 1395 _, gspec, blockchain, err := newCanonical(ethash.NewFaker(), 0, true) 1396 if err != nil { 1397 t.Fatalf("failed to create pristine chain: %v", err) 1398 } 1399 defer blockchain.Stop() 1400 1401 _, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 10, func(i int, gen *BlockGen) {}) 1402 1403 var pend sync.WaitGroup 1404 pend.Add(len(chain)) 1405 1406 for i := range chain { 1407 go func(block *types.Block) { 1408 defer pend.Done() 1409 1410 // try to retrieve a block by its canonical hash and see if the block data can be retrieved. 1411 for { 1412 ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64()) 1413 if ch == (common.Hash{}) { 1414 continue // busy wait for canonical hash to be written 1415 } 1416 if ch != block.Hash() { 1417 t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) 1418 return 1419 } 1420 fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64()) 1421 if fb == nil { 1422 t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) 1423 return 1424 } 1425 if fb.Hash() != block.Hash() { 1426 t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex()) 1427 return 1428 } 1429 return 1430 } 1431 }(chain[i]) 1432 1433 if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil { 1434 t.Fatalf("failed to insert block %d: %v", i, err) 1435 } 1436 } 1437 pend.Wait() 1438 } 1439 1440 func TestEIP155Transition(t *testing.T) { 1441 // Configure and generate a sample block chain 1442 var ( 1443 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1444 address = crypto.PubkeyToAddress(key.PublicKey) 1445 funds = big.NewInt(1000000000) 1446 deleteAddr = common.Address{1} 1447 gspec = &Genesis{ 1448 Config: ¶ms.ChainConfig{ 1449 ChainID: big.NewInt(1), 1450 EIP150Block: big.NewInt(0), 1451 EIP155Block: big.NewInt(2), 1452 HomesteadBlock: new(big.Int), 1453 }, 1454 Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, 1455 } 1456 ) 1457 genDb, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, block *BlockGen) { 1458 var ( 1459 tx *types.Transaction 1460 err error 1461 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1462 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1463 } 1464 ) 1465 switch i { 1466 case 0: 1467 tx, err = basicTx(types.HomesteadSigner{}) 1468 if err != nil { 1469 t.Fatal(err) 1470 } 1471 block.AddTx(tx) 1472 case 2: 1473 tx, err = basicTx(types.HomesteadSigner{}) 1474 if err != nil { 1475 t.Fatal(err) 1476 } 1477 block.AddTx(tx) 1478 1479 tx, err = basicTx(types.LatestSigner(gspec.Config)) 1480 if err != nil { 1481 t.Fatal(err) 1482 } 1483 block.AddTx(tx) 1484 case 3: 1485 tx, err = basicTx(types.HomesteadSigner{}) 1486 if err != nil { 1487 t.Fatal(err) 1488 } 1489 block.AddTx(tx) 1490 1491 tx, err = basicTx(types.LatestSigner(gspec.Config)) 1492 if err != nil { 1493 t.Fatal(err) 1494 } 1495 block.AddTx(tx) 1496 } 1497 }) 1498 1499 blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1500 defer blockchain.Stop() 1501 1502 if _, err := blockchain.InsertChain(blocks); err != nil { 1503 t.Fatal(err) 1504 } 1505 block := blockchain.GetBlockByNumber(1) 1506 if block.Transactions()[0].Protected() { 1507 t.Error("Expected block[0].txs[0] to not be replay protected") 1508 } 1509 1510 block = blockchain.GetBlockByNumber(3) 1511 if block.Transactions()[0].Protected() { 1512 t.Error("Expected block[3].txs[0] to not be replay protected") 1513 } 1514 if !block.Transactions()[1].Protected() { 1515 t.Error("Expected block[3].txs[1] to be replay protected") 1516 } 1517 if _, err := blockchain.InsertChain(blocks[4:]); err != nil { 1518 t.Fatal(err) 1519 } 1520 1521 // generate an invalid chain id transaction 1522 config := ¶ms.ChainConfig{ 1523 ChainID: big.NewInt(2), 1524 EIP150Block: big.NewInt(0), 1525 EIP155Block: big.NewInt(2), 1526 HomesteadBlock: new(big.Int), 1527 } 1528 blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), genDb, 4, func(i int, block *BlockGen) { 1529 var ( 1530 tx *types.Transaction 1531 err error 1532 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1533 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1534 } 1535 ) 1536 if i == 0 { 1537 tx, err = basicTx(types.LatestSigner(config)) 1538 if err != nil { 1539 t.Fatal(err) 1540 } 1541 block.AddTx(tx) 1542 } 1543 }) 1544 _, err := blockchain.InsertChain(blocks) 1545 if have, want := err, types.ErrInvalidChainId; !errors.Is(have, want) { 1546 t.Errorf("have %v, want %v", have, want) 1547 } 1548 } 1549 1550 func TestEIP161AccountRemoval(t *testing.T) { 1551 // Configure and generate a sample block chain 1552 var ( 1553 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1554 address = crypto.PubkeyToAddress(key.PublicKey) 1555 funds = big.NewInt(1000000000) 1556 theAddr = common.Address{1} 1557 gspec = &Genesis{ 1558 Config: ¶ms.ChainConfig{ 1559 ChainID: big.NewInt(1), 1560 HomesteadBlock: new(big.Int), 1561 EIP155Block: new(big.Int), 1562 EIP150Block: new(big.Int), 1563 EIP158Block: big.NewInt(2), 1564 }, 1565 Alloc: GenesisAlloc{address: {Balance: funds}}, 1566 } 1567 ) 1568 _, blocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, block *BlockGen) { 1569 var ( 1570 tx *types.Transaction 1571 err error 1572 signer = types.LatestSigner(gspec.Config) 1573 ) 1574 switch i { 1575 case 0: 1576 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1577 case 1: 1578 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1579 case 2: 1580 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1581 } 1582 if err != nil { 1583 t.Fatal(err) 1584 } 1585 block.AddTx(tx) 1586 }) 1587 // account must exist pre eip 161 1588 blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1589 defer blockchain.Stop() 1590 1591 if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil { 1592 t.Fatal(err) 1593 } 1594 if st, _ := blockchain.State(); !st.Exist(theAddr) { 1595 t.Error("expected account to exist") 1596 } 1597 1598 // account needs to be deleted post eip 161 1599 if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil { 1600 t.Fatal(err) 1601 } 1602 if st, _ := blockchain.State(); st.Exist(theAddr) { 1603 t.Error("account should not exist") 1604 } 1605 1606 // account mustn't be created post eip 161 1607 if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil { 1608 t.Fatal(err) 1609 } 1610 if st, _ := blockchain.State(); st.Exist(theAddr) { 1611 t.Error("account should not exist") 1612 } 1613 } 1614 1615 // This is a regression test (i.e. as weird as it is, don't delete it ever), which 1616 // tests that under weird reorg conditions the blockchain and its internal header- 1617 // chain return the same latest block/header. 1618 // 1619 // https://github.com/tirogen/go-ethereum/pull/15941 1620 func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { 1621 // Generate a canonical chain to act as the main dataset 1622 engine := ethash.NewFaker() 1623 genesis := &Genesis{ 1624 Config: params.TestChainConfig, 1625 BaseFee: big.NewInt(params.InitialBaseFee), 1626 } 1627 genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1628 1629 // Generate a bunch of fork blocks, each side forking from the canonical chain 1630 forks := make([]*types.Block, len(blocks)) 1631 for i := 0; i < len(forks); i++ { 1632 parent := genesis.ToBlock() 1633 if i > 0 { 1634 parent = blocks[i-1] 1635 } 1636 fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1637 forks[i] = fork[0] 1638 } 1639 // Import the canonical and fork chain side by side, verifying the current block 1640 // and current header consistency 1641 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 1642 if err != nil { 1643 t.Fatalf("failed to create tester chain: %v", err) 1644 } 1645 defer chain.Stop() 1646 1647 for i := 0; i < len(blocks); i++ { 1648 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1649 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1650 } 1651 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1652 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]) 1653 } 1654 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1655 t.Fatalf(" fork %d: failed to insert into chain: %v", i, err) 1656 } 1657 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1658 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]) 1659 } 1660 } 1661 } 1662 1663 // Tests that importing small side forks doesn't leave junk in the trie database 1664 // cache (which would eventually cause memory issues). 1665 func TestTrieForkGC(t *testing.T) { 1666 // Generate a canonical chain to act as the main dataset 1667 engine := ethash.NewFaker() 1668 genesis := &Genesis{ 1669 Config: params.TestChainConfig, 1670 BaseFee: big.NewInt(params.InitialBaseFee), 1671 } 1672 genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1673 1674 // Generate a bunch of fork blocks, each side forking from the canonical chain 1675 forks := make([]*types.Block, len(blocks)) 1676 for i := 0; i < len(forks); i++ { 1677 parent := genesis.ToBlock() 1678 if i > 0 { 1679 parent = blocks[i-1] 1680 } 1681 fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1682 forks[i] = fork[0] 1683 } 1684 // Import the canonical and fork chain side by side, forcing the trie cache to cache both 1685 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 1686 if err != nil { 1687 t.Fatalf("failed to create tester chain: %v", err) 1688 } 1689 defer chain.Stop() 1690 1691 for i := 0; i < len(blocks); i++ { 1692 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1693 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1694 } 1695 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1696 t.Fatalf("fork %d: failed to insert into chain: %v", i, err) 1697 } 1698 } 1699 // Dereference all the recent tries and ensure no past trie is left in 1700 for i := 0; i < TriesInMemory; i++ { 1701 chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root()) 1702 chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root()) 1703 } 1704 if len(chain.stateCache.TrieDB().Nodes()) > 0 { 1705 t.Fatalf("stale tries still alive after garbase collection") 1706 } 1707 } 1708 1709 // Tests that doing large reorgs works even if the state associated with the 1710 // forking point is not available any more. 1711 func TestLargeReorgTrieGC(t *testing.T) { 1712 // Generate the original common chain segment and the two competing forks 1713 engine := ethash.NewFaker() 1714 genesis := &Genesis{ 1715 Config: params.TestChainConfig, 1716 BaseFee: big.NewInt(params.InitialBaseFee), 1717 } 1718 genDb, shared, _ := GenerateChainWithGenesis(genesis, engine, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1719 original, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1720 competitor, _ := GenerateChain(genesis.Config, shared[len(shared)-1], engine, genDb, 2*TriesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) 1721 1722 // Import the shared chain and the original canonical one 1723 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 1724 if err != nil { 1725 t.Fatalf("failed to create tester chain: %v", err) 1726 } 1727 defer chain.Stop() 1728 1729 if _, err := chain.InsertChain(shared); err != nil { 1730 t.Fatalf("failed to insert shared chain: %v", err) 1731 } 1732 if _, err := chain.InsertChain(original); err != nil { 1733 t.Fatalf("failed to insert original chain: %v", err) 1734 } 1735 // Ensure that the state associated with the forking point is pruned away 1736 if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil { 1737 t.Fatalf("common-but-old ancestor still cache") 1738 } 1739 // Import the competitor chain without exceeding the canonical's TD and ensure 1740 // we have not processed any of the blocks (protection against malicious blocks) 1741 if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil { 1742 t.Fatalf("failed to insert competitor chain: %v", err) 1743 } 1744 for i, block := range competitor[:len(competitor)-2] { 1745 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1746 t.Fatalf("competitor %d: low TD chain became processed", i) 1747 } 1748 } 1749 // Import the head of the competitor chain, triggering the reorg and ensure we 1750 // successfully reprocess all the stashed away blocks. 1751 if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil { 1752 t.Fatalf("failed to finalize competitor chain: %v", err) 1753 } 1754 for i, block := range competitor[:len(competitor)-TriesInMemory] { 1755 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1756 t.Fatalf("competitor %d: competing chain state missing", i) 1757 } 1758 } 1759 } 1760 1761 func TestBlockchainRecovery(t *testing.T) { 1762 // Configure and generate a sample block chain 1763 var ( 1764 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1765 address = crypto.PubkeyToAddress(key.PublicKey) 1766 funds = big.NewInt(1000000000) 1767 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} 1768 ) 1769 height := uint64(1024) 1770 _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), int(height), nil) 1771 1772 // Import the chain as a ancient-first node and ensure all pointers are updated 1773 ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 1774 if err != nil { 1775 t.Fatalf("failed to create temp freezer db: %v", err) 1776 } 1777 defer ancientDb.Close() 1778 ancient, _ := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1779 1780 headers := make([]*types.Header, len(blocks)) 1781 for i, block := range blocks { 1782 headers[i] = block.Header() 1783 } 1784 if n, err := ancient.InsertHeaderChain(headers, 1); err != nil { 1785 t.Fatalf("failed to insert header %d: %v", n, err) 1786 } 1787 if n, err := ancient.InsertReceiptChain(blocks, receipts, uint64(3*len(blocks)/4)); err != nil { 1788 t.Fatalf("failed to insert receipt %d: %v", n, err) 1789 } 1790 rawdb.WriteLastPivotNumber(ancientDb, blocks[len(blocks)-1].NumberU64()) // Force fast sync behavior 1791 ancient.Stop() 1792 1793 // Destroy head fast block manually 1794 midBlock := blocks[len(blocks)/2] 1795 rawdb.WriteHeadFastBlockHash(ancientDb, midBlock.Hash()) 1796 1797 // Reopen broken blockchain again 1798 ancient, _ = NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1799 defer ancient.Stop() 1800 if num := ancient.CurrentBlock().NumberU64(); num != 0 { 1801 t.Errorf("head block mismatch: have #%v, want #%v", num, 0) 1802 } 1803 if num := ancient.CurrentFastBlock().NumberU64(); num != midBlock.NumberU64() { 1804 t.Errorf("head fast-block mismatch: have #%v, want #%v", num, midBlock.NumberU64()) 1805 } 1806 if num := ancient.CurrentHeader().Number.Uint64(); num != midBlock.NumberU64() { 1807 t.Errorf("head header mismatch: have #%v, want #%v", num, midBlock.NumberU64()) 1808 } 1809 } 1810 1811 // This test checks that InsertReceiptChain will roll back correctly when attempting to insert a side chain. 1812 func TestInsertReceiptChainRollback(t *testing.T) { 1813 // Generate forked chain. The returned BlockChain object is used to process the side chain blocks. 1814 tmpChain, sideblocks, canonblocks, gspec, err := getLongAndShortChains() 1815 if err != nil { 1816 t.Fatal(err) 1817 } 1818 defer tmpChain.Stop() 1819 // Get the side chain receipts. 1820 if _, err := tmpChain.InsertChain(sideblocks); err != nil { 1821 t.Fatal("processing side chain failed:", err) 1822 } 1823 t.Log("sidechain head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash()) 1824 sidechainReceipts := make([]types.Receipts, len(sideblocks)) 1825 for i, block := range sideblocks { 1826 sidechainReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash()) 1827 } 1828 // Get the canon chain receipts. 1829 if _, err := tmpChain.InsertChain(canonblocks); err != nil { 1830 t.Fatal("processing canon chain failed:", err) 1831 } 1832 t.Log("canon head:", tmpChain.CurrentBlock().Number(), tmpChain.CurrentBlock().Hash()) 1833 canonReceipts := make([]types.Receipts, len(canonblocks)) 1834 for i, block := range canonblocks { 1835 canonReceipts[i] = tmpChain.GetReceiptsByHash(block.Hash()) 1836 } 1837 1838 // Set up a BlockChain that uses the ancient store. 1839 ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 1840 if err != nil { 1841 t.Fatalf("failed to create temp freezer db: %v", err) 1842 } 1843 defer ancientDb.Close() 1844 1845 ancientChain, _ := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil) 1846 defer ancientChain.Stop() 1847 1848 // Import the canonical header chain. 1849 canonHeaders := make([]*types.Header, len(canonblocks)) 1850 for i, block := range canonblocks { 1851 canonHeaders[i] = block.Header() 1852 } 1853 if _, err = ancientChain.InsertHeaderChain(canonHeaders, 1); err != nil { 1854 t.Fatal("can't import canon headers:", err) 1855 } 1856 1857 // Try to insert blocks/receipts of the side chain. 1858 _, err = ancientChain.InsertReceiptChain(sideblocks, sidechainReceipts, uint64(len(sideblocks))) 1859 if err == nil { 1860 t.Fatal("expected error from InsertReceiptChain.") 1861 } 1862 if ancientChain.CurrentFastBlock().NumberU64() != 0 { 1863 t.Fatalf("failed to rollback ancient data, want %d, have %d", 0, ancientChain.CurrentFastBlock().NumberU64()) 1864 } 1865 if frozen, err := ancientChain.db.Ancients(); err != nil || frozen != 1 { 1866 t.Fatalf("failed to truncate ancient data, frozen index is %d", frozen) 1867 } 1868 1869 // Insert blocks/receipts of the canonical chain. 1870 _, err = ancientChain.InsertReceiptChain(canonblocks, canonReceipts, uint64(len(canonblocks))) 1871 if err != nil { 1872 t.Fatalf("can't import canon chain receipts: %v", err) 1873 } 1874 if ancientChain.CurrentFastBlock().NumberU64() != canonblocks[len(canonblocks)-1].NumberU64() { 1875 t.Fatalf("failed to insert ancient recept chain after rollback") 1876 } 1877 if frozen, _ := ancientChain.db.Ancients(); frozen != uint64(len(canonblocks))+1 { 1878 t.Fatalf("wrong ancients count %d", frozen) 1879 } 1880 } 1881 1882 // Tests that importing a very large side fork, which is larger than the canon chain, 1883 // but where the difficulty per block is kept low: this means that it will not 1884 // overtake the 'canon' chain until after it's passed canon by about 200 blocks. 1885 // 1886 // Details at: 1887 // - https://github.com/tirogen/go-ethereum/issues/18977 1888 // - https://github.com/tirogen/go-ethereum/pull/18988 1889 func TestLowDiffLongChain(t *testing.T) { 1890 // Generate a canonical chain to act as the main dataset 1891 engine := ethash.NewFaker() 1892 genesis := &Genesis{ 1893 Config: params.TestChainConfig, 1894 BaseFee: big.NewInt(params.InitialBaseFee), 1895 } 1896 // We must use a pretty long chain to ensure that the fork doesn't overtake us 1897 // until after at least 128 blocks post tip 1898 genDb, blocks, _ := GenerateChainWithGenesis(genesis, engine, 6*TriesInMemory, func(i int, b *BlockGen) { 1899 b.SetCoinbase(common.Address{1}) 1900 b.OffsetTime(-9) 1901 }) 1902 1903 // Import the canonical chain 1904 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 1905 if err != nil { 1906 t.Fatalf("failed to create tester chain: %v", err) 1907 } 1908 defer chain.stopWithoutSaving() 1909 1910 if n, err := chain.InsertChain(blocks); err != nil { 1911 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 1912 } 1913 // Generate fork chain, starting from an early block 1914 parent := blocks[10] 1915 fork, _ := GenerateChain(genesis.Config, parent, engine, genDb, 8*TriesInMemory, func(i int, b *BlockGen) { 1916 b.SetCoinbase(common.Address{2}) 1917 }) 1918 1919 // And now import the fork 1920 if i, err := chain.InsertChain(fork); err != nil { 1921 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1922 } 1923 head := chain.CurrentBlock() 1924 if got := fork[len(fork)-1].Hash(); got != head.Hash() { 1925 t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) 1926 } 1927 // Sanity check that all the canonical numbers are present 1928 header := chain.CurrentHeader() 1929 for number := head.NumberU64(); number > 0; number-- { 1930 if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() { 1931 t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash()) 1932 } 1933 header = chain.GetHeader(header.ParentHash, number-1) 1934 } 1935 } 1936 1937 // Tests that importing a sidechain (S), where 1938 // - S is sidechain, containing blocks [Sn...Sm] 1939 // - C is canon chain, containing blocks [G..Cn..Cm] 1940 // - A common ancestor is placed at prune-point + blocksBetweenCommonAncestorAndPruneblock 1941 // - The sidechain S is prepended with numCanonBlocksInSidechain blocks from the canon chain 1942 // 1943 // The mergePoint can be these values: 1944 // -1: the transition won't happen 1945 // 0: the transition happens since genesis 1946 // 1: the transition happens after some chain segments 1947 func testSideImport(t *testing.T, numCanonBlocksInSidechain, blocksBetweenCommonAncestorAndPruneblock int, mergePoint int) { 1948 // Generate a canonical chain to act as the main dataset 1949 chainConfig := *params.TestChainConfig 1950 var ( 1951 merger = consensus.NewMerger(rawdb.NewMemoryDatabase()) 1952 engine = beacon.New(ethash.NewFaker()) 1953 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1954 addr = crypto.PubkeyToAddress(key.PublicKey) 1955 nonce = uint64(0) 1956 1957 gspec = &Genesis{ 1958 Config: &chainConfig, 1959 Alloc: GenesisAlloc{addr: {Balance: big.NewInt(math.MaxInt64)}}, 1960 BaseFee: big.NewInt(params.InitialBaseFee), 1961 } 1962 signer = types.LatestSigner(gspec.Config) 1963 mergeBlock = math.MaxInt32 1964 ) 1965 // Generate and import the canonical chain 1966 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 1967 if err != nil { 1968 t.Fatalf("failed to create tester chain: %v", err) 1969 } 1970 defer chain.Stop() 1971 1972 // Activate the transition since genesis if required 1973 if mergePoint == 0 { 1974 mergeBlock = 0 1975 merger.ReachTTD() 1976 merger.FinalizePoS() 1977 1978 // Set the terminal total difficulty in the config 1979 gspec.Config.TerminalTotalDifficulty = big.NewInt(0) 1980 } 1981 genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { 1982 tx, err := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("deadbeef"), big.NewInt(100), 21000, big.NewInt(int64(i+1)*params.GWei), nil), signer, key) 1983 if err != nil { 1984 t.Fatalf("failed to create tx: %v", err) 1985 } 1986 gen.AddTx(tx) 1987 if int(gen.header.Number.Uint64()) >= mergeBlock { 1988 gen.SetPoS() 1989 } 1990 nonce++ 1991 }) 1992 if n, err := chain.InsertChain(blocks); err != nil { 1993 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 1994 } 1995 1996 lastPrunedIndex := len(blocks) - TriesInMemory - 1 1997 lastPrunedBlock := blocks[lastPrunedIndex] 1998 firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory] 1999 2000 // Verify pruning of lastPrunedBlock 2001 if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) { 2002 t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64()) 2003 } 2004 // Verify firstNonPrunedBlock is not pruned 2005 if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) { 2006 t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64()) 2007 } 2008 2009 // Activate the transition in the middle of the chain 2010 if mergePoint == 1 { 2011 merger.ReachTTD() 2012 merger.FinalizePoS() 2013 // Set the terminal total difficulty in the config 2014 ttd := big.NewInt(int64(len(blocks))) 2015 ttd.Mul(ttd, params.GenesisDifficulty) 2016 gspec.Config.TerminalTotalDifficulty = ttd 2017 mergeBlock = len(blocks) 2018 } 2019 2020 // Generate the sidechain 2021 // First block should be a known block, block after should be a pruned block. So 2022 // canon(pruned), side, side... 2023 2024 // Generate fork chain, make it longer than canon 2025 parentIndex := lastPrunedIndex + blocksBetweenCommonAncestorAndPruneblock 2026 parent := blocks[parentIndex] 2027 fork, _ := GenerateChain(gspec.Config, parent, engine, genDb, 2*TriesInMemory, func(i int, b *BlockGen) { 2028 b.SetCoinbase(common.Address{2}) 2029 if int(b.header.Number.Uint64()) >= mergeBlock { 2030 b.SetPoS() 2031 } 2032 }) 2033 // Prepend the parent(s) 2034 var sidechain []*types.Block 2035 for i := numCanonBlocksInSidechain; i > 0; i-- { 2036 sidechain = append(sidechain, blocks[parentIndex+1-i]) 2037 } 2038 sidechain = append(sidechain, fork...) 2039 n, err := chain.InsertChain(sidechain) 2040 if err != nil { 2041 t.Errorf("Got error, %v number %d - %d", err, sidechain[n].NumberU64(), n) 2042 } 2043 head := chain.CurrentBlock() 2044 if got := fork[len(fork)-1].Hash(); got != head.Hash() { 2045 t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) 2046 } 2047 } 2048 2049 // Tests that importing a sidechain (S), where 2050 // - S is sidechain, containing blocks [Sn...Sm] 2051 // - C is canon chain, containing blocks [G..Cn..Cm] 2052 // - The common ancestor Cc is pruned 2053 // - The first block in S: Sn, is == Cn 2054 // 2055 // That is: the sidechain for import contains some blocks already present in canon chain. 2056 // So the blocks are: 2057 // 2058 // [ Cn, Cn+1, Cc, Sn+3 ... Sm] 2059 // ^ ^ ^ pruned 2060 func TestPrunedImportSide(t *testing.T) { 2061 //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) 2062 //glogger.Verbosity(3) 2063 //log.Root().SetHandler(log.Handler(glogger)) 2064 testSideImport(t, 3, 3, -1) 2065 testSideImport(t, 3, -3, -1) 2066 testSideImport(t, 10, 0, -1) 2067 testSideImport(t, 1, 10, -1) 2068 testSideImport(t, 1, -10, -1) 2069 } 2070 2071 func TestPrunedImportSideWithMerging(t *testing.T) { 2072 //glogger := log.NewGlogHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false))) 2073 //glogger.Verbosity(3) 2074 //log.Root().SetHandler(log.Handler(glogger)) 2075 testSideImport(t, 3, 3, 0) 2076 testSideImport(t, 3, -3, 0) 2077 testSideImport(t, 10, 0, 0) 2078 testSideImport(t, 1, 10, 0) 2079 testSideImport(t, 1, -10, 0) 2080 2081 testSideImport(t, 3, 3, 1) 2082 testSideImport(t, 3, -3, 1) 2083 testSideImport(t, 10, 0, 1) 2084 testSideImport(t, 1, 10, 1) 2085 testSideImport(t, 1, -10, 1) 2086 } 2087 2088 func TestInsertKnownHeaders(t *testing.T) { testInsertKnownChainData(t, "headers") } 2089 func TestInsertKnownReceiptChain(t *testing.T) { testInsertKnownChainData(t, "receipts") } 2090 func TestInsertKnownBlocks(t *testing.T) { testInsertKnownChainData(t, "blocks") } 2091 2092 func testInsertKnownChainData(t *testing.T, typ string) { 2093 engine := ethash.NewFaker() 2094 genesis := &Genesis{ 2095 Config: params.TestChainConfig, 2096 BaseFee: big.NewInt(params.InitialBaseFee), 2097 } 2098 genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 2099 2100 // A longer chain but total difficulty is lower. 2101 blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 2102 2103 // A shorter chain but total difficulty is higher. 2104 blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) { 2105 b.SetCoinbase(common.Address{1}) 2106 b.OffsetTime(-9) // A higher difficulty 2107 }) 2108 // Import the shared chain and the original canonical one 2109 chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 2110 if err != nil { 2111 t.Fatalf("failed to create temp freezer db: %v", err) 2112 } 2113 defer chaindb.Close() 2114 2115 chain, err := NewBlockChain(chaindb, nil, genesis, nil, engine, vm.Config{}, nil, nil) 2116 if err != nil { 2117 t.Fatalf("failed to create tester chain: %v", err) 2118 } 2119 defer chain.Stop() 2120 2121 var ( 2122 inserter func(blocks []*types.Block, receipts []types.Receipts) error 2123 asserter func(t *testing.T, block *types.Block) 2124 ) 2125 if typ == "headers" { 2126 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2127 headers := make([]*types.Header, 0, len(blocks)) 2128 for _, block := range blocks { 2129 headers = append(headers, block.Header()) 2130 } 2131 _, err := chain.InsertHeaderChain(headers, 1) 2132 return err 2133 } 2134 asserter = func(t *testing.T, block *types.Block) { 2135 if chain.CurrentHeader().Hash() != block.Hash() { 2136 t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex()) 2137 } 2138 } 2139 } else if typ == "receipts" { 2140 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2141 headers := make([]*types.Header, 0, len(blocks)) 2142 for _, block := range blocks { 2143 headers = append(headers, block.Header()) 2144 } 2145 _, err := chain.InsertHeaderChain(headers, 1) 2146 if err != nil { 2147 return err 2148 } 2149 _, err = chain.InsertReceiptChain(blocks, receipts, 0) 2150 return err 2151 } 2152 asserter = func(t *testing.T, block *types.Block) { 2153 if chain.CurrentFastBlock().Hash() != block.Hash() { 2154 t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex()) 2155 } 2156 } 2157 } else { 2158 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2159 _, err := chain.InsertChain(blocks) 2160 return err 2161 } 2162 asserter = func(t *testing.T, block *types.Block) { 2163 if chain.CurrentBlock().Hash() != block.Hash() { 2164 t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex()) 2165 } 2166 } 2167 } 2168 2169 if err := inserter(blocks, receipts); err != nil { 2170 t.Fatalf("failed to insert chain data: %v", err) 2171 } 2172 2173 // Reimport the chain data again. All the imported 2174 // chain data are regarded "known" data. 2175 if err := inserter(blocks, receipts); err != nil { 2176 t.Fatalf("failed to insert chain data: %v", err) 2177 } 2178 asserter(t, blocks[len(blocks)-1]) 2179 2180 // Import a long canonical chain with some known data as prefix. 2181 rollback := blocks[len(blocks)/2].NumberU64() 2182 2183 chain.SetHead(rollback - 1) 2184 if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil { 2185 t.Fatalf("failed to insert chain data: %v", err) 2186 } 2187 asserter(t, blocks2[len(blocks2)-1]) 2188 2189 // Import a heavier shorter but higher total difficulty chain with some known data as prefix. 2190 if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil { 2191 t.Fatalf("failed to insert chain data: %v", err) 2192 } 2193 asserter(t, blocks3[len(blocks3)-1]) 2194 2195 // Import a longer but lower total difficulty chain with some known data as prefix. 2196 if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil { 2197 t.Fatalf("failed to insert chain data: %v", err) 2198 } 2199 // The head shouldn't change. 2200 asserter(t, blocks3[len(blocks3)-1]) 2201 2202 // Rollback the heavier chain and re-insert the longer chain again 2203 chain.SetHead(rollback - 1) 2204 if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil { 2205 t.Fatalf("failed to insert chain data: %v", err) 2206 } 2207 asserter(t, blocks2[len(blocks2)-1]) 2208 } 2209 2210 func TestInsertKnownHeadersWithMerging(t *testing.T) { 2211 testInsertKnownChainDataWithMerging(t, "headers", 0) 2212 } 2213 func TestInsertKnownReceiptChainWithMerging(t *testing.T) { 2214 testInsertKnownChainDataWithMerging(t, "receipts", 0) 2215 } 2216 func TestInsertKnownBlocksWithMerging(t *testing.T) { 2217 testInsertKnownChainDataWithMerging(t, "blocks", 0) 2218 } 2219 func TestInsertKnownHeadersAfterMerging(t *testing.T) { 2220 testInsertKnownChainDataWithMerging(t, "headers", 1) 2221 } 2222 func TestInsertKnownReceiptChainAfterMerging(t *testing.T) { 2223 testInsertKnownChainDataWithMerging(t, "receipts", 1) 2224 } 2225 func TestInsertKnownBlocksAfterMerging(t *testing.T) { 2226 testInsertKnownChainDataWithMerging(t, "blocks", 1) 2227 } 2228 2229 // mergeHeight can be assigned in these values: 2230 // 0: means the merging is applied since genesis 2231 // 1: means the merging is applied after the first segment 2232 func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight int) { 2233 // Copy the TestChainConfig so we can modify it during tests 2234 chainConfig := *params.TestChainConfig 2235 var ( 2236 genesis = &Genesis{ 2237 BaseFee: big.NewInt(params.InitialBaseFee), 2238 Config: &chainConfig, 2239 } 2240 engine = beacon.New(ethash.NewFaker()) 2241 mergeBlock = uint64(math.MaxUint64) 2242 ) 2243 // Apply merging since genesis 2244 if mergeHeight == 0 { 2245 genesis.Config.TerminalTotalDifficulty = big.NewInt(0) 2246 mergeBlock = uint64(0) 2247 } 2248 2249 genDb, blocks, receipts := GenerateChainWithGenesis(genesis, engine, 32, 2250 func(i int, b *BlockGen) { 2251 if b.header.Number.Uint64() >= mergeBlock { 2252 b.SetPoS() 2253 } 2254 b.SetCoinbase(common.Address{1}) 2255 }) 2256 2257 // Apply merging after the first segment 2258 if mergeHeight == 1 { 2259 // TTD is genesis diff + blocks 2260 ttd := big.NewInt(1 + int64(len(blocks))) 2261 ttd.Mul(ttd, params.GenesisDifficulty) 2262 genesis.Config.TerminalTotalDifficulty = ttd 2263 mergeBlock = uint64(len(blocks)) 2264 } 2265 // Longer chain and shorter chain 2266 blocks2, receipts2 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 65, func(i int, b *BlockGen) { 2267 b.SetCoinbase(common.Address{1}) 2268 if b.header.Number.Uint64() >= mergeBlock { 2269 b.SetPoS() 2270 } 2271 }) 2272 blocks3, receipts3 := GenerateChain(genesis.Config, blocks[len(blocks)-1], engine, genDb, 64, func(i int, b *BlockGen) { 2273 b.SetCoinbase(common.Address{1}) 2274 b.OffsetTime(-9) // Time shifted, difficulty shouldn't be changed 2275 if b.header.Number.Uint64() >= mergeBlock { 2276 b.SetPoS() 2277 } 2278 }) 2279 // Import the shared chain and the original canonical one 2280 chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 2281 if err != nil { 2282 t.Fatalf("failed to create temp freezer db: %v", err) 2283 } 2284 defer chaindb.Close() 2285 2286 chain, err := NewBlockChain(chaindb, nil, genesis, nil, engine, vm.Config{}, nil, nil) 2287 if err != nil { 2288 t.Fatalf("failed to create tester chain: %v", err) 2289 } 2290 defer chain.Stop() 2291 2292 var ( 2293 inserter func(blocks []*types.Block, receipts []types.Receipts) error 2294 asserter func(t *testing.T, block *types.Block) 2295 ) 2296 if typ == "headers" { 2297 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2298 headers := make([]*types.Header, 0, len(blocks)) 2299 for _, block := range blocks { 2300 headers = append(headers, block.Header()) 2301 } 2302 i, err := chain.InsertHeaderChain(headers, 1) 2303 if err != nil { 2304 return fmt.Errorf("index %d, number %d: %w", i, headers[i].Number, err) 2305 } 2306 return err 2307 } 2308 asserter = func(t *testing.T, block *types.Block) { 2309 if chain.CurrentHeader().Hash() != block.Hash() { 2310 t.Fatalf("current head header mismatch, have %v, want %v", chain.CurrentHeader().Hash().Hex(), block.Hash().Hex()) 2311 } 2312 } 2313 } else if typ == "receipts" { 2314 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2315 headers := make([]*types.Header, 0, len(blocks)) 2316 for _, block := range blocks { 2317 headers = append(headers, block.Header()) 2318 } 2319 i, err := chain.InsertHeaderChain(headers, 1) 2320 if err != nil { 2321 return fmt.Errorf("index %d: %w", i, err) 2322 } 2323 _, err = chain.InsertReceiptChain(blocks, receipts, 0) 2324 return err 2325 } 2326 asserter = func(t *testing.T, block *types.Block) { 2327 if chain.CurrentFastBlock().Hash() != block.Hash() { 2328 t.Fatalf("current head fast block mismatch, have %v, want %v", chain.CurrentFastBlock().Hash().Hex(), block.Hash().Hex()) 2329 } 2330 } 2331 } else { 2332 inserter = func(blocks []*types.Block, receipts []types.Receipts) error { 2333 i, err := chain.InsertChain(blocks) 2334 if err != nil { 2335 return fmt.Errorf("index %d: %w", i, err) 2336 } 2337 return nil 2338 } 2339 asserter = func(t *testing.T, block *types.Block) { 2340 if chain.CurrentBlock().Hash() != block.Hash() { 2341 t.Fatalf("current head block mismatch, have %v, want %v", chain.CurrentBlock().Hash().Hex(), block.Hash().Hex()) 2342 } 2343 } 2344 } 2345 if err := inserter(blocks, receipts); err != nil { 2346 t.Fatalf("failed to insert chain data: %v", err) 2347 } 2348 2349 // Reimport the chain data again. All the imported 2350 // chain data are regarded "known" data. 2351 if err := inserter(blocks, receipts); err != nil { 2352 t.Fatalf("failed to insert chain data: %v", err) 2353 } 2354 asserter(t, blocks[len(blocks)-1]) 2355 2356 // Import a long canonical chain with some known data as prefix. 2357 rollback := blocks[len(blocks)/2].NumberU64() 2358 chain.SetHead(rollback - 1) 2359 if err := inserter(blocks, receipts); err != nil { 2360 t.Fatalf("failed to insert chain data: %v", err) 2361 } 2362 asserter(t, blocks[len(blocks)-1]) 2363 2364 // Import a longer chain with some known data as prefix. 2365 if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil { 2366 t.Fatalf("failed to insert chain data: %v", err) 2367 } 2368 asserter(t, blocks2[len(blocks2)-1]) 2369 2370 // Import a shorter chain with some known data as prefix. 2371 // The reorg is expected since the fork choice rule is 2372 // already changed. 2373 if err := inserter(append(blocks, blocks3...), append(receipts, receipts3...)); err != nil { 2374 t.Fatalf("failed to insert chain data: %v", err) 2375 } 2376 // The head shouldn't change. 2377 asserter(t, blocks3[len(blocks3)-1]) 2378 2379 // Reimport the longer chain again, the reorg is still expected 2380 chain.SetHead(rollback - 1) 2381 if err := inserter(append(blocks, blocks2...), append(receipts, receipts2...)); err != nil { 2382 t.Fatalf("failed to insert chain data: %v", err) 2383 } 2384 asserter(t, blocks2[len(blocks2)-1]) 2385 } 2386 2387 // getLongAndShortChains returns two chains: A is longer, B is heavier. 2388 func getLongAndShortChains() (*BlockChain, []*types.Block, []*types.Block, *Genesis, error) { 2389 // Generate a canonical chain to act as the main dataset 2390 engine := ethash.NewFaker() 2391 genesis := &Genesis{ 2392 Config: params.TestChainConfig, 2393 BaseFee: big.NewInt(params.InitialBaseFee), 2394 } 2395 // Generate and import the canonical chain, 2396 // Offset the time, to keep the difficulty low 2397 genDb, longChain, _ := GenerateChainWithGenesis(genesis, engine, 80, func(i int, b *BlockGen) { 2398 b.SetCoinbase(common.Address{1}) 2399 }) 2400 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 2401 if err != nil { 2402 return nil, nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err) 2403 } 2404 // Generate fork chain, make it shorter than canon, with common ancestor pretty early 2405 parentIndex := 3 2406 parent := longChain[parentIndex] 2407 heavyChainExt, _ := GenerateChain(genesis.Config, parent, engine, genDb, 75, func(i int, b *BlockGen) { 2408 b.SetCoinbase(common.Address{2}) 2409 b.OffsetTime(-9) 2410 }) 2411 var heavyChain []*types.Block 2412 heavyChain = append(heavyChain, longChain[:parentIndex+1]...) 2413 heavyChain = append(heavyChain, heavyChainExt...) 2414 2415 // Verify that the test is sane 2416 var ( 2417 longerTd = new(big.Int) 2418 shorterTd = new(big.Int) 2419 ) 2420 for index, b := range longChain { 2421 longerTd.Add(longerTd, b.Difficulty()) 2422 if index <= parentIndex { 2423 shorterTd.Add(shorterTd, b.Difficulty()) 2424 } 2425 } 2426 for _, b := range heavyChain { 2427 shorterTd.Add(shorterTd, b.Difficulty()) 2428 } 2429 if shorterTd.Cmp(longerTd) <= 0 { 2430 return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain td (%v) must be larger than canon td (%v)", shorterTd, longerTd) 2431 } 2432 longerNum := longChain[len(longChain)-1].NumberU64() 2433 shorterNum := heavyChain[len(heavyChain)-1].NumberU64() 2434 if shorterNum >= longerNum { 2435 return nil, nil, nil, nil, fmt.Errorf("test is moot, heavyChain num (%v) must be lower than canon num (%v)", shorterNum, longerNum) 2436 } 2437 return chain, longChain, heavyChain, genesis, nil 2438 } 2439 2440 // TestReorgToShorterRemovesCanonMapping tests that if we 2441 // 1. Have a chain [0 ... N .. X] 2442 // 2. Reorg to shorter but heavier chain [0 ... N ... Y] 2443 // 3. Then there should be no canon mapping for the block at height X 2444 // 4. The forked block should still be retrievable by hash 2445 func TestReorgToShorterRemovesCanonMapping(t *testing.T) { 2446 chain, canonblocks, sideblocks, _, err := getLongAndShortChains() 2447 if err != nil { 2448 t.Fatal(err) 2449 } 2450 defer chain.Stop() 2451 2452 if n, err := chain.InsertChain(canonblocks); err != nil { 2453 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 2454 } 2455 canonNum := chain.CurrentBlock().NumberU64() 2456 canonHash := chain.CurrentBlock().Hash() 2457 _, err = chain.InsertChain(sideblocks) 2458 if err != nil { 2459 t.Errorf("Got error, %v", err) 2460 } 2461 head := chain.CurrentBlock() 2462 if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() { 2463 t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) 2464 } 2465 // We have now inserted a sidechain. 2466 if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil { 2467 t.Errorf("expected block to be gone: %v", blockByNum.NumberU64()) 2468 } 2469 if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { 2470 t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) 2471 } 2472 if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil { 2473 t.Errorf("expected block to be present: %x", blockByHash.Hash()) 2474 } 2475 if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil { 2476 t.Errorf("expected header to be present: %x", headerByHash.Hash()) 2477 } 2478 } 2479 2480 // TestReorgToShorterRemovesCanonMappingHeaderChain is the same scenario 2481 // as TestReorgToShorterRemovesCanonMapping, but applied on headerchain 2482 // imports -- that is, for fast sync 2483 func TestReorgToShorterRemovesCanonMappingHeaderChain(t *testing.T) { 2484 chain, canonblocks, sideblocks, _, err := getLongAndShortChains() 2485 if err != nil { 2486 t.Fatal(err) 2487 } 2488 defer chain.Stop() 2489 2490 // Convert into headers 2491 canonHeaders := make([]*types.Header, len(canonblocks)) 2492 for i, block := range canonblocks { 2493 canonHeaders[i] = block.Header() 2494 } 2495 if n, err := chain.InsertHeaderChain(canonHeaders, 0); err != nil { 2496 t.Fatalf("header %d: failed to insert into chain: %v", n, err) 2497 } 2498 canonNum := chain.CurrentHeader().Number.Uint64() 2499 canonHash := chain.CurrentBlock().Hash() 2500 sideHeaders := make([]*types.Header, len(sideblocks)) 2501 for i, block := range sideblocks { 2502 sideHeaders[i] = block.Header() 2503 } 2504 if n, err := chain.InsertHeaderChain(sideHeaders, 0); err != nil { 2505 t.Fatalf("header %d: failed to insert into chain: %v", n, err) 2506 } 2507 head := chain.CurrentHeader() 2508 if got := sideblocks[len(sideblocks)-1].Hash(); got != head.Hash() { 2509 t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) 2510 } 2511 // We have now inserted a sidechain. 2512 if blockByNum := chain.GetBlockByNumber(canonNum); blockByNum != nil { 2513 t.Errorf("expected block to be gone: %v", blockByNum.NumberU64()) 2514 } 2515 if headerByNum := chain.GetHeaderByNumber(canonNum); headerByNum != nil { 2516 t.Errorf("expected header to be gone: %v", headerByNum.Number.Uint64()) 2517 } 2518 if blockByHash := chain.GetBlockByHash(canonHash); blockByHash == nil { 2519 t.Errorf("expected block to be present: %x", blockByHash.Hash()) 2520 } 2521 if headerByHash := chain.GetHeaderByHash(canonHash); headerByHash == nil { 2522 t.Errorf("expected header to be present: %x", headerByHash.Hash()) 2523 } 2524 } 2525 2526 func TestTransactionIndices(t *testing.T) { 2527 // Configure and generate a sample block chain 2528 var ( 2529 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 2530 address = crypto.PubkeyToAddress(key.PublicKey) 2531 funds = big.NewInt(100000000000000000) 2532 gspec = &Genesis{ 2533 Config: params.TestChainConfig, 2534 Alloc: GenesisAlloc{address: {Balance: funds}}, 2535 BaseFee: big.NewInt(params.InitialBaseFee), 2536 } 2537 signer = types.LatestSigner(gspec.Config) 2538 ) 2539 _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) { 2540 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) 2541 if err != nil { 2542 panic(err) 2543 } 2544 block.AddTx(tx) 2545 }) 2546 2547 check := func(tail *uint64, chain *BlockChain) { 2548 stored := rawdb.ReadTxIndexTail(chain.db) 2549 if tail == nil && stored != nil { 2550 t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored) 2551 } 2552 if tail != nil && *stored != *tail { 2553 t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored) 2554 } 2555 if tail != nil { 2556 for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ { 2557 block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i) 2558 if block.Transactions().Len() == 0 { 2559 continue 2560 } 2561 for _, tx := range block.Transactions() { 2562 if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil { 2563 t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex()) 2564 } 2565 } 2566 } 2567 for i := uint64(0); i < *tail; i++ { 2568 block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i) 2569 if block.Transactions().Len() == 0 { 2570 continue 2571 } 2572 for _, tx := range block.Transactions() { 2573 if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil { 2574 t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex()) 2575 } 2576 } 2577 } 2578 } 2579 } 2580 // Init block chain with external ancients, check all needed indices has been indexed. 2581 limit := []uint64{0, 32, 64, 128} 2582 for _, l := range limit { 2583 frdir := t.TempDir() 2584 ancientDb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false) 2585 rawdb.WriteAncientBlocks(ancientDb, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) 2586 2587 l := l 2588 chain, err := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l) 2589 if err != nil { 2590 t.Fatalf("failed to create tester chain: %v", err) 2591 } 2592 chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{})) 2593 2594 var tail uint64 2595 if l != 0 { 2596 tail = uint64(128) - l + 1 2597 } 2598 check(&tail, chain) 2599 chain.Stop() 2600 ancientDb.Close() 2601 os.RemoveAll(frdir) 2602 } 2603 2604 // Reconstruct a block chain which only reserves HEAD-64 tx indices 2605 ancientDb, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 2606 defer ancientDb.Close() 2607 2608 rawdb.WriteAncientBlocks(ancientDb, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) 2609 limit = []uint64{0, 64 /* drop stale */, 32 /* shorten history */, 64 /* extend history */, 0 /* restore all */} 2610 for _, l := range limit { 2611 l := l 2612 chain, err := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l) 2613 if err != nil { 2614 t.Fatalf("failed to create tester chain: %v", err) 2615 } 2616 var tail uint64 2617 if l != 0 { 2618 tail = uint64(128) - l + 1 2619 } 2620 chain.indexBlocks(rawdb.ReadTxIndexTail(ancientDb), 128, make(chan struct{})) 2621 check(&tail, chain) 2622 chain.Stop() 2623 } 2624 } 2625 2626 func TestSkipStaleTxIndicesInSnapSync(t *testing.T) { 2627 // Configure and generate a sample block chain 2628 var ( 2629 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 2630 address = crypto.PubkeyToAddress(key.PublicKey) 2631 funds = big.NewInt(100000000000000000) 2632 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} 2633 signer = types.LatestSigner(gspec.Config) 2634 ) 2635 _, blocks, receipts := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 128, func(i int, block *BlockGen) { 2636 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, block.header.BaseFee, nil), signer, key) 2637 if err != nil { 2638 panic(err) 2639 } 2640 block.AddTx(tx) 2641 }) 2642 2643 check := func(tail *uint64, chain *BlockChain) { 2644 stored := rawdb.ReadTxIndexTail(chain.db) 2645 if tail == nil && stored != nil { 2646 t.Fatalf("Oldest indexded block mismatch, want nil, have %d", *stored) 2647 } 2648 if tail != nil && *stored != *tail { 2649 t.Fatalf("Oldest indexded block mismatch, want %d, have %d", *tail, *stored) 2650 } 2651 if tail != nil { 2652 for i := *tail; i <= chain.CurrentBlock().NumberU64(); i++ { 2653 block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i) 2654 if block.Transactions().Len() == 0 { 2655 continue 2656 } 2657 for _, tx := range block.Transactions() { 2658 if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index == nil { 2659 t.Fatalf("Miss transaction indice, number %d hash %s", i, tx.Hash().Hex()) 2660 } 2661 } 2662 } 2663 for i := uint64(0); i < *tail; i++ { 2664 block := rawdb.ReadBlock(chain.db, rawdb.ReadCanonicalHash(chain.db, i), i) 2665 if block.Transactions().Len() == 0 { 2666 continue 2667 } 2668 for _, tx := range block.Transactions() { 2669 if index := rawdb.ReadTxLookupEntry(chain.db, tx.Hash()); index != nil { 2670 t.Fatalf("Transaction indice should be deleted, number %d hash %s", i, tx.Hash().Hex()) 2671 } 2672 } 2673 } 2674 } 2675 } 2676 2677 ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), t.TempDir(), "", false) 2678 if err != nil { 2679 t.Fatalf("failed to create temp freezer db: %v", err) 2680 } 2681 defer ancientDb.Close() 2682 2683 // Import all blocks into ancient db, only HEAD-32 indices are kept. 2684 l := uint64(32) 2685 chain, err := NewBlockChain(ancientDb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, &l) 2686 if err != nil { 2687 t.Fatalf("failed to create tester chain: %v", err) 2688 } 2689 defer chain.Stop() 2690 2691 headers := make([]*types.Header, len(blocks)) 2692 for i, block := range blocks { 2693 headers[i] = block.Header() 2694 } 2695 if n, err := chain.InsertHeaderChain(headers, 0); err != nil { 2696 t.Fatalf("failed to insert header %d: %v", n, err) 2697 } 2698 // The indices before ancient-N(32) should be ignored. After that all blocks should be indexed. 2699 if n, err := chain.InsertReceiptChain(blocks, receipts, 64); err != nil { 2700 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 2701 } 2702 tail := uint64(32) 2703 check(&tail, chain) 2704 } 2705 2706 // Benchmarks large blocks with value transfers to non-existing accounts 2707 func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) { 2708 var ( 2709 signer = types.HomesteadSigner{} 2710 testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 2711 testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) 2712 bankFunds = big.NewInt(100000000000000000) 2713 gspec = &Genesis{ 2714 Config: params.TestChainConfig, 2715 Alloc: GenesisAlloc{ 2716 testBankAddress: {Balance: bankFunds}, 2717 common.HexToAddress("0xc0de"): { 2718 Code: []byte{0x60, 0x01, 0x50}, 2719 Balance: big.NewInt(0), 2720 }, // push 1, pop 2721 }, 2722 GasLimit: 100e6, // 100 M 2723 } 2724 ) 2725 // Generate the original common chain segment and the two competing forks 2726 engine := ethash.NewFaker() 2727 2728 blockGenerator := func(i int, block *BlockGen) { 2729 block.SetCoinbase(common.Address{1}) 2730 for txi := 0; txi < numTxs; txi++ { 2731 uniq := uint64(i*numTxs + txi) 2732 recipient := recipientFn(uniq) 2733 tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, block.header.BaseFee, nil), signer, testBankKey) 2734 if err != nil { 2735 b.Error(err) 2736 } 2737 block.AddTx(tx) 2738 } 2739 } 2740 2741 _, shared, _ := GenerateChainWithGenesis(gspec, engine, numBlocks, blockGenerator) 2742 b.StopTimer() 2743 b.ResetTimer() 2744 for i := 0; i < b.N; i++ { 2745 // Import the shared chain and the original canonical one 2746 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 2747 if err != nil { 2748 b.Fatalf("failed to create tester chain: %v", err) 2749 } 2750 b.StartTimer() 2751 if _, err := chain.InsertChain(shared); err != nil { 2752 b.Fatalf("failed to insert shared chain: %v", err) 2753 } 2754 b.StopTimer() 2755 if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks { 2756 b.Fatalf("Transactions were not included, expected %d, got %d", numTxs*numBlocks, got) 2757 } 2758 } 2759 } 2760 2761 func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { 2762 var ( 2763 numTxs = 1000 2764 numBlocks = 1 2765 ) 2766 recipientFn := func(nonce uint64) common.Address { 2767 return common.BigToAddress(new(big.Int).SetUint64(1337 + nonce)) 2768 } 2769 dataFn := func(nonce uint64) []byte { 2770 return nil 2771 } 2772 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 2773 } 2774 2775 func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { 2776 var ( 2777 numTxs = 1000 2778 numBlocks = 1 2779 ) 2780 b.StopTimer() 2781 b.ResetTimer() 2782 2783 recipientFn := func(nonce uint64) common.Address { 2784 return common.BigToAddress(new(big.Int).SetUint64(1337)) 2785 } 2786 dataFn := func(nonce uint64) []byte { 2787 return nil 2788 } 2789 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 2790 } 2791 2792 func BenchmarkBlockChain_1x1000Executions(b *testing.B) { 2793 var ( 2794 numTxs = 1000 2795 numBlocks = 1 2796 ) 2797 b.StopTimer() 2798 b.ResetTimer() 2799 2800 recipientFn := func(nonce uint64) common.Address { 2801 return common.BigToAddress(new(big.Int).SetUint64(0xc0de)) 2802 } 2803 dataFn := func(nonce uint64) []byte { 2804 return nil 2805 } 2806 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 2807 } 2808 2809 // Tests that importing a some old blocks, where all blocks are before the 2810 // pruning point. 2811 // This internally leads to a sidechain import, since the blocks trigger an 2812 // ErrPrunedAncestor error. 2813 // This may e.g. happen if 2814 // 1. Downloader rollbacks a batch of inserted blocks and exits 2815 // 2. Downloader starts to sync again 2816 // 3. The blocks fetched are all known and canonical blocks 2817 func TestSideImportPrunedBlocks(t *testing.T) { 2818 // Generate a canonical chain to act as the main dataset 2819 engine := ethash.NewFaker() 2820 genesis := &Genesis{ 2821 Config: params.TestChainConfig, 2822 BaseFee: big.NewInt(params.InitialBaseFee), 2823 } 2824 // Generate and import the canonical chain 2825 _, blocks, _ := GenerateChainWithGenesis(genesis, engine, 2*TriesInMemory, nil) 2826 2827 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, genesis, nil, engine, vm.Config{}, nil, nil) 2828 if err != nil { 2829 t.Fatalf("failed to create tester chain: %v", err) 2830 } 2831 defer chain.Stop() 2832 2833 if n, err := chain.InsertChain(blocks); err != nil { 2834 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 2835 } 2836 2837 lastPrunedIndex := len(blocks) - TriesInMemory - 1 2838 lastPrunedBlock := blocks[lastPrunedIndex] 2839 2840 // Verify pruning of lastPrunedBlock 2841 if chain.HasBlockAndState(lastPrunedBlock.Hash(), lastPrunedBlock.NumberU64()) { 2842 t.Errorf("Block %d not pruned", lastPrunedBlock.NumberU64()) 2843 } 2844 firstNonPrunedBlock := blocks[len(blocks)-TriesInMemory] 2845 // Verify firstNonPrunedBlock is not pruned 2846 if !chain.HasBlockAndState(firstNonPrunedBlock.Hash(), firstNonPrunedBlock.NumberU64()) { 2847 t.Errorf("Block %d pruned", firstNonPrunedBlock.NumberU64()) 2848 } 2849 // Now re-import some old blocks 2850 blockToReimport := blocks[5:8] 2851 _, err = chain.InsertChain(blockToReimport) 2852 if err != nil { 2853 t.Errorf("Got error, %v", err) 2854 } 2855 } 2856 2857 // TestDeleteCreateRevert tests a weird state transition corner case that we hit 2858 // while changing the internals of statedb. The workflow is that a contract is 2859 // self destructed, then in a followup transaction (but same block) it's created 2860 // again and the transaction reverted. 2861 // 2862 // The original statedb implementation flushed dirty objects to the tries after 2863 // each transaction, so this works ok. The rework accumulated writes in memory 2864 // first, but the journal wiped the entire state object on create-revert. 2865 func TestDeleteCreateRevert(t *testing.T) { 2866 var ( 2867 aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") 2868 bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") 2869 engine = ethash.NewFaker() 2870 2871 // A sender who makes transactions, has some funds 2872 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 2873 address = crypto.PubkeyToAddress(key.PublicKey) 2874 funds = big.NewInt(100000000000000000) 2875 gspec = &Genesis{ 2876 Config: params.TestChainConfig, 2877 Alloc: GenesisAlloc{ 2878 address: {Balance: funds}, 2879 // The address 0xAAAAA selfdestructs if called 2880 aa: { 2881 // Code needs to just selfdestruct 2882 Code: []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)}, 2883 Nonce: 1, 2884 Balance: big.NewInt(0), 2885 }, 2886 // The address 0xBBBB send 1 wei to 0xAAAA, then reverts 2887 bb: { 2888 Code: []byte{ 2889 byte(vm.PC), // [0] 2890 byte(vm.DUP1), // [0,0] 2891 byte(vm.DUP1), // [0,0,0] 2892 byte(vm.DUP1), // [0,0,0,0] 2893 byte(vm.PUSH1), 0x01, // [0,0,0,0,1] (value) 2894 byte(vm.PUSH2), 0xaa, 0xaa, // [0,0,0,0,1, 0xaaaa] 2895 byte(vm.GAS), 2896 byte(vm.CALL), 2897 byte(vm.REVERT), 2898 }, 2899 Balance: big.NewInt(1), 2900 }, 2901 }, 2902 } 2903 ) 2904 2905 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 2906 b.SetCoinbase(common.Address{1}) 2907 // One transaction to AAAA 2908 tx, _ := types.SignTx(types.NewTransaction(0, aa, 2909 big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 2910 b.AddTx(tx) 2911 // One transaction to BBBB 2912 tx, _ = types.SignTx(types.NewTransaction(1, bb, 2913 big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 2914 b.AddTx(tx) 2915 }) 2916 // Import the canonical chain 2917 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 2918 if err != nil { 2919 t.Fatalf("failed to create tester chain: %v", err) 2920 } 2921 defer chain.Stop() 2922 2923 if n, err := chain.InsertChain(blocks); err != nil { 2924 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 2925 } 2926 } 2927 2928 // TestDeleteRecreateSlots tests a state-transition that contains both deletion 2929 // and recreation of contract state. 2930 // Contract A exists, has slots 1 and 2 set 2931 // Tx 1: Selfdestruct A 2932 // Tx 2: Re-create A, set slots 3 and 4 2933 // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct, 2934 // and then the new slots exist 2935 func TestDeleteRecreateSlots(t *testing.T) { 2936 var ( 2937 engine = ethash.NewFaker() 2938 2939 // A sender who makes transactions, has some funds 2940 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 2941 address = crypto.PubkeyToAddress(key.PublicKey) 2942 funds = big.NewInt(1000000000000000) 2943 bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") 2944 aaStorage = make(map[common.Hash]common.Hash) // Initial storage in AA 2945 aaCode = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct) 2946 ) 2947 // Populate two slots 2948 aaStorage[common.HexToHash("01")] = common.HexToHash("01") 2949 aaStorage[common.HexToHash("02")] = common.HexToHash("02") 2950 2951 // The bb-code needs to CREATE2 the aa contract. It consists of 2952 // both initcode and deployment code 2953 // initcode: 2954 // 1. Set slots 3=3, 4=4, 2955 // 2. Return aaCode 2956 2957 initCode := []byte{ 2958 byte(vm.PUSH1), 0x3, // value 2959 byte(vm.PUSH1), 0x3, // location 2960 byte(vm.SSTORE), // Set slot[3] = 3 2961 byte(vm.PUSH1), 0x4, // value 2962 byte(vm.PUSH1), 0x4, // location 2963 byte(vm.SSTORE), // Set slot[4] = 4 2964 // Slots are set, now return the code 2965 byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack 2966 byte(vm.PUSH1), 0x0, // memory start on stack 2967 byte(vm.MSTORE), 2968 // Code is now in memory. 2969 byte(vm.PUSH1), 0x2, // size 2970 byte(vm.PUSH1), byte(32 - 2), // offset 2971 byte(vm.RETURN), 2972 } 2973 if l := len(initCode); l > 32 { 2974 t.Fatalf("init code is too long for a pushx, need a more elaborate deployer") 2975 } 2976 bbCode := []byte{ 2977 // Push initcode onto stack 2978 byte(vm.PUSH1) + byte(len(initCode)-1)} 2979 bbCode = append(bbCode, initCode...) 2980 bbCode = append(bbCode, []byte{ 2981 byte(vm.PUSH1), 0x0, // memory start on stack 2982 byte(vm.MSTORE), 2983 byte(vm.PUSH1), 0x00, // salt 2984 byte(vm.PUSH1), byte(len(initCode)), // size 2985 byte(vm.PUSH1), byte(32 - len(initCode)), // offset 2986 byte(vm.PUSH1), 0x00, // endowment 2987 byte(vm.CREATE2), 2988 }...) 2989 2990 initHash := crypto.Keccak256Hash(initCode) 2991 aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:]) 2992 t.Logf("Destination address: %x\n", aa) 2993 2994 gspec := &Genesis{ 2995 Config: params.TestChainConfig, 2996 Alloc: GenesisAlloc{ 2997 address: {Balance: funds}, 2998 // The address 0xAAAAA selfdestructs if called 2999 aa: { 3000 // Code needs to just selfdestruct 3001 Code: aaCode, 3002 Nonce: 1, 3003 Balance: big.NewInt(0), 3004 Storage: aaStorage, 3005 }, 3006 // The contract BB recreates AA 3007 bb: { 3008 Code: bbCode, 3009 Balance: big.NewInt(1), 3010 }, 3011 }, 3012 } 3013 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 3014 b.SetCoinbase(common.Address{1}) 3015 // One transaction to AA, to kill it 3016 tx, _ := types.SignTx(types.NewTransaction(0, aa, 3017 big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3018 b.AddTx(tx) 3019 // One transaction to BB, to recreate AA 3020 tx, _ = types.SignTx(types.NewTransaction(1, bb, 3021 big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3022 b.AddTx(tx) 3023 }) 3024 // Import the canonical chain 3025 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{ 3026 Debug: true, 3027 Tracer: logger.NewJSONLogger(nil, os.Stdout), 3028 }, nil, nil) 3029 if err != nil { 3030 t.Fatalf("failed to create tester chain: %v", err) 3031 } 3032 defer chain.Stop() 3033 3034 if n, err := chain.InsertChain(blocks); err != nil { 3035 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3036 } 3037 statedb, _ := chain.State() 3038 3039 // If all is correct, then slot 1 and 2 are zero 3040 if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { 3041 t.Errorf("got %x exp %x", got, exp) 3042 } 3043 if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp { 3044 t.Errorf("got %x exp %x", got, exp) 3045 } 3046 // Also, 3 and 4 should be set 3047 if got, exp := statedb.GetState(aa, common.HexToHash("03")), common.HexToHash("03"); got != exp { 3048 t.Fatalf("got %x exp %x", got, exp) 3049 } 3050 if got, exp := statedb.GetState(aa, common.HexToHash("04")), common.HexToHash("04"); got != exp { 3051 t.Fatalf("got %x exp %x", got, exp) 3052 } 3053 } 3054 3055 // TestDeleteRecreateAccount tests a state-transition that contains deletion of a 3056 // contract with storage, and a recreate of the same contract via a 3057 // regular value-transfer 3058 // Expected outcome is that _all_ slots are cleared from A 3059 func TestDeleteRecreateAccount(t *testing.T) { 3060 var ( 3061 engine = ethash.NewFaker() 3062 3063 // A sender who makes transactions, has some funds 3064 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3065 address = crypto.PubkeyToAddress(key.PublicKey) 3066 funds = big.NewInt(1000000000000000) 3067 3068 aa = common.HexToAddress("0x7217d81b76bdd8707601e959454e3d776aee5f43") 3069 aaStorage = make(map[common.Hash]common.Hash) // Initial storage in AA 3070 aaCode = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct) 3071 ) 3072 // Populate two slots 3073 aaStorage[common.HexToHash("01")] = common.HexToHash("01") 3074 aaStorage[common.HexToHash("02")] = common.HexToHash("02") 3075 3076 gspec := &Genesis{ 3077 Config: params.TestChainConfig, 3078 Alloc: GenesisAlloc{ 3079 address: {Balance: funds}, 3080 // The address 0xAAAAA selfdestructs if called 3081 aa: { 3082 // Code needs to just selfdestruct 3083 Code: aaCode, 3084 Nonce: 1, 3085 Balance: big.NewInt(0), 3086 Storage: aaStorage, 3087 }, 3088 }, 3089 } 3090 3091 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 3092 b.SetCoinbase(common.Address{1}) 3093 // One transaction to AA, to kill it 3094 tx, _ := types.SignTx(types.NewTransaction(0, aa, 3095 big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3096 b.AddTx(tx) 3097 // One transaction to AA, to recreate it (but without storage 3098 tx, _ = types.SignTx(types.NewTransaction(1, aa, 3099 big.NewInt(1), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3100 b.AddTx(tx) 3101 }) 3102 // Import the canonical chain 3103 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{ 3104 Debug: true, 3105 Tracer: logger.NewJSONLogger(nil, os.Stdout), 3106 }, nil, nil) 3107 if err != nil { 3108 t.Fatalf("failed to create tester chain: %v", err) 3109 } 3110 defer chain.Stop() 3111 3112 if n, err := chain.InsertChain(blocks); err != nil { 3113 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3114 } 3115 statedb, _ := chain.State() 3116 3117 // If all is correct, then both slots are zero 3118 if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { 3119 t.Errorf("got %x exp %x", got, exp) 3120 } 3121 if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp { 3122 t.Errorf("got %x exp %x", got, exp) 3123 } 3124 } 3125 3126 // TestDeleteRecreateSlotsAcrossManyBlocks tests multiple state-transition that contains both deletion 3127 // and recreation of contract state. 3128 // Contract A exists, has slots 1 and 2 set 3129 // Tx 1: Selfdestruct A 3130 // Tx 2: Re-create A, set slots 3 and 4 3131 // Expected outcome is that _all_ slots are cleared from A, due to the selfdestruct, 3132 // and then the new slots exist 3133 func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { 3134 var ( 3135 engine = ethash.NewFaker() 3136 3137 // A sender who makes transactions, has some funds 3138 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3139 address = crypto.PubkeyToAddress(key.PublicKey) 3140 funds = big.NewInt(1000000000000000) 3141 bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") 3142 aaStorage = make(map[common.Hash]common.Hash) // Initial storage in AA 3143 aaCode = []byte{byte(vm.PC), byte(vm.SELFDESTRUCT)} // Code for AA (simple selfdestruct) 3144 ) 3145 // Populate two slots 3146 aaStorage[common.HexToHash("01")] = common.HexToHash("01") 3147 aaStorage[common.HexToHash("02")] = common.HexToHash("02") 3148 3149 // The bb-code needs to CREATE2 the aa contract. It consists of 3150 // both initcode and deployment code 3151 // initcode: 3152 // 1. Set slots 3=blocknum+1, 4=4, 3153 // 2. Return aaCode 3154 3155 initCode := []byte{ 3156 byte(vm.PUSH1), 0x1, // 3157 byte(vm.NUMBER), // value = number + 1 3158 byte(vm.ADD), // 3159 byte(vm.PUSH1), 0x3, // location 3160 byte(vm.SSTORE), // Set slot[3] = number + 1 3161 byte(vm.PUSH1), 0x4, // value 3162 byte(vm.PUSH1), 0x4, // location 3163 byte(vm.SSTORE), // Set slot[4] = 4 3164 // Slots are set, now return the code 3165 byte(vm.PUSH2), byte(vm.PC), byte(vm.SELFDESTRUCT), // Push code on stack 3166 byte(vm.PUSH1), 0x0, // memory start on stack 3167 byte(vm.MSTORE), 3168 // Code is now in memory. 3169 byte(vm.PUSH1), 0x2, // size 3170 byte(vm.PUSH1), byte(32 - 2), // offset 3171 byte(vm.RETURN), 3172 } 3173 if l := len(initCode); l > 32 { 3174 t.Fatalf("init code is too long for a pushx, need a more elaborate deployer") 3175 } 3176 bbCode := []byte{ 3177 // Push initcode onto stack 3178 byte(vm.PUSH1) + byte(len(initCode)-1)} 3179 bbCode = append(bbCode, initCode...) 3180 bbCode = append(bbCode, []byte{ 3181 byte(vm.PUSH1), 0x0, // memory start on stack 3182 byte(vm.MSTORE), 3183 byte(vm.PUSH1), 0x00, // salt 3184 byte(vm.PUSH1), byte(len(initCode)), // size 3185 byte(vm.PUSH1), byte(32 - len(initCode)), // offset 3186 byte(vm.PUSH1), 0x00, // endowment 3187 byte(vm.CREATE2), 3188 }...) 3189 3190 initHash := crypto.Keccak256Hash(initCode) 3191 aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:]) 3192 t.Logf("Destination address: %x\n", aa) 3193 gspec := &Genesis{ 3194 Config: params.TestChainConfig, 3195 Alloc: GenesisAlloc{ 3196 address: {Balance: funds}, 3197 // The address 0xAAAAA selfdestructs if called 3198 aa: { 3199 // Code needs to just selfdestruct 3200 Code: aaCode, 3201 Nonce: 1, 3202 Balance: big.NewInt(0), 3203 Storage: aaStorage, 3204 }, 3205 // The contract BB recreates AA 3206 bb: { 3207 Code: bbCode, 3208 Balance: big.NewInt(1), 3209 }, 3210 }, 3211 } 3212 var nonce uint64 3213 3214 type expectation struct { 3215 exist bool 3216 blocknum int 3217 values map[int]int 3218 } 3219 var current = &expectation{ 3220 exist: true, // exists in genesis 3221 blocknum: 0, 3222 values: map[int]int{1: 1, 2: 2}, 3223 } 3224 var expectations []*expectation 3225 var newDestruct = func(e *expectation, b *BlockGen) *types.Transaction { 3226 tx, _ := types.SignTx(types.NewTransaction(nonce, aa, 3227 big.NewInt(0), 50000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3228 nonce++ 3229 if e.exist { 3230 e.exist = false 3231 e.values = nil 3232 } 3233 //t.Logf("block %d; adding destruct\n", e.blocknum) 3234 return tx 3235 } 3236 var newResurrect = func(e *expectation, b *BlockGen) *types.Transaction { 3237 tx, _ := types.SignTx(types.NewTransaction(nonce, bb, 3238 big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3239 nonce++ 3240 if !e.exist { 3241 e.exist = true 3242 e.values = map[int]int{3: e.blocknum + 1, 4: 4} 3243 } 3244 //t.Logf("block %d; adding resurrect\n", e.blocknum) 3245 return tx 3246 } 3247 3248 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 150, func(i int, b *BlockGen) { 3249 var exp = new(expectation) 3250 exp.blocknum = i + 1 3251 exp.values = make(map[int]int) 3252 for k, v := range current.values { 3253 exp.values[k] = v 3254 } 3255 exp.exist = current.exist 3256 3257 b.SetCoinbase(common.Address{1}) 3258 if i%2 == 0 { 3259 b.AddTx(newDestruct(exp, b)) 3260 } 3261 if i%3 == 0 { 3262 b.AddTx(newResurrect(exp, b)) 3263 } 3264 if i%5 == 0 { 3265 b.AddTx(newDestruct(exp, b)) 3266 } 3267 if i%7 == 0 { 3268 b.AddTx(newResurrect(exp, b)) 3269 } 3270 expectations = append(expectations, exp) 3271 current = exp 3272 }) 3273 // Import the canonical chain 3274 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{ 3275 //Debug: true, 3276 //Tracer: vm.NewJSONLogger(nil, os.Stdout), 3277 }, nil, nil) 3278 if err != nil { 3279 t.Fatalf("failed to create tester chain: %v", err) 3280 } 3281 defer chain.Stop() 3282 3283 var asHash = func(num int) common.Hash { 3284 return common.BytesToHash([]byte{byte(num)}) 3285 } 3286 for i, block := range blocks { 3287 blockNum := i + 1 3288 if n, err := chain.InsertChain([]*types.Block{block}); err != nil { 3289 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3290 } 3291 statedb, _ := chain.State() 3292 // If all is correct, then slot 1 and 2 are zero 3293 if got, exp := statedb.GetState(aa, common.HexToHash("01")), (common.Hash{}); got != exp { 3294 t.Errorf("block %d, got %x exp %x", blockNum, got, exp) 3295 } 3296 if got, exp := statedb.GetState(aa, common.HexToHash("02")), (common.Hash{}); got != exp { 3297 t.Errorf("block %d, got %x exp %x", blockNum, got, exp) 3298 } 3299 exp := expectations[i] 3300 if exp.exist { 3301 if !statedb.Exist(aa) { 3302 t.Fatalf("block %d, expected %v to exist, it did not", blockNum, aa) 3303 } 3304 for slot, val := range exp.values { 3305 if gotValue, expValue := statedb.GetState(aa, asHash(slot)), asHash(val); gotValue != expValue { 3306 t.Fatalf("block %d, slot %d, got %x exp %x", blockNum, slot, gotValue, expValue) 3307 } 3308 } 3309 } else { 3310 if statedb.Exist(aa) { 3311 t.Fatalf("block %d, expected %v to not exist, it did", blockNum, aa) 3312 } 3313 } 3314 } 3315 } 3316 3317 // TestInitThenFailCreateContract tests a pretty notorious case that happened 3318 // on mainnet over blocks 7338108, 7338110 and 7338115. 3319 // - Block 7338108: address e771789f5cccac282f23bb7add5690e1f6ca467c is initiated 3320 // with 0.001 ether (thus created but no code) 3321 // - Block 7338110: a CREATE2 is attempted. The CREATE2 would deploy code on 3322 // the same address e771789f5cccac282f23bb7add5690e1f6ca467c. However, the 3323 // deployment fails due to OOG during initcode execution 3324 // - Block 7338115: another tx checks the balance of 3325 // e771789f5cccac282f23bb7add5690e1f6ca467c, and the snapshotter returned it as 3326 // zero. 3327 // 3328 // The problem being that the snapshotter maintains a destructset, and adds items 3329 // to the destructset in case something is created "onto" an existing item. 3330 // We need to either roll back the snapDestructs, or not place it into snapDestructs 3331 // in the first place. 3332 func TestInitThenFailCreateContract(t *testing.T) { 3333 var ( 3334 engine = ethash.NewFaker() 3335 3336 // A sender who makes transactions, has some funds 3337 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3338 address = crypto.PubkeyToAddress(key.PublicKey) 3339 funds = big.NewInt(1000000000000000) 3340 bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") 3341 ) 3342 3343 // The bb-code needs to CREATE2 the aa contract. It consists of 3344 // both initcode and deployment code 3345 // initcode: 3346 // 1. If blocknum < 1, error out (e.g invalid opcode) 3347 // 2. else, return a snippet of code 3348 initCode := []byte{ 3349 byte(vm.PUSH1), 0x1, // y (2) 3350 byte(vm.NUMBER), // x (number) 3351 byte(vm.GT), // x > y? 3352 byte(vm.PUSH1), byte(0x8), 3353 byte(vm.JUMPI), // jump to label if number > 2 3354 byte(0xFE), // illegal opcode 3355 byte(vm.JUMPDEST), 3356 byte(vm.PUSH1), 0x2, // size 3357 byte(vm.PUSH1), 0x0, // offset 3358 byte(vm.RETURN), // return 2 bytes of zero-code 3359 } 3360 if l := len(initCode); l > 32 { 3361 t.Fatalf("init code is too long for a pushx, need a more elaborate deployer") 3362 } 3363 bbCode := []byte{ 3364 // Push initcode onto stack 3365 byte(vm.PUSH1) + byte(len(initCode)-1)} 3366 bbCode = append(bbCode, initCode...) 3367 bbCode = append(bbCode, []byte{ 3368 byte(vm.PUSH1), 0x0, // memory start on stack 3369 byte(vm.MSTORE), 3370 byte(vm.PUSH1), 0x00, // salt 3371 byte(vm.PUSH1), byte(len(initCode)), // size 3372 byte(vm.PUSH1), byte(32 - len(initCode)), // offset 3373 byte(vm.PUSH1), 0x00, // endowment 3374 byte(vm.CREATE2), 3375 }...) 3376 3377 initHash := crypto.Keccak256Hash(initCode) 3378 aa := crypto.CreateAddress2(bb, [32]byte{}, initHash[:]) 3379 t.Logf("Destination address: %x\n", aa) 3380 3381 gspec := &Genesis{ 3382 Config: params.TestChainConfig, 3383 Alloc: GenesisAlloc{ 3384 address: {Balance: funds}, 3385 // The address aa has some funds 3386 aa: {Balance: big.NewInt(100000)}, 3387 // The contract BB tries to create code onto AA 3388 bb: { 3389 Code: bbCode, 3390 Balance: big.NewInt(1), 3391 }, 3392 }, 3393 } 3394 nonce := uint64(0) 3395 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 4, func(i int, b *BlockGen) { 3396 b.SetCoinbase(common.Address{1}) 3397 // One transaction to BB 3398 tx, _ := types.SignTx(types.NewTransaction(nonce, bb, 3399 big.NewInt(0), 100000, b.header.BaseFee, nil), types.HomesteadSigner{}, key) 3400 b.AddTx(tx) 3401 nonce++ 3402 }) 3403 3404 // Import the canonical chain 3405 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{ 3406 //Debug: true, 3407 //Tracer: vm.NewJSONLogger(nil, os.Stdout), 3408 }, nil, nil) 3409 if err != nil { 3410 t.Fatalf("failed to create tester chain: %v", err) 3411 } 3412 defer chain.Stop() 3413 3414 statedb, _ := chain.State() 3415 if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 { 3416 t.Fatalf("Genesis err, got %v exp %v", got, exp) 3417 } 3418 // First block tries to create, but fails 3419 { 3420 block := blocks[0] 3421 if _, err := chain.InsertChain([]*types.Block{blocks[0]}); err != nil { 3422 t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) 3423 } 3424 statedb, _ = chain.State() 3425 if got, exp := statedb.GetBalance(aa), big.NewInt(100000); got.Cmp(exp) != 0 { 3426 t.Fatalf("block %d: got %v exp %v", block.NumberU64(), got, exp) 3427 } 3428 } 3429 // Import the rest of the blocks 3430 for _, block := range blocks[1:] { 3431 if _, err := chain.InsertChain([]*types.Block{block}); err != nil { 3432 t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) 3433 } 3434 } 3435 } 3436 3437 // TestEIP2718Transition tests that an EIP-2718 transaction will be accepted 3438 // after the fork block has passed. This is verified by sending an EIP-2930 3439 // access list transaction, which specifies a single slot access, and then 3440 // checking that the gas usage of a hot SLOAD and a cold SLOAD are calculated 3441 // correctly. 3442 func TestEIP2718Transition(t *testing.T) { 3443 var ( 3444 aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") 3445 engine = ethash.NewFaker() 3446 3447 // A sender who makes transactions, has some funds 3448 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3449 address = crypto.PubkeyToAddress(key.PublicKey) 3450 funds = big.NewInt(1000000000000000) 3451 gspec = &Genesis{ 3452 Config: params.TestChainConfig, 3453 Alloc: GenesisAlloc{ 3454 address: {Balance: funds}, 3455 // The address 0xAAAA sloads 0x00 and 0x01 3456 aa: { 3457 Code: []byte{ 3458 byte(vm.PC), 3459 byte(vm.PC), 3460 byte(vm.SLOAD), 3461 byte(vm.SLOAD), 3462 }, 3463 Nonce: 0, 3464 Balance: big.NewInt(0), 3465 }, 3466 }, 3467 } 3468 ) 3469 // Generate blocks 3470 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 3471 b.SetCoinbase(common.Address{1}) 3472 3473 // One transaction to 0xAAAA 3474 signer := types.LatestSigner(gspec.Config) 3475 tx, _ := types.SignNewTx(key, signer, &types.AccessListTx{ 3476 ChainID: gspec.Config.ChainID, 3477 Nonce: 0, 3478 To: &aa, 3479 Gas: 30000, 3480 GasPrice: b.header.BaseFee, 3481 AccessList: types.AccessList{{ 3482 Address: aa, 3483 StorageKeys: []common.Hash{{0}}, 3484 }}, 3485 }) 3486 b.AddTx(tx) 3487 }) 3488 3489 // Import the canonical chain 3490 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 3491 if err != nil { 3492 t.Fatalf("failed to create tester chain: %v", err) 3493 } 3494 defer chain.Stop() 3495 3496 if n, err := chain.InsertChain(blocks); err != nil { 3497 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3498 } 3499 3500 block := chain.GetBlockByNumber(1) 3501 3502 // Expected gas is intrinsic + 2 * pc + hot load + cold load, since only one load is in the access list 3503 expected := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas + 3504 vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929 3505 if block.GasUsed() != expected { 3506 t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expected, block.GasUsed()) 3507 } 3508 } 3509 3510 // TestEIP1559Transition tests the following: 3511 // 3512 // 1. A transaction whose gasFeeCap is greater than the baseFee is valid. 3513 // 2. Gas accounting for access lists on EIP-1559 transactions is correct. 3514 // 3. Only the transaction's tip will be received by the coinbase. 3515 // 4. The transaction sender pays for both the tip and baseFee. 3516 // 5. The coinbase receives only the partially realized tip when 3517 // gasFeeCap - gasTipCap < baseFee. 3518 // 6. Legacy transaction behave as expected (e.g. gasPrice = gasFeeCap = gasTipCap). 3519 func TestEIP1559Transition(t *testing.T) { 3520 var ( 3521 aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") 3522 engine = ethash.NewFaker() 3523 3524 // A sender who makes transactions, has some funds 3525 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3526 key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 3527 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 3528 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 3529 funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) 3530 gspec = &Genesis{ 3531 Config: params.AllEthashProtocolChanges, 3532 Alloc: GenesisAlloc{ 3533 addr1: {Balance: funds}, 3534 addr2: {Balance: funds}, 3535 // The address 0xAAAA sloads 0x00 and 0x01 3536 aa: { 3537 Code: []byte{ 3538 byte(vm.PC), 3539 byte(vm.PC), 3540 byte(vm.SLOAD), 3541 byte(vm.SLOAD), 3542 }, 3543 Nonce: 0, 3544 Balance: big.NewInt(0), 3545 }, 3546 }, 3547 } 3548 ) 3549 3550 gspec.Config.BerlinBlock = common.Big0 3551 gspec.Config.LondonBlock = common.Big0 3552 signer := types.LatestSigner(gspec.Config) 3553 3554 genDb, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 3555 b.SetCoinbase(common.Address{1}) 3556 3557 // One transaction to 0xAAAA 3558 accesses := types.AccessList{types.AccessTuple{ 3559 Address: aa, 3560 StorageKeys: []common.Hash{{0}}, 3561 }} 3562 3563 txdata := &types.DynamicFeeTx{ 3564 ChainID: gspec.Config.ChainID, 3565 Nonce: 0, 3566 To: &aa, 3567 Gas: 30000, 3568 GasFeeCap: newGwei(5), 3569 GasTipCap: big.NewInt(2), 3570 AccessList: accesses, 3571 Data: []byte{}, 3572 } 3573 tx := types.NewTx(txdata) 3574 tx, _ = types.SignTx(tx, signer, key1) 3575 3576 b.AddTx(tx) 3577 }) 3578 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 3579 if err != nil { 3580 t.Fatalf("failed to create tester chain: %v", err) 3581 } 3582 defer chain.Stop() 3583 3584 if n, err := chain.InsertChain(blocks); err != nil { 3585 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3586 } 3587 3588 block := chain.GetBlockByNumber(1) 3589 3590 // 1+2: Ensure EIP-1559 access lists are accounted for via gas usage. 3591 expectedGas := params.TxGas + params.TxAccessListAddressGas + params.TxAccessListStorageKeyGas + 3592 vm.GasQuickStep*2 + params.WarmStorageReadCostEIP2929 + params.ColdSloadCostEIP2929 3593 if block.GasUsed() != expectedGas { 3594 t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) 3595 } 3596 3597 state, _ := chain.State() 3598 3599 // 3: Ensure that miner received only the tx's tip. 3600 actual := state.GetBalance(block.Coinbase()) 3601 expected := new(big.Int).Add( 3602 new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()), 3603 ethash.ConstantinopleBlockReward, 3604 ) 3605 if actual.Cmp(expected) != 0 { 3606 t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) 3607 } 3608 3609 // 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee). 3610 actual = new(big.Int).Sub(funds, state.GetBalance(addr1)) 3611 expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64())) 3612 if actual.Cmp(expected) != 0 { 3613 t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) 3614 } 3615 3616 blocks, _ = GenerateChain(gspec.Config, block, engine, genDb, 1, func(i int, b *BlockGen) { 3617 b.SetCoinbase(common.Address{2}) 3618 3619 txdata := &types.LegacyTx{ 3620 Nonce: 0, 3621 To: &aa, 3622 Gas: 30000, 3623 GasPrice: newGwei(5), 3624 } 3625 tx := types.NewTx(txdata) 3626 tx, _ = types.SignTx(tx, signer, key2) 3627 3628 b.AddTx(tx) 3629 }) 3630 3631 if n, err := chain.InsertChain(blocks); err != nil { 3632 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3633 } 3634 3635 block = chain.GetBlockByNumber(2) 3636 state, _ = chain.State() 3637 effectiveTip := block.Transactions()[0].GasTipCap().Uint64() - block.BaseFee().Uint64() 3638 3639 // 6+5: Ensure that miner received only the tx's effective tip. 3640 actual = state.GetBalance(block.Coinbase()) 3641 expected = new(big.Int).Add( 3642 new(big.Int).SetUint64(block.GasUsed()*effectiveTip), 3643 ethash.ConstantinopleBlockReward, 3644 ) 3645 if actual.Cmp(expected) != 0 { 3646 t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) 3647 } 3648 3649 // 4: Ensure the tx sender paid for the gasUsed * (effectiveTip + block baseFee). 3650 actual = new(big.Int).Sub(funds, state.GetBalance(addr2)) 3651 expected = new(big.Int).SetUint64(block.GasUsed() * (effectiveTip + block.BaseFee().Uint64())) 3652 if actual.Cmp(expected) != 0 { 3653 t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) 3654 } 3655 } 3656 3657 // Tests the scenario the chain is requested to another point with the missing state. 3658 // It expects the state is recovered and all relevant chain markers are set correctly. 3659 func TestSetCanonical(t *testing.T) { 3660 //log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))) 3661 3662 var ( 3663 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 3664 address = crypto.PubkeyToAddress(key.PublicKey) 3665 funds = big.NewInt(100000000000000000) 3666 gspec = &Genesis{ 3667 Config: params.TestChainConfig, 3668 Alloc: GenesisAlloc{address: {Balance: funds}}, 3669 BaseFee: big.NewInt(params.InitialBaseFee), 3670 } 3671 signer = types.LatestSigner(gspec.Config) 3672 engine = ethash.NewFaker() 3673 ) 3674 // Generate and import the canonical chain 3675 _, canon, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { 3676 tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, gen.header.BaseFee, nil), signer, key) 3677 if err != nil { 3678 panic(err) 3679 } 3680 gen.AddTx(tx) 3681 }) 3682 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 3683 if err != nil { 3684 t.Fatalf("failed to create tester chain: %v", err) 3685 } 3686 defer chain.Stop() 3687 3688 if n, err := chain.InsertChain(canon); err != nil { 3689 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3690 } 3691 3692 // Generate the side chain and import them 3693 _, side, _ := GenerateChainWithGenesis(gspec, engine, 2*TriesInMemory, func(i int, gen *BlockGen) { 3694 tx, err := types.SignTx(types.NewTransaction(gen.TxNonce(address), common.Address{0x00}, big.NewInt(1), params.TxGas, gen.header.BaseFee, nil), signer, key) 3695 if err != nil { 3696 panic(err) 3697 } 3698 gen.AddTx(tx) 3699 }) 3700 for _, block := range side { 3701 err := chain.InsertBlockWithoutSetHead(block) 3702 if err != nil { 3703 t.Fatalf("Failed to insert into chain: %v", err) 3704 } 3705 } 3706 for _, block := range side { 3707 got := chain.GetBlockByHash(block.Hash()) 3708 if got == nil { 3709 t.Fatalf("Lost the inserted block") 3710 } 3711 } 3712 3713 // Set the chain head to the side chain, ensure all the relevant markers are updated. 3714 verify := func(head *types.Block) { 3715 if chain.CurrentBlock().Hash() != head.Hash() { 3716 t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash()) 3717 } 3718 if chain.CurrentFastBlock().Hash() != head.Hash() { 3719 t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentFastBlock().Hash()) 3720 } 3721 if chain.CurrentHeader().Hash() != head.Hash() { 3722 t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash()) 3723 } 3724 if !chain.HasState(head.Root()) { 3725 t.Fatalf("Lost block state %v %x", head.Number(), head.Hash()) 3726 } 3727 } 3728 chain.SetCanonical(side[len(side)-1]) 3729 verify(side[len(side)-1]) 3730 3731 // Reset the chain head to original chain 3732 chain.SetCanonical(canon[TriesInMemory-1]) 3733 verify(canon[TriesInMemory-1]) 3734 } 3735 3736 // TestCanonicalHashMarker tests all the canonical hash markers are updated/deleted 3737 // correctly in case reorg is called. 3738 func TestCanonicalHashMarker(t *testing.T) { 3739 var cases = []struct { 3740 forkA int 3741 forkB int 3742 }{ 3743 // ForkA: 10 blocks 3744 // ForkB: 1 blocks 3745 // 3746 // reorged: 3747 // markers [2, 10] should be deleted 3748 // markers [1] should be updated 3749 {10, 1}, 3750 3751 // ForkA: 10 blocks 3752 // ForkB: 2 blocks 3753 // 3754 // reorged: 3755 // markers [3, 10] should be deleted 3756 // markers [1, 2] should be updated 3757 {10, 2}, 3758 3759 // ForkA: 10 blocks 3760 // ForkB: 10 blocks 3761 // 3762 // reorged: 3763 // markers [1, 10] should be updated 3764 {10, 10}, 3765 3766 // ForkA: 10 blocks 3767 // ForkB: 11 blocks 3768 // 3769 // reorged: 3770 // markers [1, 11] should be updated 3771 {10, 11}, 3772 } 3773 for _, c := range cases { 3774 var ( 3775 gspec = &Genesis{ 3776 Config: params.TestChainConfig, 3777 Alloc: GenesisAlloc{}, 3778 BaseFee: big.NewInt(params.InitialBaseFee), 3779 } 3780 engine = ethash.NewFaker() 3781 ) 3782 _, forkA, _ := GenerateChainWithGenesis(gspec, engine, c.forkA, func(i int, gen *BlockGen) {}) 3783 _, forkB, _ := GenerateChainWithGenesis(gspec, engine, c.forkB, func(i int, gen *BlockGen) {}) 3784 3785 // Initialize test chain 3786 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{}, nil, nil) 3787 if err != nil { 3788 t.Fatalf("failed to create tester chain: %v", err) 3789 } 3790 // Insert forkA and forkB, the canonical should on forkA still 3791 if n, err := chain.InsertChain(forkA); err != nil { 3792 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3793 } 3794 if n, err := chain.InsertChain(forkB); err != nil { 3795 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 3796 } 3797 3798 verify := func(head *types.Block) { 3799 if chain.CurrentBlock().Hash() != head.Hash() { 3800 t.Fatalf("Unexpected block hash, want %x, got %x", head.Hash(), chain.CurrentBlock().Hash()) 3801 } 3802 if chain.CurrentFastBlock().Hash() != head.Hash() { 3803 t.Fatalf("Unexpected fast block hash, want %x, got %x", head.Hash(), chain.CurrentFastBlock().Hash()) 3804 } 3805 if chain.CurrentHeader().Hash() != head.Hash() { 3806 t.Fatalf("Unexpected head header, want %x, got %x", head.Hash(), chain.CurrentHeader().Hash()) 3807 } 3808 if !chain.HasState(head.Root()) { 3809 t.Fatalf("Lost block state %v %x", head.Number(), head.Hash()) 3810 } 3811 } 3812 3813 // Switch canonical chain to forkB if necessary 3814 if len(forkA) < len(forkB) { 3815 verify(forkB[len(forkB)-1]) 3816 } else { 3817 verify(forkA[len(forkA)-1]) 3818 chain.SetCanonical(forkB[len(forkB)-1]) 3819 verify(forkB[len(forkB)-1]) 3820 } 3821 3822 // Ensure all hash markers are updated correctly 3823 for i := 0; i < len(forkB); i++ { 3824 block := forkB[i] 3825 hash := chain.GetCanonicalHash(block.NumberU64()) 3826 if hash != block.Hash() { 3827 t.Fatalf("Unexpected canonical hash %d", block.NumberU64()) 3828 } 3829 } 3830 if c.forkA > c.forkB { 3831 for i := uint64(c.forkB) + 1; i <= uint64(c.forkA); i++ { 3832 hash := chain.GetCanonicalHash(i) 3833 if hash != (common.Hash{}) { 3834 t.Fatalf("Unexpected canonical hash %d", i) 3835 } 3836 } 3837 } 3838 chain.Stop() 3839 } 3840 } 3841 3842 // TestTxIndexer tests the tx indexes are updated correctly. 3843 func TestTxIndexer(t *testing.T) { 3844 var ( 3845 testBankKey, _ = crypto.GenerateKey() 3846 testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) 3847 testBankFunds = big.NewInt(1000000000000000000) 3848 3849 gspec = &Genesis{ 3850 Config: params.TestChainConfig, 3851 Alloc: GenesisAlloc{testBankAddress: {Balance: testBankFunds}}, 3852 BaseFee: big.NewInt(params.InitialBaseFee), 3853 } 3854 engine = ethash.NewFaker() 3855 nonce = uint64(0) 3856 ) 3857 _, blocks, receipts := GenerateChainWithGenesis(gspec, engine, 128, func(i int, gen *BlockGen) { 3858 tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0xdeadbeef"), big.NewInt(1000), params.TxGas, big.NewInt(10*params.InitialBaseFee), nil), types.HomesteadSigner{}, testBankKey) 3859 gen.AddTx(tx) 3860 nonce += 1 3861 }) 3862 3863 // verifyIndexes checks if the transaction indexes are present or not 3864 // of the specified block. 3865 verifyIndexes := func(db ethdb.Database, number uint64, exist bool) { 3866 if number == 0 { 3867 return 3868 } 3869 block := blocks[number-1] 3870 for _, tx := range block.Transactions() { 3871 lookup := rawdb.ReadTxLookupEntry(db, tx.Hash()) 3872 if exist && lookup == nil { 3873 t.Fatalf("missing %d %x", number, tx.Hash().Hex()) 3874 } 3875 if !exist && lookup != nil { 3876 t.Fatalf("unexpected %d %x", number, tx.Hash().Hex()) 3877 } 3878 } 3879 } 3880 // verifyRange runs verifyIndexes for a range of blocks, from and to are included. 3881 verifyRange := func(db ethdb.Database, from, to uint64, exist bool) { 3882 for number := from; number <= to; number += 1 { 3883 verifyIndexes(db, number, exist) 3884 } 3885 } 3886 verify := func(db ethdb.Database, expTail uint64) { 3887 tail := rawdb.ReadTxIndexTail(db) 3888 if tail == nil { 3889 t.Fatal("Failed to write tx index tail") 3890 } 3891 if *tail != expTail { 3892 t.Fatalf("Unexpected tx index tail, want %v, got %d", expTail, *tail) 3893 } 3894 if *tail != 0 { 3895 verifyRange(db, 0, *tail-1, false) 3896 } 3897 verifyRange(db, *tail, 128, true) 3898 } 3899 3900 var cases = []struct { 3901 limitA uint64 3902 tailA uint64 3903 limitB uint64 3904 tailB uint64 3905 limitC uint64 3906 tailC uint64 3907 }{ 3908 { 3909 // LimitA: 0 3910 // TailA: 0 3911 // 3912 // all blocks are indexed 3913 limitA: 0, 3914 tailA: 0, 3915 3916 // LimitB: 1 3917 // TailB: 128 3918 // 3919 // block-128 is indexed 3920 limitB: 1, 3921 tailB: 128, 3922 3923 // LimitB: 64 3924 // TailB: 65 3925 // 3926 // block [65, 128] are indexed 3927 limitC: 64, 3928 tailC: 65, 3929 }, 3930 { 3931 // LimitA: 64 3932 // TailA: 65 3933 // 3934 // block [65, 128] are indexed 3935 limitA: 64, 3936 tailA: 65, 3937 3938 // LimitB: 1 3939 // TailB: 128 3940 // 3941 // block-128 is indexed 3942 limitB: 1, 3943 tailB: 128, 3944 3945 // LimitB: 64 3946 // TailB: 65 3947 // 3948 // block [65, 128] are indexed 3949 limitC: 64, 3950 tailC: 65, 3951 }, 3952 { 3953 // LimitA: 127 3954 // TailA: 2 3955 // 3956 // block [2, 128] are indexed 3957 limitA: 127, 3958 tailA: 2, 3959 3960 // LimitB: 1 3961 // TailB: 128 3962 // 3963 // block-128 is indexed 3964 limitB: 1, 3965 tailB: 128, 3966 3967 // LimitB: 64 3968 // TailB: 65 3969 // 3970 // block [65, 128] are indexed 3971 limitC: 64, 3972 tailC: 65, 3973 }, 3974 { 3975 // LimitA: 128 3976 // TailA: 1 3977 // 3978 // block [2, 128] are indexed 3979 limitA: 128, 3980 tailA: 1, 3981 3982 // LimitB: 1 3983 // TailB: 128 3984 // 3985 // block-128 is indexed 3986 limitB: 1, 3987 tailB: 128, 3988 3989 // LimitB: 64 3990 // TailB: 65 3991 // 3992 // block [65, 128] are indexed 3993 limitC: 64, 3994 tailC: 65, 3995 }, 3996 { 3997 // LimitA: 129 3998 // TailA: 0 3999 // 4000 // block [0, 128] are indexed 4001 limitA: 129, 4002 tailA: 0, 4003 4004 // LimitB: 1 4005 // TailB: 128 4006 // 4007 // block-128 is indexed 4008 limitB: 1, 4009 tailB: 128, 4010 4011 // LimitB: 64 4012 // TailB: 65 4013 // 4014 // block [65, 128] are indexed 4015 limitC: 64, 4016 tailC: 65, 4017 }, 4018 } 4019 for _, c := range cases { 4020 frdir := t.TempDir() 4021 db, _ := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false) 4022 rawdb.WriteAncientBlocks(db, append([]*types.Block{gspec.ToBlock()}, blocks...), append([]types.Receipts{{}}, receipts...), big.NewInt(0)) 4023 4024 // Index the initial blocks from ancient store 4025 chain, _ := NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, &c.limitA) 4026 chain.indexBlocks(nil, 128, make(chan struct{})) 4027 verify(db, c.tailA) 4028 4029 chain.SetTxLookupLimit(c.limitB) 4030 chain.indexBlocks(rawdb.ReadTxIndexTail(db), 128, make(chan struct{})) 4031 verify(db, c.tailB) 4032 4033 chain.SetTxLookupLimit(c.limitC) 4034 chain.indexBlocks(rawdb.ReadTxIndexTail(db), 128, make(chan struct{})) 4035 verify(db, c.tailC) 4036 4037 // Recover all indexes 4038 chain.SetTxLookupLimit(0) 4039 chain.indexBlocks(rawdb.ReadTxIndexTail(db), 128, make(chan struct{})) 4040 verify(db, 0) 4041 4042 chain.Stop() 4043 db.Close() 4044 os.RemoveAll(frdir) 4045 } 4046 } 4047 4048 func TestCreateThenDeletePreByzantium(t *testing.T) { 4049 // We use Ropsten chain config instead of Testchain config, this is 4050 // deliberate: we want to use pre-byz rules where we have intermediate state roots 4051 // between transactions. 4052 testCreateThenDelete(t, params.RopstenChainConfig) 4053 } 4054 func TestCreateThenDeletePostByzantium(t *testing.T) { 4055 testCreateThenDelete(t, params.TestChainConfig) 4056 } 4057 4058 // testCreateThenDelete tests a creation and subsequent deletion of a contract, happening 4059 // within the same block. 4060 func testCreateThenDelete(t *testing.T, config *params.ChainConfig) { 4061 var ( 4062 engine = ethash.NewFaker() 4063 // A sender who makes transactions, has some funds 4064 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 4065 address = crypto.PubkeyToAddress(key.PublicKey) 4066 destAddress = crypto.CreateAddress(address, 0) 4067 funds = big.NewInt(1000000000000000) 4068 ) 4069 4070 // runtime code is 0x60ffff : PUSH1 0xFF SELFDESTRUCT, a.k.a SELFDESTRUCT(0xFF) 4071 code := append([]byte{0x60, 0xff, 0xff}, make([]byte, 32-3)...) 4072 initCode := []byte{ 4073 // SSTORE 1:1 4074 byte(vm.PUSH1), 0x1, 4075 byte(vm.PUSH1), 0x1, 4076 byte(vm.SSTORE), 4077 // Get the runtime-code on the stack 4078 byte(vm.PUSH32)} 4079 initCode = append(initCode, code...) 4080 initCode = append(initCode, []byte{ 4081 byte(vm.PUSH1), 0x0, // offset 4082 byte(vm.MSTORE), 4083 byte(vm.PUSH1), 0x3, // size 4084 byte(vm.PUSH1), 0x0, // offset 4085 byte(vm.RETURN), // return 3 bytes of zero-code 4086 }...) 4087 gspec := &Genesis{ 4088 Config: config, 4089 Alloc: GenesisAlloc{ 4090 address: {Balance: funds}, 4091 }, 4092 } 4093 nonce := uint64(0) 4094 signer := types.HomesteadSigner{} 4095 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 2, func(i int, b *BlockGen) { 4096 fee := big.NewInt(1) 4097 if b.header.BaseFee != nil { 4098 fee = b.header.BaseFee 4099 } 4100 b.SetCoinbase(common.Address{1}) 4101 tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{ 4102 Nonce: nonce, 4103 GasPrice: new(big.Int).Set(fee), 4104 Gas: 100000, 4105 Data: initCode, 4106 }) 4107 nonce++ 4108 b.AddTx(tx) 4109 tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{ 4110 Nonce: nonce, 4111 GasPrice: new(big.Int).Set(fee), 4112 Gas: 100000, 4113 To: &destAddress, 4114 }) 4115 b.AddTx(tx) 4116 nonce++ 4117 }) 4118 // Import the canonical chain 4119 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{ 4120 //Debug: true, 4121 //Tracer: logger.NewJSONLogger(nil, os.Stdout), 4122 }, nil, nil) 4123 if err != nil { 4124 t.Fatalf("failed to create tester chain: %v", err) 4125 } 4126 // Import the blocks 4127 for _, block := range blocks { 4128 if _, err := chain.InsertChain([]*types.Block{block}); err != nil { 4129 t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) 4130 } 4131 } 4132 } 4133 4134 // TestTransientStorageReset ensures the transient storage is wiped correctly 4135 // between transactions. 4136 func TestTransientStorageReset(t *testing.T) { 4137 var ( 4138 engine = ethash.NewFaker() 4139 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 4140 address = crypto.PubkeyToAddress(key.PublicKey) 4141 destAddress = crypto.CreateAddress(address, 0) 4142 funds = big.NewInt(1000000000000000) 4143 vmConfig = vm.Config{ 4144 ExtraEips: []int{1153}, // Enable transient storage EIP 4145 } 4146 ) 4147 code := append([]byte{ 4148 // TLoad value with location 1 4149 byte(vm.PUSH1), 0x1, 4150 byte(vm.TLOAD), 4151 4152 // PUSH location 4153 byte(vm.PUSH1), 0x1, 4154 4155 // SStore location:value 4156 byte(vm.SSTORE), 4157 }, make([]byte, 32-6)...) 4158 initCode := []byte{ 4159 // TSTORE 1:1 4160 byte(vm.PUSH1), 0x1, 4161 byte(vm.PUSH1), 0x1, 4162 byte(vm.TSTORE), 4163 4164 // Get the runtime-code on the stack 4165 byte(vm.PUSH32)} 4166 initCode = append(initCode, code...) 4167 initCode = append(initCode, []byte{ 4168 byte(vm.PUSH1), 0x0, // offset 4169 byte(vm.MSTORE), 4170 byte(vm.PUSH1), 0x6, // size 4171 byte(vm.PUSH1), 0x0, // offset 4172 byte(vm.RETURN), // return 6 bytes of zero-code 4173 }...) 4174 gspec := &Genesis{ 4175 Config: params.TestChainConfig, 4176 Alloc: GenesisAlloc{ 4177 address: {Balance: funds}, 4178 }, 4179 } 4180 nonce := uint64(0) 4181 signer := types.HomesteadSigner{} 4182 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 4183 fee := big.NewInt(1) 4184 if b.header.BaseFee != nil { 4185 fee = b.header.BaseFee 4186 } 4187 b.SetCoinbase(common.Address{1}) 4188 tx, _ := types.SignNewTx(key, signer, &types.LegacyTx{ 4189 Nonce: nonce, 4190 GasPrice: new(big.Int).Set(fee), 4191 Gas: 100000, 4192 Data: initCode, 4193 }) 4194 nonce++ 4195 b.AddTxWithVMConfig(tx, vmConfig) 4196 4197 tx, _ = types.SignNewTx(key, signer, &types.LegacyTx{ 4198 Nonce: nonce, 4199 GasPrice: new(big.Int).Set(fee), 4200 Gas: 100000, 4201 To: &destAddress, 4202 }) 4203 b.AddTxWithVMConfig(tx, vmConfig) 4204 nonce++ 4205 }) 4206 4207 // Initialize the blockchain with 1153 enabled. 4208 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vmConfig, nil, nil) 4209 if err != nil { 4210 t.Fatalf("failed to create tester chain: %v", err) 4211 } 4212 // Import the blocks 4213 if _, err := chain.InsertChain(blocks); err != nil { 4214 t.Fatalf("failed to insert into chain: %v", err) 4215 } 4216 // Check the storage 4217 state, err := chain.StateAt(chain.CurrentHeader().Root) 4218 if err != nil { 4219 t.Fatalf("Failed to load state %v", err) 4220 } 4221 loc := common.BytesToHash([]byte{1}) 4222 slot := state.GetState(destAddress, loc) 4223 if slot != (common.Hash{}) { 4224 t.Fatalf("Unexpected dirty storage slot") 4225 } 4226 } 4227 4228 func TestEIP3651(t *testing.T) { 4229 var ( 4230 aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa") 4231 bb = common.HexToAddress("0x000000000000000000000000000000000000bbbb") 4232 engine = ethash.NewFaker() 4233 4234 // A sender who makes transactions, has some funds 4235 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 4236 key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 4237 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 4238 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 4239 funds = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) 4240 gspec = &Genesis{ 4241 Config: params.AllEthashProtocolChanges, 4242 Alloc: GenesisAlloc{ 4243 addr1: {Balance: funds}, 4244 addr2: {Balance: funds}, 4245 // The address 0xAAAA sloads 0x00 and 0x01 4246 aa: { 4247 Code: []byte{ 4248 byte(vm.PC), 4249 byte(vm.PC), 4250 byte(vm.SLOAD), 4251 byte(vm.SLOAD), 4252 }, 4253 Nonce: 0, 4254 Balance: big.NewInt(0), 4255 }, 4256 // The address 0xBBBB calls 0xAAAA 4257 bb: { 4258 Code: []byte{ 4259 byte(vm.PUSH1), 0, // out size 4260 byte(vm.DUP1), // out offset 4261 byte(vm.DUP1), // out insize 4262 byte(vm.DUP1), // in offset 4263 byte(vm.PUSH2), // address 4264 byte(0xaa), 4265 byte(0xaa), 4266 byte(vm.GAS), // gas 4267 byte(vm.DELEGATECALL), 4268 }, 4269 Nonce: 0, 4270 Balance: big.NewInt(0), 4271 }, 4272 }, 4273 } 4274 ) 4275 4276 gspec.Config.BerlinBlock = common.Big0 4277 gspec.Config.LondonBlock = common.Big0 4278 gspec.Config.ShanghaiBlock = common.Big0 4279 signer := types.LatestSigner(gspec.Config) 4280 4281 _, blocks, _ := GenerateChainWithGenesis(gspec, engine, 1, func(i int, b *BlockGen) { 4282 b.SetCoinbase(aa) 4283 // One transaction to Coinbase 4284 txdata := &types.DynamicFeeTx{ 4285 ChainID: gspec.Config.ChainID, 4286 Nonce: 0, 4287 To: &bb, 4288 Gas: 500000, 4289 GasFeeCap: newGwei(5), 4290 GasTipCap: big.NewInt(2), 4291 AccessList: nil, 4292 Data: []byte{}, 4293 } 4294 tx := types.NewTx(txdata) 4295 tx, _ = types.SignTx(tx, signer, key1) 4296 4297 b.AddTx(tx) 4298 }) 4299 chain, err := NewBlockChain(rawdb.NewMemoryDatabase(), nil, gspec, nil, engine, vm.Config{Tracer: logger.NewMarkdownLogger(&logger.Config{}, os.Stderr)}, nil, nil) 4300 if err != nil { 4301 t.Fatalf("failed to create tester chain: %v", err) 4302 } 4303 if n, err := chain.InsertChain(blocks); err != nil { 4304 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 4305 } 4306 4307 block := chain.GetBlockByNumber(1) 4308 4309 // 1+2: Ensure EIP-1559 access lists are accounted for via gas usage. 4310 innerGas := vm.GasQuickStep*2 + params.ColdSloadCostEIP2929*2 4311 expectedGas := params.TxGas + 5*vm.GasFastestStep + vm.GasQuickStep + 100 + innerGas // 100 because 0xaaaa is in access list 4312 if block.GasUsed() != expectedGas { 4313 t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) 4314 } 4315 4316 state, _ := chain.State() 4317 4318 // 3: Ensure that miner received only the tx's tip. 4319 actual := state.GetBalance(block.Coinbase()) 4320 expected := new(big.Int).Add( 4321 new(big.Int).SetUint64(block.GasUsed()*block.Transactions()[0].GasTipCap().Uint64()), 4322 ethash.ConstantinopleBlockReward, 4323 ) 4324 if actual.Cmp(expected) != 0 { 4325 t.Fatalf("miner balance incorrect: expected %d, got %d", expected, actual) 4326 } 4327 4328 // 4: Ensure the tx sender paid for the gasUsed * (tip + block baseFee). 4329 actual = new(big.Int).Sub(funds, state.GetBalance(addr1)) 4330 expected = new(big.Int).SetUint64(block.GasUsed() * (block.Transactions()[0].GasTipCap().Uint64() + block.BaseFee().Uint64())) 4331 if actual.Cmp(expected) != 0 { 4332 t.Fatalf("sender balance incorrect: expected %d, got %d", expected, actual) 4333 } 4334 }