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