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