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