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