github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/core/blockchain_test.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "fmt" 21 "math/big" 22 "math/rand" 23 "sync" 24 "testing" 25 "time" 26 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/consensus" 29 "github.com/ethereum/go-ethereum/consensus/ethash" 30 "github.com/ethereum/go-ethereum/core/rawdb" 31 "github.com/ethereum/go-ethereum/core/state" 32 "github.com/ethereum/go-ethereum/core/types" 33 "github.com/ethereum/go-ethereum/core/vm" 34 "github.com/ethereum/go-ethereum/crypto" 35 "github.com/ethereum/go-ethereum/ethdb" 36 "github.com/ethereum/go-ethereum/params" 37 ) 38 39 // So we can deterministically seed different blockchains 40 var ( 41 canonicalSeed = 1 42 forkSeed = 2 43 ) 44 45 // newCanonical creates a chain database, and injects a deterministic canonical 46 // chain. Depending on the full flag, if creates either a full block chain or a 47 // header only chain. 48 func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) { 49 var ( 50 db = ethdb.NewMemDatabase() 51 genesis = new(Genesis).MustCommit(db) 52 ) 53 54 // Initialize a fresh chain with only a genesis block 55 blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil) 56 // Create and inject the requested chain 57 if n == 0 { 58 return db, blockchain, nil 59 } 60 if full { 61 // Full block-chain requested 62 blocks := makeBlockChain(genesis, n, engine, db, canonicalSeed) 63 _, err := blockchain.InsertChain(blocks) 64 return db, blockchain, err 65 } 66 // Header-only chain requested 67 headers := makeHeaderChain(genesis.Header(), n, engine, db, canonicalSeed) 68 _, err := blockchain.InsertHeaderChain(headers, 1) 69 return db, blockchain, err 70 } 71 72 // Test fork of length N starting from block i 73 func testFork(t *testing.T, blockchain *BlockChain, i, n int, full bool, comparator func(td1, td2 *big.Int)) { 74 // Copy old chain up to #i into a new db 75 db, blockchain2, err := newCanonical(ethash.NewFaker(), i, full) 76 if err != nil { 77 t.Fatal("could not make new canonical in testFork", err) 78 } 79 defer blockchain2.Stop() 80 81 // Assert the chains have the same header/block at #i 82 var hash1, hash2 common.Hash 83 if full { 84 hash1 = blockchain.GetBlockByNumber(uint64(i)).Hash() 85 hash2 = blockchain2.GetBlockByNumber(uint64(i)).Hash() 86 } else { 87 hash1 = blockchain.GetHeaderByNumber(uint64(i)).Hash() 88 hash2 = blockchain2.GetHeaderByNumber(uint64(i)).Hash() 89 } 90 if hash1 != hash2 { 91 t.Errorf("chain content mismatch at %d: have hash %v, want hash %v", i, hash2, hash1) 92 } 93 // Extend the newly created chain 94 var ( 95 blockChainB []*types.Block 96 headerChainB []*types.Header 97 ) 98 if full { 99 blockChainB = makeBlockChain(blockchain2.CurrentBlock(), n, ethash.NewFaker(), db, forkSeed) 100 if _, err := blockchain2.InsertChain(blockChainB); err != nil { 101 t.Fatalf("failed to insert forking chain: %v", err) 102 } 103 } else { 104 headerChainB = makeHeaderChain(blockchain2.CurrentHeader(), n, ethash.NewFaker(), db, forkSeed) 105 if _, err := blockchain2.InsertHeaderChain(headerChainB, 1); err != nil { 106 t.Fatalf("failed to insert forking chain: %v", err) 107 } 108 } 109 // Sanity check that the forked chain can be imported into the original 110 var tdPre, tdPost *big.Int 111 112 if full { 113 tdPre = blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()) 114 if err := testBlockChainImport(blockChainB, blockchain); err != nil { 115 t.Fatalf("failed to import forked block chain: %v", err) 116 } 117 tdPost = blockchain.GetTdByHash(blockChainB[len(blockChainB)-1].Hash()) 118 } else { 119 tdPre = blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()) 120 if err := testHeaderChainImport(headerChainB, blockchain); err != nil { 121 t.Fatalf("failed to import forked header chain: %v", err) 122 } 123 tdPost = blockchain.GetTdByHash(headerChainB[len(headerChainB)-1].Hash()) 124 } 125 // Compare the total difficulties of the chains 126 comparator(tdPre, tdPost) 127 } 128 129 func printChain(bc *BlockChain) { 130 for i := bc.CurrentBlock().Number().Uint64(); i > 0; i-- { 131 b := bc.GetBlockByNumber(uint64(i)) 132 fmt.Printf("\t%x %v\n", b.Hash(), b.Difficulty()) 133 } 134 } 135 136 // testBlockChainImport tries to process a chain of blocks, writing them into 137 // the database if successful. 138 func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { 139 for _, block := range chain { 140 // Try and process the block 141 err := blockchain.engine.VerifyHeader(blockchain, block.Header(), true) 142 if err == nil { 143 err = blockchain.validator.ValidateBody(block) 144 } 145 if err != nil { 146 if err == ErrKnownBlock { 147 continue 148 } 149 return err 150 } 151 statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache) 152 if err != nil { 153 return err 154 } 155 receipts, _, _, usedGas, err := blockchain.Processor().Process(block, statedb, statedb, vm.Config{}) 156 if err != nil { 157 blockchain.reportBlock(block, receipts, err) 158 return err 159 } 160 err = blockchain.validator.ValidateState(block, blockchain.GetBlockByHash(block.ParentHash()), statedb, receipts, usedGas) 161 if err != nil { 162 blockchain.reportBlock(block, receipts, err) 163 return err 164 } 165 blockchain.mu.Lock() 166 rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash()))) 167 rawdb.WriteBlock(blockchain.db, block) 168 statedb.Commit(false) 169 blockchain.mu.Unlock() 170 } 171 return nil 172 } 173 174 // testHeaderChainImport tries to process a chain of header, writing them into 175 // the database if successful. 176 func testHeaderChainImport(chain []*types.Header, blockchain *BlockChain) error { 177 for _, header := range chain { 178 // Try and validate the header 179 if err := blockchain.engine.VerifyHeader(blockchain, header, false); err != nil { 180 return err 181 } 182 // Manually insert the header into the database, but don't reorganise (allows subsequent testing) 183 blockchain.mu.Lock() 184 rawdb.WriteTd(blockchain.db, header.Hash(), header.Number.Uint64(), new(big.Int).Add(header.Difficulty, blockchain.GetTdByHash(header.ParentHash))) 185 rawdb.WriteHeader(blockchain.db, header) 186 blockchain.mu.Unlock() 187 } 188 return nil 189 } 190 191 func insertChain(done chan bool, blockchain *BlockChain, chain types.Blocks, t *testing.T) { 192 _, err := blockchain.InsertChain(chain) 193 if err != nil { 194 fmt.Println(err) 195 t.FailNow() 196 } 197 done <- true 198 } 199 200 func TestLastBlock(t *testing.T) { 201 _, blockchain, err := newCanonical(ethash.NewFaker(), 0, true) 202 if err != nil { 203 t.Fatalf("failed to create pristine chain: %v", err) 204 } 205 defer blockchain.Stop() 206 207 blocks := makeBlockChain(blockchain.CurrentBlock(), 1, ethash.NewFullFaker(), blockchain.db, 0) 208 if _, err := blockchain.InsertChain(blocks); err != nil { 209 t.Fatalf("Failed to insert block: %v", err) 210 } 211 if blocks[len(blocks)-1].Hash() != rawdb.ReadHeadBlockHash(blockchain.db) { 212 t.Fatalf("Write/Get HeadBlockHash failed") 213 } 214 } 215 216 // Tests that given a starting canonical chain of a given size, it can be extended 217 // with various length chains. 218 func TestExtendCanonicalHeaders(t *testing.T) { testExtendCanonical(t, false) } 219 func TestExtendCanonicalBlocks(t *testing.T) { testExtendCanonical(t, true) } 220 221 func testExtendCanonical(t *testing.T, full bool) { 222 length := 5 223 224 // Make first chain starting from genesis 225 _, processor, err := newCanonical(ethash.NewFaker(), length, full) 226 if err != nil { 227 t.Fatalf("failed to make new canonical chain: %v", err) 228 } 229 defer processor.Stop() 230 231 // Define the difficulty comparator 232 better := func(td1, td2 *big.Int) { 233 if td2.Cmp(td1) <= 0 { 234 t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) 235 } 236 } 237 // Start fork from current height 238 testFork(t, processor, length, 1, full, better) 239 testFork(t, processor, length, 2, full, better) 240 testFork(t, processor, length, 5, full, better) 241 testFork(t, processor, length, 10, full, better) 242 } 243 244 // Tests that given a starting canonical chain of a given size, creating shorter 245 // forks do not take canonical ownership. 246 func TestShorterForkHeaders(t *testing.T) { testShorterFork(t, false) } 247 func TestShorterForkBlocks(t *testing.T) { testShorterFork(t, true) } 248 249 func testShorterFork(t *testing.T, full bool) { 250 length := 10 251 252 // Make first chain starting from genesis 253 _, processor, err := newCanonical(ethash.NewFaker(), length, full) 254 if err != nil { 255 t.Fatalf("failed to make new canonical chain: %v", err) 256 } 257 defer processor.Stop() 258 259 // Define the difficulty comparator 260 worse := func(td1, td2 *big.Int) { 261 if td2.Cmp(td1) >= 0 { 262 t.Errorf("total difficulty mismatch: have %v, expected less than %v", td2, td1) 263 } 264 } 265 // Sum of numbers must be less than `length` for this to be a shorter fork 266 testFork(t, processor, 0, 3, full, worse) 267 testFork(t, processor, 0, 7, full, worse) 268 testFork(t, processor, 1, 1, full, worse) 269 testFork(t, processor, 1, 7, full, worse) 270 testFork(t, processor, 5, 3, full, worse) 271 testFork(t, processor, 5, 4, full, worse) 272 } 273 274 // Tests that given a starting canonical chain of a given size, creating longer 275 // forks do take canonical ownership. 276 func TestLongerForkHeaders(t *testing.T) { testLongerFork(t, false) } 277 func TestLongerForkBlocks(t *testing.T) { testLongerFork(t, true) } 278 279 func testLongerFork(t *testing.T, full bool) { 280 length := 10 281 282 // Make first chain starting from genesis 283 _, processor, err := newCanonical(ethash.NewFaker(), length, full) 284 if err != nil { 285 t.Fatalf("failed to make new canonical chain: %v", err) 286 } 287 defer processor.Stop() 288 289 // Define the difficulty comparator 290 better := func(td1, td2 *big.Int) { 291 if td2.Cmp(td1) <= 0 { 292 t.Errorf("total difficulty mismatch: have %v, expected more than %v", td2, td1) 293 } 294 } 295 // Sum of numbers must be greater than `length` for this to be a longer fork 296 testFork(t, processor, 0, 11, full, better) 297 testFork(t, processor, 0, 15, full, better) 298 testFork(t, processor, 1, 10, full, better) 299 testFork(t, processor, 1, 12, full, better) 300 testFork(t, processor, 5, 6, full, better) 301 testFork(t, processor, 5, 8, full, better) 302 } 303 304 // Tests that given a starting canonical chain of a given size, creating equal 305 // forks do take canonical ownership. 306 func TestEqualForkHeaders(t *testing.T) { testEqualFork(t, false) } 307 func TestEqualForkBlocks(t *testing.T) { testEqualFork(t, true) } 308 309 func testEqualFork(t *testing.T, full bool) { 310 length := 10 311 312 // Make first chain starting from genesis 313 _, processor, err := newCanonical(ethash.NewFaker(), length, full) 314 if err != nil { 315 t.Fatalf("failed to make new canonical chain: %v", err) 316 } 317 defer processor.Stop() 318 319 // Define the difficulty comparator 320 equal := func(td1, td2 *big.Int) { 321 if td2.Cmp(td1) != 0 { 322 t.Errorf("total difficulty mismatch: have %v, want %v", td2, td1) 323 } 324 } 325 // Sum of numbers must be equal to `length` for this to be an equal fork 326 testFork(t, processor, 0, 10, full, equal) 327 testFork(t, processor, 1, 9, full, equal) 328 testFork(t, processor, 2, 8, full, equal) 329 testFork(t, processor, 5, 5, full, equal) 330 testFork(t, processor, 6, 4, full, equal) 331 testFork(t, processor, 9, 1, full, equal) 332 } 333 334 // Tests that chains missing links do not get accepted by the processor. 335 func TestBrokenHeaderChain(t *testing.T) { testBrokenChain(t, false) } 336 func TestBrokenBlockChain(t *testing.T) { testBrokenChain(t, true) } 337 338 func testBrokenChain(t *testing.T, full bool) { 339 // Make chain starting from genesis 340 db, blockchain, err := newCanonical(ethash.NewFaker(), 10, full) 341 if err != nil { 342 t.Fatalf("failed to make new canonical chain: %v", err) 343 } 344 defer blockchain.Stop() 345 346 // Create a forked chain, and try to insert with a missing link 347 if full { 348 chain := makeBlockChain(blockchain.CurrentBlock(), 5, ethash.NewFaker(), db, forkSeed)[1:] 349 if err := testBlockChainImport(chain, blockchain); err == nil { 350 t.Errorf("broken block chain not reported") 351 } 352 } else { 353 chain := makeHeaderChain(blockchain.CurrentHeader(), 5, ethash.NewFaker(), db, forkSeed)[1:] 354 if err := testHeaderChainImport(chain, blockchain); err == nil { 355 t.Errorf("broken header chain not reported") 356 } 357 } 358 } 359 360 // Tests that reorganising a long difficult chain after a short easy one 361 // overwrites the canonical numbers and links in the database. 362 func TestReorgLongHeaders(t *testing.T) { testReorgLong(t, false) } 363 func TestReorgLongBlocks(t *testing.T) { testReorgLong(t, true) } 364 365 func testReorgLong(t *testing.T, full bool) { 366 testReorg(t, []int64{0, 0, -9}, []int64{0, 0, 0, -9}, 393280, full) 367 } 368 369 // Tests that reorganising a short difficult chain after a long easy one 370 // overwrites the canonical numbers and links in the database. 371 func TestReorgShortHeaders(t *testing.T) { testReorgShort(t, false) } 372 func TestReorgShortBlocks(t *testing.T) { testReorgShort(t, true) } 373 374 func testReorgShort(t *testing.T, full bool) { 375 // Create a long easy chain vs. a short heavy one. Due to difficulty adjustment 376 // we need a fairly long chain of blocks with different difficulties for a short 377 // one to become heavyer than a long one. The 96 is an empirical value. 378 easy := make([]int64, 96) 379 for i := 0; i < len(easy); i++ { 380 easy[i] = 60 381 } 382 diff := make([]int64, len(easy)-1) 383 for i := 0; i < len(diff); i++ { 384 diff[i] = -9 385 } 386 testReorg(t, easy, diff, 12615120, full) 387 } 388 389 func testReorg(t *testing.T, first, second []int64, td int64, full bool) { 390 // Create a pristine chain and database 391 db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 392 if err != nil { 393 t.Fatalf("failed to create pristine chain: %v", err) 394 } 395 defer blockchain.Stop() 396 397 // Insert an easy and a difficult chain afterwards 398 easyBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(first), func(i int, b *BlockGen) { 399 b.OffsetTime(first[i]) 400 }) 401 diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ethash.NewFaker(), db, len(second), func(i int, b *BlockGen) { 402 b.OffsetTime(second[i]) 403 }) 404 if full { 405 if _, err := blockchain.InsertChain(easyBlocks); err != nil { 406 t.Fatalf("failed to insert easy chain: %v", err) 407 } 408 if _, err := blockchain.InsertChain(diffBlocks); err != nil { 409 t.Fatalf("failed to insert difficult chain: %v", err) 410 } 411 } else { 412 easyHeaders := make([]*types.Header, len(easyBlocks)) 413 for i, block := range easyBlocks { 414 easyHeaders[i] = block.Header() 415 } 416 diffHeaders := make([]*types.Header, len(diffBlocks)) 417 for i, block := range diffBlocks { 418 diffHeaders[i] = block.Header() 419 } 420 if _, err := blockchain.InsertHeaderChain(easyHeaders, 1); err != nil { 421 t.Fatalf("failed to insert easy chain: %v", err) 422 } 423 if _, err := blockchain.InsertHeaderChain(diffHeaders, 1); err != nil { 424 t.Fatalf("failed to insert difficult chain: %v", err) 425 } 426 } 427 // Check that the chain is valid number and link wise 428 if full { 429 prev := blockchain.CurrentBlock() 430 for block := blockchain.GetBlockByNumber(blockchain.CurrentBlock().NumberU64() - 1); block.NumberU64() != 0; prev, block = block, blockchain.GetBlockByNumber(block.NumberU64()-1) { 431 if prev.ParentHash() != block.Hash() { 432 t.Errorf("parent block hash mismatch: have %x, want %x", prev.ParentHash(), block.Hash()) 433 } 434 } 435 } else { 436 prev := blockchain.CurrentHeader() 437 for header := blockchain.GetHeaderByNumber(blockchain.CurrentHeader().Number.Uint64() - 1); header.Number.Uint64() != 0; prev, header = header, blockchain.GetHeaderByNumber(header.Number.Uint64()-1) { 438 if prev.ParentHash != header.Hash() { 439 t.Errorf("parent header hash mismatch: have %x, want %x", prev.ParentHash, header.Hash()) 440 } 441 } 442 } 443 // Make sure the chain total difficulty is the correct one 444 want := new(big.Int).Add(blockchain.genesisBlock.Difficulty(), big.NewInt(td)) 445 if full { 446 if have := blockchain.GetTdByHash(blockchain.CurrentBlock().Hash()); have.Cmp(want) != 0 { 447 t.Errorf("total difficulty mismatch: have %v, want %v", have, want) 448 } 449 } else { 450 if have := blockchain.GetTdByHash(blockchain.CurrentHeader().Hash()); have.Cmp(want) != 0 { 451 t.Errorf("total difficulty mismatch: have %v, want %v", have, want) 452 } 453 } 454 } 455 456 // Tests that the insertion functions detect banned hashes. 457 func TestBadHeaderHashes(t *testing.T) { testBadHashes(t, false) } 458 func TestBadBlockHashes(t *testing.T) { testBadHashes(t, true) } 459 460 func testBadHashes(t *testing.T, full bool) { 461 // Create a pristine chain and database 462 db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 463 if err != nil { 464 t.Fatalf("failed to create pristine chain: %v", err) 465 } 466 defer blockchain.Stop() 467 468 // Create a chain, ban a hash and try to import 469 if full { 470 blocks := makeBlockChain(blockchain.CurrentBlock(), 3, ethash.NewFaker(), db, 10) 471 472 BadHashes[blocks[2].Header().Hash()] = true 473 defer func() { delete(BadHashes, blocks[2].Header().Hash()) }() 474 475 _, err = blockchain.InsertChain(blocks) 476 } else { 477 headers := makeHeaderChain(blockchain.CurrentHeader(), 3, ethash.NewFaker(), db, 10) 478 479 BadHashes[headers[2].Hash()] = true 480 defer func() { delete(BadHashes, headers[2].Hash()) }() 481 482 _, err = blockchain.InsertHeaderChain(headers, 1) 483 } 484 if err != ErrBlacklistedHash { 485 t.Errorf("error mismatch: have: %v, want: %v", err, ErrBlacklistedHash) 486 } 487 } 488 489 // Tests that bad hashes are detected on boot, and the chain rolled back to a 490 // good state prior to the bad hash. 491 func TestReorgBadHeaderHashes(t *testing.T) { testReorgBadHashes(t, false) } 492 func TestReorgBadBlockHashes(t *testing.T) { testReorgBadHashes(t, true) } 493 494 func testReorgBadHashes(t *testing.T, full bool) { 495 // Create a pristine chain and database 496 db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 497 if err != nil { 498 t.Fatalf("failed to create pristine chain: %v", err) 499 } 500 // Create a chain, import and ban afterwards 501 headers := makeHeaderChain(blockchain.CurrentHeader(), 4, ethash.NewFaker(), db, 10) 502 blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ethash.NewFaker(), db, 10) 503 504 if full { 505 if _, err = blockchain.InsertChain(blocks); err != nil { 506 t.Errorf("failed to import blocks: %v", err) 507 } 508 if blockchain.CurrentBlock().Hash() != blocks[3].Hash() { 509 t.Errorf("last block hash mismatch: have: %x, want %x", blockchain.CurrentBlock().Hash(), blocks[3].Header().Hash()) 510 } 511 BadHashes[blocks[3].Header().Hash()] = true 512 defer func() { delete(BadHashes, blocks[3].Header().Hash()) }() 513 } else { 514 if _, err = blockchain.InsertHeaderChain(headers, 1); err != nil { 515 t.Errorf("failed to import headers: %v", err) 516 } 517 if blockchain.CurrentHeader().Hash() != headers[3].Hash() { 518 t.Errorf("last header hash mismatch: have: %x, want %x", blockchain.CurrentHeader().Hash(), headers[3].Hash()) 519 } 520 BadHashes[headers[3].Hash()] = true 521 defer func() { delete(BadHashes, headers[3].Hash()) }() 522 } 523 blockchain.Stop() 524 525 // Create a new BlockChain and check that it rolled back the state. 526 ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{}, nil) 527 if err != nil { 528 t.Fatalf("failed to create new chain manager: %v", err) 529 } 530 defer ncm.Stop() 531 532 if full { 533 if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { 534 t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) 535 } 536 if blocks[2].Header().GasLimit != ncm.GasLimit() { 537 t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit) 538 } 539 } else { 540 if ncm.CurrentHeader().Hash() != headers[2].Hash() { 541 t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash()) 542 } 543 } 544 ncm.Stop() 545 } 546 547 // Tests chain insertions in the face of one entity containing an invalid nonce. 548 func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) } 549 func TestBlocksInsertNonceError(t *testing.T) { testInsertNonceError(t, true) } 550 551 func testInsertNonceError(t *testing.T, full bool) { 552 for i := 1; i < 25 && !t.Failed(); i++ { 553 // Create a pristine chain and database 554 db, blockchain, err := newCanonical(ethash.NewFaker(), 0, full) 555 if err != nil { 556 t.Fatalf("failed to create pristine chain: %v", err) 557 } 558 defer blockchain.Stop() 559 560 // Create and insert a chain with a failing nonce 561 var ( 562 failAt int 563 failRes int 564 failNum uint64 565 ) 566 if full { 567 blocks := makeBlockChain(blockchain.CurrentBlock(), i, ethash.NewFaker(), db, 0) 568 569 failAt = rand.Int() % len(blocks) 570 failNum = blocks[failAt].NumberU64() 571 572 blockchain.engine = ethash.NewFakeFailer(failNum) 573 failRes, err = blockchain.InsertChain(blocks) 574 } else { 575 headers := makeHeaderChain(blockchain.CurrentHeader(), i, ethash.NewFaker(), db, 0) 576 577 failAt = rand.Int() % len(headers) 578 failNum = headers[failAt].Number.Uint64() 579 580 blockchain.engine = ethash.NewFakeFailer(failNum) 581 blockchain.hc.engine = blockchain.engine 582 failRes, err = blockchain.InsertHeaderChain(headers, 1) 583 } 584 // Check that the returned error indicates the failure. 585 if failRes != failAt { 586 t.Errorf("test %d: failure index mismatch: have %d, want %d", i, failRes, failAt) 587 } 588 // Check that all no blocks after the failing block have been inserted. 589 for j := 0; j < i-failAt; j++ { 590 if full { 591 if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil { 592 t.Errorf("test %d: invalid block in chain: %v", i, block) 593 } 594 } else { 595 if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil { 596 t.Errorf("test %d: invalid header in chain: %v", i, header) 597 } 598 } 599 } 600 } 601 } 602 603 // Tests that fast importing a block chain produces the same chain data as the 604 // classical full block processing. 605 func TestFastVsFullChains(t *testing.T) { 606 // Configure and generate a sample block chain 607 var ( 608 gendb = ethdb.NewMemDatabase() 609 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 610 address = crypto.PubkeyToAddress(key.PublicKey) 611 funds = big.NewInt(1000000000) 612 gspec = &Genesis{ 613 Config: params.TestChainConfig, 614 Alloc: GenesisAlloc{address: {Balance: funds}}, 615 } 616 genesis = gspec.MustCommit(gendb) 617 signer = types.NewEIP155Signer(gspec.Config.ChainID) 618 ) 619 blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) { 620 block.SetCoinbase(common.Address{0x00}) 621 622 // If the block number is multiple of 3, send a few bonus transactions to the miner 623 if i%3 == 2 { 624 for j := 0; j < i%4+1; j++ { 625 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key) 626 if err != nil { 627 panic(err) 628 } 629 block.AddTx(tx) 630 } 631 } 632 // If the block number is a multiple of 5, add a few bonus uncles to the block 633 if i%5 == 5 { 634 block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))}) 635 } 636 }) 637 // Import the chain as an archive node for the comparison baseline 638 archiveDb := ethdb.NewMemDatabase() 639 gspec.MustCommit(archiveDb) 640 archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 641 defer archive.Stop() 642 643 if n, err := archive.InsertChain(blocks); err != nil { 644 t.Fatalf("failed to process block %d: %v", n, err) 645 } 646 // Fast import the chain as a non-archive node to test 647 fastDb := ethdb.NewMemDatabase() 648 gspec.MustCommit(fastDb) 649 fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 650 defer fast.Stop() 651 652 headers := make([]*types.Header, len(blocks)) 653 for i, block := range blocks { 654 headers[i] = block.Header() 655 } 656 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 657 t.Fatalf("failed to insert header %d: %v", n, err) 658 } 659 if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { 660 t.Fatalf("failed to insert receipt %d: %v", n, err) 661 } 662 // Iterate over all chain data components, and cross reference 663 for i := 0; i < len(blocks); i++ { 664 num, hash := blocks[i].NumberU64(), blocks[i].Hash() 665 666 if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 { 667 t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd) 668 } 669 if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() { 670 t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader) 671 } 672 if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() { 673 t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock) 674 } else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) { 675 t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions()) 676 } else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) { 677 t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles()) 678 } 679 if freceipts, areceipts := rawdb.ReadReceipts(fastDb, hash, *rawdb.ReadHeaderNumber(fastDb, hash)), rawdb.ReadReceipts(archiveDb, hash, *rawdb.ReadHeaderNumber(archiveDb, hash)); types.DeriveSha(freceipts) != types.DeriveSha(areceipts) { 680 t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts) 681 } 682 } 683 // Check that the canonical chains are the same between the databases 684 for i := 0; i < len(blocks)+1; i++ { 685 if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash { 686 t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash) 687 } 688 } 689 } 690 691 // Tests that various import methods move the chain head pointers to the correct 692 // positions. 693 func TestLightVsFastVsFullChainHeads(t *testing.T) { 694 // Configure and generate a sample block chain 695 var ( 696 gendb = ethdb.NewMemDatabase() 697 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 698 address = crypto.PubkeyToAddress(key.PublicKey) 699 funds = big.NewInt(1000000000) 700 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} 701 genesis = gspec.MustCommit(gendb) 702 ) 703 height := uint64(1024) 704 blocks, receipts := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), gendb, int(height), nil) 705 706 // Configure a subchain to roll back 707 remove := []common.Hash{} 708 for _, block := range blocks[height/2:] { 709 remove = append(remove, block.Hash()) 710 } 711 // Create a small assertion method to check the three heads 712 assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) { 713 if num := chain.CurrentBlock().NumberU64(); num != block { 714 t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block) 715 } 716 if num := chain.CurrentFastBlock().NumberU64(); num != fast { 717 t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast) 718 } 719 if num := chain.CurrentHeader().Number.Uint64(); num != header { 720 t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header) 721 } 722 } 723 // Import the chain as an archive node and ensure all pointers are updated 724 archiveDb := ethdb.NewMemDatabase() 725 gspec.MustCommit(archiveDb) 726 727 archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 728 if n, err := archive.InsertChain(blocks); err != nil { 729 t.Fatalf("failed to process block %d: %v", n, err) 730 } 731 defer archive.Stop() 732 733 assert(t, "archive", archive, height, height, height) 734 archive.Rollback(remove) 735 assert(t, "archive", archive, height/2, height/2, height/2) 736 737 // Import the chain as a non-archive node and ensure all pointers are updated 738 fastDb := ethdb.NewMemDatabase() 739 gspec.MustCommit(fastDb) 740 fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 741 defer fast.Stop() 742 743 headers := make([]*types.Header, len(blocks)) 744 for i, block := range blocks { 745 headers[i] = block.Header() 746 } 747 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 748 t.Fatalf("failed to insert header %d: %v", n, err) 749 } 750 if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { 751 t.Fatalf("failed to insert receipt %d: %v", n, err) 752 } 753 assert(t, "fast", fast, height, height, 0) 754 fast.Rollback(remove) 755 assert(t, "fast", fast, height/2, height/2, 0) 756 757 // Import the chain as a light node and ensure all pointers are updated 758 lightDb := ethdb.NewMemDatabase() 759 gspec.MustCommit(lightDb) 760 761 light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 762 if n, err := light.InsertHeaderChain(headers, 1); err != nil { 763 t.Fatalf("failed to insert header %d: %v", n, err) 764 } 765 defer light.Stop() 766 767 assert(t, "light", light, height, 0, 0) 768 light.Rollback(remove) 769 assert(t, "light", light, height/2, 0, 0) 770 } 771 772 // Tests that chain reorganisations handle transaction removals and reinsertions. 773 func TestChainTxReorgs(t *testing.T) { 774 var ( 775 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 776 key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 777 key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") 778 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 779 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 780 addr3 = crypto.PubkeyToAddress(key3.PublicKey) 781 db = ethdb.NewMemDatabase() 782 gspec = &Genesis{ 783 Config: params.TestChainConfig, 784 GasLimit: 700000000, 785 Alloc: GenesisAlloc{ 786 addr1: {Balance: big.NewInt(1000000)}, 787 addr2: {Balance: big.NewInt(1000000)}, 788 addr3: {Balance: big.NewInt(1000000)}, 789 }, 790 } 791 genesis = gspec.MustCommit(db) 792 signer = types.NewEIP155Signer(gspec.Config.ChainID) 793 ) 794 795 // Create two transactions shared between the chains: 796 // - postponed: transaction included at a later block in the forked chain 797 // - swapped: transaction included at the same block number in the forked chain 798 postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) 799 swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) 800 801 // Create two transactions that will be dropped by the forked chain: 802 // - pastDrop: transaction dropped retroactively from a past block 803 // - freshDrop: transaction dropped exactly at the block where the reorg is detected 804 var pastDrop, freshDrop *types.Transaction 805 806 // Create three transactions that will be added in the forked chain: 807 // - pastAdd: transaction added before the reorganization is detected 808 // - freshAdd: transaction added at the exact block the reorg is detected 809 // - futureAdd: transaction added after the reorg has already finished 810 var pastAdd, freshAdd, futureAdd *types.Transaction 811 812 chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) { 813 switch i { 814 case 0: 815 pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) 816 817 gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point 818 gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork 819 820 case 2: 821 freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) 822 823 gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point 824 gen.AddTx(swapped) // This transaction will be swapped out at the exact height 825 826 gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain 827 } 828 }) 829 // Import the chain. This runs all block validation rules. 830 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 831 if i, err := blockchain.InsertChain(chain); err != nil { 832 t.Fatalf("failed to insert original chain[%d]: %v", i, err) 833 } 834 defer blockchain.Stop() 835 836 // overwrite the old chain 837 chain, _ = GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 5, func(i int, gen *BlockGen) { 838 switch i { 839 case 0: 840 pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 841 gen.AddTx(pastAdd) // This transaction needs to be injected during reorg 842 843 case 2: 844 gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain 845 gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain 846 847 freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 848 gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time 849 850 case 3: 851 futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 852 gen.AddTx(futureAdd) // This transaction will be added after a full reorg 853 } 854 }) 855 if _, err := blockchain.InsertChain(chain); err != nil { 856 t.Fatalf("failed to insert forked chain: %v", err) 857 } 858 859 // removed tx 860 for i, tx := range (types.Transactions{pastDrop, freshDrop}) { 861 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil { 862 t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) 863 } 864 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil { 865 t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt) 866 } 867 } 868 // added tx 869 for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { 870 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 871 t.Errorf("add %d: expected tx to be found", i) 872 } 873 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { 874 t.Errorf("add %d: expected receipt to be found", i) 875 } 876 } 877 // shared tx 878 for i, tx := range (types.Transactions{postponed, swapped}) { 879 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 880 t.Errorf("share %d: expected tx to be found", i) 881 } 882 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { 883 t.Errorf("share %d: expected receipt to be found", i) 884 } 885 } 886 } 887 888 func TestLogReorgs(t *testing.T) { 889 890 var ( 891 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 892 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 893 db = ethdb.NewMemDatabase() 894 // this code generates a log 895 code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 896 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} 897 genesis = gspec.MustCommit(db) 898 signer = types.NewEIP155Signer(gspec.Config.ChainID) 899 ) 900 901 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 902 defer blockchain.Stop() 903 904 rmLogsCh := make(chan RemovedLogsEvent) 905 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 906 chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 907 if i == 1 { 908 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) 909 if err != nil { 910 t.Fatalf("failed to create tx: %v", err) 911 } 912 gen.AddTx(tx) 913 } 914 }) 915 if _, err := blockchain.InsertChain(chain); err != nil { 916 t.Fatalf("failed to insert chain: %v", err) 917 } 918 919 chain, _ = GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) 920 if _, err := blockchain.InsertChain(chain); err != nil { 921 t.Fatalf("failed to insert forked chain: %v", err) 922 } 923 924 timeout := time.NewTimer(1 * time.Second) 925 select { 926 case ev := <-rmLogsCh: 927 if len(ev.Logs) == 0 { 928 t.Error("expected logs") 929 } 930 case <-timeout.C: 931 t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") 932 } 933 } 934 935 func TestReorgSideEvent(t *testing.T) { 936 var ( 937 db = ethdb.NewMemDatabase() 938 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 939 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 940 gspec = &Genesis{ 941 Config: params.TestChainConfig, 942 Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}, 943 } 944 genesis = gspec.MustCommit(db) 945 signer = types.NewEIP155Signer(gspec.Config.ChainID) 946 ) 947 948 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 949 defer blockchain.Stop() 950 951 chain, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) 952 if _, err := blockchain.InsertChain(chain); err != nil { 953 t.Fatalf("failed to insert chain: %v", err) 954 } 955 956 replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, gen *BlockGen) { 957 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1) 958 if i == 2 { 959 gen.OffsetTime(-9) 960 } 961 if err != nil { 962 t.Fatalf("failed to create tx: %v", err) 963 } 964 gen.AddTx(tx) 965 }) 966 chainSideCh := make(chan ChainSideEvent, 64) 967 blockchain.SubscribeChainSideEvent(chainSideCh) 968 if _, err := blockchain.InsertChain(replacementBlocks); err != nil { 969 t.Fatalf("failed to insert chain: %v", err) 970 } 971 972 // first two block of the secondary chain are for a brief moment considered 973 // side chains because up to that point the first one is considered the 974 // heavier chain. 975 expectedSideHashes := map[common.Hash]bool{ 976 replacementBlocks[0].Hash(): true, 977 replacementBlocks[1].Hash(): true, 978 chain[0].Hash(): true, 979 chain[1].Hash(): true, 980 chain[2].Hash(): true, 981 } 982 983 i := 0 984 985 const timeoutDura = 10 * time.Second 986 timeout := time.NewTimer(timeoutDura) 987 done: 988 for { 989 select { 990 case ev := <-chainSideCh: 991 block := ev.Block 992 if _, ok := expectedSideHashes[block.Hash()]; !ok { 993 t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) 994 } 995 i++ 996 997 if i == len(expectedSideHashes) { 998 timeout.Stop() 999 1000 break done 1001 } 1002 timeout.Reset(timeoutDura) 1003 1004 case <-timeout.C: 1005 t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") 1006 } 1007 } 1008 1009 // make sure no more events are fired 1010 select { 1011 case e := <-chainSideCh: 1012 t.Errorf("unexpected event fired: %v", e) 1013 case <-time.After(250 * time.Millisecond): 1014 } 1015 1016 } 1017 1018 // Tests if the canonical block can be fetched from the database during chain insertion. 1019 func TestCanonicalBlockRetrieval(t *testing.T) { 1020 _, blockchain, err := newCanonical(ethash.NewFaker(), 0, true) 1021 if err != nil { 1022 t.Fatalf("failed to create pristine chain: %v", err) 1023 } 1024 defer blockchain.Stop() 1025 1026 chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ethash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {}) 1027 1028 var pend sync.WaitGroup 1029 pend.Add(len(chain)) 1030 1031 for i := range chain { 1032 go func(block *types.Block) { 1033 defer pend.Done() 1034 1035 // try to retrieve a block by its canonical hash and see if the block data can be retrieved. 1036 for { 1037 ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64()) 1038 if ch == (common.Hash{}) { 1039 continue // busy wait for canonical hash to be written 1040 } 1041 if ch != block.Hash() { 1042 t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) 1043 } 1044 fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64()) 1045 if fb == nil { 1046 t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) 1047 } 1048 if fb.Hash() != block.Hash() { 1049 t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex()) 1050 } 1051 return 1052 } 1053 }(chain[i]) 1054 1055 if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil { 1056 t.Fatalf("failed to insert block %d: %v", i, err) 1057 } 1058 } 1059 pend.Wait() 1060 } 1061 1062 func TestEIP155Transition(t *testing.T) { 1063 // Configure and generate a sample block chain 1064 var ( 1065 db = ethdb.NewMemDatabase() 1066 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1067 address = crypto.PubkeyToAddress(key.PublicKey) 1068 funds = big.NewInt(1000000000) 1069 deleteAddr = common.Address{1} 1070 gspec = &Genesis{ 1071 Config: ¶ms.ChainConfig{ChainID: big.NewInt(10), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, 1072 Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, 1073 } 1074 genesis = gspec.MustCommit(db) 1075 ) 1076 1077 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 1078 defer blockchain.Stop() 1079 1080 blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) { 1081 var ( 1082 tx *types.Transaction 1083 err error 1084 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1085 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1086 } 1087 ) 1088 switch i { 1089 case 0: 1090 tx, err = basicTx(types.HomesteadSigner{}) 1091 if err != nil { 1092 t.Fatal(err) 1093 } 1094 block.AddTx(tx) 1095 case 2: 1096 tx, err = basicTx(types.HomesteadSigner{}) 1097 if err != nil { 1098 t.Fatal(err) 1099 } 1100 block.AddTx(tx) 1101 1102 tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) 1103 if err != nil { 1104 t.Fatal(err) 1105 } 1106 block.AddTx(tx) 1107 case 3: 1108 tx, err = basicTx(types.HomesteadSigner{}) 1109 if err != nil { 1110 t.Fatal(err) 1111 } 1112 block.AddTx(tx) 1113 1114 tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) 1115 if err != nil { 1116 t.Fatal(err) 1117 } 1118 block.AddTx(tx) 1119 } 1120 }) 1121 1122 if _, err := blockchain.InsertChain(blocks); err != nil { 1123 t.Fatal(err) 1124 } 1125 block := blockchain.GetBlockByNumber(1) 1126 if block.Transactions()[0].Protected() { 1127 t.Error("Expected block[0].txs[0] to not be replay protected") 1128 } 1129 1130 block = blockchain.GetBlockByNumber(3) 1131 if block.Transactions()[0].Protected() { 1132 t.Error("Expected block[3].txs[0] to not be replay protected") 1133 } 1134 if !block.Transactions()[1].Protected() { 1135 t.Error("Expected block[3].txs[1] to be replay protected") 1136 } 1137 if _, err := blockchain.InsertChain(blocks[4:]); err != nil { 1138 t.Fatal(err) 1139 } 1140 1141 // generate an invalid chain id transaction 1142 config := ¶ms.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)} 1143 blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ethash.NewFaker(), db, 4, func(i int, block *BlockGen) { 1144 var ( 1145 tx *types.Transaction 1146 err error 1147 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1148 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1149 } 1150 ) 1151 if i == 0 { 1152 tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2))) 1153 if err != nil { 1154 t.Fatal(err) 1155 } 1156 block.AddTx(tx) 1157 } 1158 }) 1159 _, err := blockchain.InsertChain(blocks) 1160 if err != types.ErrInvalidChainId { 1161 t.Error("expected error:", types.ErrInvalidChainId) 1162 } 1163 } 1164 1165 func TestEIP161AccountRemoval(t *testing.T) { 1166 // Configure and generate a sample block chain 1167 var ( 1168 db = ethdb.NewMemDatabase() 1169 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1170 address = crypto.PubkeyToAddress(key.PublicKey) 1171 funds = big.NewInt(1000000000) 1172 theAddr = common.Address{1} 1173 gspec = &Genesis{ 1174 Config: ¶ms.ChainConfig{ 1175 ChainID: big.NewInt(10), 1176 HomesteadBlock: new(big.Int), 1177 EIP155Block: new(big.Int), 1178 EIP158Block: big.NewInt(2), 1179 }, 1180 Alloc: GenesisAlloc{address: {Balance: funds}}, 1181 } 1182 genesis = gspec.MustCommit(db) 1183 ) 1184 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 1185 defer blockchain.Stop() 1186 1187 blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) { 1188 var ( 1189 tx *types.Transaction 1190 err error 1191 signer = types.NewEIP155Signer(gspec.Config.ChainID) 1192 ) 1193 switch i { 1194 case 0: 1195 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1196 case 1: 1197 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1198 case 2: 1199 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1200 } 1201 if err != nil { 1202 t.Fatal(err) 1203 } 1204 block.AddTx(tx) 1205 }) 1206 // account must exist pre eip 161 1207 if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil { 1208 t.Fatal(err) 1209 } 1210 if st, _, _ := blockchain.State(); !st.Exist(theAddr) { 1211 t.Error("expected account to exist") 1212 } 1213 1214 // account needs to be deleted post eip 161 1215 if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil { 1216 t.Fatal(err) 1217 } 1218 if st, _, _ := blockchain.State(); st.Exist(theAddr) { 1219 t.Error("account should not exist") 1220 } 1221 1222 // account musn't be created post eip 161 1223 if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil { 1224 t.Fatal(err) 1225 } 1226 if st, _, _ := blockchain.State(); st.Exist(theAddr) { 1227 t.Error("account should not exist") 1228 } 1229 } 1230 1231 // This is a regression test (i.e. as weird as it is, don't delete it ever), which 1232 // tests that under weird reorg conditions the blockchain and its internal header- 1233 // chain return the same latest block/header. 1234 // 1235 // https://github.com/ethereum/go-ethereum/pull/15941 1236 func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { 1237 // Generate a canonical chain to act as the main dataset 1238 engine := ethash.NewFaker() 1239 1240 db := ethdb.NewMemDatabase() 1241 genesis := new(Genesis).MustCommit(db) 1242 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1243 1244 // Generate a bunch of fork blocks, each side forking from the canonical chain 1245 forks := make([]*types.Block, len(blocks)) 1246 for i := 0; i < len(forks); i++ { 1247 parent := genesis 1248 if i > 0 { 1249 parent = blocks[i-1] 1250 } 1251 fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1252 forks[i] = fork[0] 1253 } 1254 // Import the canonical and fork chain side by side, verifying the current block 1255 // and current header consistency 1256 diskdb := ethdb.NewMemDatabase() 1257 new(Genesis).MustCommit(diskdb) 1258 1259 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1260 if err != nil { 1261 t.Fatalf("failed to create tester chain: %v", err) 1262 } 1263 for i := 0; i < len(blocks); i++ { 1264 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1265 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1266 } 1267 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1268 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]) 1269 } 1270 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1271 t.Fatalf(" fork %d: failed to insert into chain: %v", i, err) 1272 } 1273 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1274 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]) 1275 } 1276 } 1277 } 1278 1279 // Tests that importing small side forks doesn't leave junk in the trie database 1280 // cache (which would eventually cause memory issues). 1281 func TestTrieForkGC(t *testing.T) { 1282 // Generate a canonical chain to act as the main dataset 1283 engine := ethash.NewFaker() 1284 1285 db := ethdb.NewMemDatabase() 1286 genesis := new(Genesis).MustCommit(db) 1287 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1288 1289 // Generate a bunch of fork blocks, each side forking from the canonical chain 1290 forks := make([]*types.Block, len(blocks)) 1291 for i := 0; i < len(forks); i++ { 1292 parent := genesis 1293 if i > 0 { 1294 parent = blocks[i-1] 1295 } 1296 fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1297 forks[i] = fork[0] 1298 } 1299 // Import the canonical and fork chain side by side, forcing the trie cache to cache both 1300 diskdb := ethdb.NewMemDatabase() 1301 new(Genesis).MustCommit(diskdb) 1302 1303 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1304 if err != nil { 1305 t.Fatalf("failed to create tester chain: %v", err) 1306 } 1307 for i := 0; i < len(blocks); i++ { 1308 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1309 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1310 } 1311 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1312 t.Fatalf("fork %d: failed to insert into chain: %v", i, err) 1313 } 1314 } 1315 // Dereference all the recent tries and ensure no past trie is left in 1316 for i := 0; i < triesInMemory; i++ { 1317 chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root()) 1318 chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root()) 1319 } 1320 if len(chain.stateCache.TrieDB().Nodes()) > 0 { 1321 t.Fatalf("stale tries still alive after garbase collection") 1322 } 1323 } 1324 1325 // Tests that doing large reorgs works even if the state associated with the 1326 // forking point is not available any more. 1327 func TestLargeReorgTrieGC(t *testing.T) { 1328 // Generate the original common chain segment and the two competing forks 1329 engine := ethash.NewFaker() 1330 1331 db := ethdb.NewMemDatabase() 1332 genesis := new(Genesis).MustCommit(db) 1333 1334 shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1335 original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1336 competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) 1337 1338 // Import the shared chain and the original canonical one 1339 diskdb := ethdb.NewMemDatabase() 1340 new(Genesis).MustCommit(diskdb) 1341 1342 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1343 if err != nil { 1344 t.Fatalf("failed to create tester chain: %v", err) 1345 } 1346 if _, err := chain.InsertChain(shared); err != nil { 1347 t.Fatalf("failed to insert shared chain: %v", err) 1348 } 1349 if _, err := chain.InsertChain(original); err != nil { 1350 t.Fatalf("failed to insert shared chain: %v", err) 1351 } 1352 // Ensure that the state associated with the forking point is pruned away 1353 if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil { 1354 t.Fatalf("common-but-old ancestor still cache") 1355 } 1356 // Import the competitor chain without exceeding the canonical's TD and ensure 1357 // we have not processed any of the blocks (protection against malicious blocks) 1358 if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil { 1359 t.Fatalf("failed to insert competitor chain: %v", err) 1360 } 1361 for i, block := range competitor[:len(competitor)-2] { 1362 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1363 t.Fatalf("competitor %d: low TD chain became processed", i) 1364 } 1365 } 1366 // Import the head of the competitor chain, triggering the reorg and ensure we 1367 // successfully reprocess all the stashed away blocks. 1368 if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil { 1369 t.Fatalf("failed to finalize competitor chain: %v", err) 1370 } 1371 for i, block := range competitor[:len(competitor)-triesInMemory] { 1372 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1373 t.Fatalf("competitor %d: competing chain state missing", i) 1374 } 1375 } 1376 } 1377 1378 // Benchmarks large blocks with value transfers to non-existing accounts 1379 func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) { 1380 var ( 1381 signer = types.HomesteadSigner{} 1382 testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1383 testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) 1384 bankFunds = big.NewInt(100000000000000000) 1385 gspec = Genesis{ 1386 Config: params.TestChainConfig, 1387 Alloc: GenesisAlloc{ 1388 testBankAddress: {Balance: bankFunds}, 1389 common.HexToAddress("0xc0de"): { 1390 Code: []byte{0x60, 0x01, 0x50}, 1391 Balance: big.NewInt(0), 1392 }, // push 1, pop 1393 }, 1394 GasLimit: 100e6, // 100 M 1395 } 1396 ) 1397 // Generate the original common chain segment and the two competing forks 1398 engine := ethash.NewFaker() 1399 db := ethdb.NewMemDatabase() 1400 genesis := gspec.MustCommit(db) 1401 1402 blockGenerator := func(i int, block *BlockGen) { 1403 block.SetCoinbase(common.Address{1}) 1404 for txi := 0; txi < numTxs; txi++ { 1405 uniq := uint64(i*numTxs + txi) 1406 recipient := recipientFn(uniq) 1407 //recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq)) 1408 tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey) 1409 if err != nil { 1410 b.Error(err) 1411 } 1412 block.AddTx(tx) 1413 } 1414 } 1415 1416 shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator) 1417 b.StopTimer() 1418 b.ResetTimer() 1419 for i := 0; i < b.N; i++ { 1420 // Import the shared chain and the original canonical one 1421 diskdb := ethdb.NewMemDatabase() 1422 gspec.MustCommit(diskdb) 1423 1424 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1425 if err != nil { 1426 b.Fatalf("failed to create tester chain: %v", err) 1427 } 1428 b.StartTimer() 1429 if _, err := chain.InsertChain(shared); err != nil { 1430 b.Fatalf("failed to insert shared chain: %v", err) 1431 } 1432 b.StopTimer() 1433 if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks { 1434 b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got) 1435 1436 } 1437 } 1438 } 1439 func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { 1440 var ( 1441 numTxs = 1000 1442 numBlocks = 1 1443 ) 1444 1445 recipientFn := func(nonce uint64) common.Address { 1446 return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce)) 1447 } 1448 dataFn := func(nonce uint64) []byte { 1449 return nil 1450 } 1451 1452 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1453 } 1454 func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { 1455 var ( 1456 numTxs = 1000 1457 numBlocks = 1 1458 ) 1459 b.StopTimer() 1460 b.ResetTimer() 1461 1462 recipientFn := func(nonce uint64) common.Address { 1463 return common.BigToAddress(big.NewInt(0).SetUint64(1337)) 1464 } 1465 dataFn := func(nonce uint64) []byte { 1466 return nil 1467 } 1468 1469 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1470 } 1471 func BenchmarkBlockChain_1x1000Executions(b *testing.B) { 1472 var ( 1473 numTxs = 1000 1474 numBlocks = 1 1475 ) 1476 b.StopTimer() 1477 b.ResetTimer() 1478 1479 recipientFn := func(nonce uint64) common.Address { 1480 return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de)) 1481 } 1482 dataFn := func(nonce uint64) []byte { 1483 return nil 1484 } 1485 1486 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1487 }