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