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