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