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