github.com/ubiq/go-ethereum@v3.0.1+incompatible/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/ubiq/go-ubiq/common" 28 "github.com/ubiq/go-ubiq/consensus" 29 "github.com/ubiq/go-ubiq/consensus/ubqhash" 30 "github.com/ubiq/go-ubiq/core/rawdb" 31 "github.com/ubiq/go-ubiq/core/state" 32 "github.com/ubiq/go-ubiq/core/types" 33 "github.com/ubiq/go-ubiq/core/vm" 34 "github.com/ubiq/go-ubiq/crypto" 35 "github.com/ubiq/go-ubiq/ethdb" 36 "github.com/ubiq/go-ubiq/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.AllUbqhashProtocolChanges, 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(ubqhash.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, ubqhash.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, ubqhash.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, 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(ubqhash.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, ubqhash.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(ubqhash.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(ubqhash.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(ubqhash.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(ubqhash.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(ubqhash.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, ubqhash.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, ubqhash.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(ubqhash.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(), ubqhash.NewFaker(), db, len(first), func(i int, b *BlockGen) { 399 b.OffsetTime(first[i]) 400 }) 401 diffBlocks, _ := GenerateChain(params.TestChainConfig, blockchain.CurrentBlock(), ubqhash.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(ubqhash.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, ubqhash.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, ubqhash.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(ubqhash.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, ubqhash.NewFaker(), db, 10) 502 blocks := makeBlockChain(blockchain.CurrentBlock(), 4, ubqhash.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, ubqhash.NewFaker(), vm.Config{}, nil) 527 if err != nil { 528 t.Fatalf("failed to create new chain manager: %v", err) 529 } 530 if full { 531 if ncm.CurrentBlock().Hash() != blocks[2].Header().Hash() { 532 t.Errorf("last block hash mismatch: have: %x, want %x", ncm.CurrentBlock().Hash(), blocks[2].Header().Hash()) 533 } 534 if blocks[2].Header().GasLimit != ncm.GasLimit() { 535 t.Errorf("last block gasLimit mismatch: have: %d, want %d", ncm.GasLimit(), blocks[2].Header().GasLimit) 536 } 537 } else { 538 if ncm.CurrentHeader().Hash() != headers[2].Hash() { 539 t.Errorf("last header hash mismatch: have: %x, want %x", ncm.CurrentHeader().Hash(), headers[2].Hash()) 540 } 541 } 542 ncm.Stop() 543 } 544 545 // Tests chain insertions in the face of one entity containing an invalid nonce. 546 func TestHeadersInsertNonceError(t *testing.T) { testInsertNonceError(t, false) } 547 func TestBlocksInsertNonceError(t *testing.T) { testInsertNonceError(t, true) } 548 549 func testInsertNonceError(t *testing.T, full bool) { 550 for i := 1; i < 25 && !t.Failed(); i++ { 551 // Create a pristine chain and database 552 db, blockchain, err := newCanonical(ubqhash.NewFaker(), 0, full) 553 if err != nil { 554 t.Fatalf("failed to create pristine chain: %v", err) 555 } 556 defer blockchain.Stop() 557 558 // Create and insert a chain with a failing nonce 559 var ( 560 failAt int 561 failRes int 562 failNum uint64 563 ) 564 if full { 565 blocks := makeBlockChain(blockchain.CurrentBlock(), i, ubqhash.NewFaker(), db, 0) 566 567 failAt = rand.Int() % len(blocks) 568 failNum = blocks[failAt].NumberU64() 569 570 blockchain.engine = ubqhash.NewFakeFailer(failNum) 571 failRes, err = blockchain.InsertChain(blocks) 572 } else { 573 headers := makeHeaderChain(blockchain.CurrentHeader(), i, ubqhash.NewFaker(), db, 0) 574 575 failAt = rand.Int() % len(headers) 576 failNum = headers[failAt].Number.Uint64() 577 578 blockchain.engine = ubqhash.NewFakeFailer(failNum) 579 blockchain.hc.engine = blockchain.engine 580 failRes, err = blockchain.InsertHeaderChain(headers, 1) 581 } 582 // Check that the returned error indicates the failure 583 if failRes != failAt { 584 t.Errorf("test %d: failure (%v) index mismatch: have %d, want %d", i, err, failRes, failAt) 585 } 586 // Check that all blocks after the failing block have been inserted 587 for j := 0; j < i-failAt; j++ { 588 if full { 589 if block := blockchain.GetBlockByNumber(failNum + uint64(j)); block != nil { 590 t.Errorf("test %d: invalid block in chain: %v", i, block) 591 } 592 } else { 593 if header := blockchain.GetHeaderByNumber(failNum + uint64(j)); header != nil { 594 t.Errorf("test %d: invalid header in chain: %v", i, header) 595 } 596 } 597 } 598 } 599 } 600 601 // Tests that fast importing a block chain produces the same chain data as the 602 // classical full block processing. 603 func TestFastVsFullChains(t *testing.T) { 604 // Configure and generate a sample block chain 605 var ( 606 gendb = ethdb.NewMemDatabase() 607 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 608 address = crypto.PubkeyToAddress(key.PublicKey) 609 funds = big.NewInt(1000000000) 610 gspec = &Genesis{ 611 Config: params.TestChainConfig, 612 Alloc: GenesisAlloc{address: {Balance: funds}}, 613 } 614 genesis = gspec.MustCommit(gendb) 615 signer = types.NewEIP155Signer(gspec.Config.ChainID) 616 ) 617 blocks, receipts := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), gendb, 1024, func(i int, block *BlockGen) { 618 block.SetCoinbase(common.Address{0x00}) 619 620 // If the block number is multiple of 3, send a few bonus transactions to the miner 621 if i%3 == 2 { 622 for j := 0; j < i%4+1; j++ { 623 tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key) 624 if err != nil { 625 panic(err) 626 } 627 block.AddTx(tx) 628 } 629 } 630 // If the block number is a multiple of 5, add a few bonus uncles to the block 631 if i%5 == 5 { 632 block.AddUncle(&types.Header{ParentHash: block.PrevBlock(i - 1).Hash(), Number: big.NewInt(int64(i - 1))}) 633 } 634 }) 635 // Import the chain as an archive node for the comparison baseline 636 archiveDb := ethdb.NewMemDatabase() 637 gspec.MustCommit(archiveDb) 638 archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 639 defer archive.Stop() 640 641 if n, err := archive.InsertChain(blocks); err != nil { 642 t.Fatalf("failed to process block %d: %v", n, err) 643 } 644 // Fast import the chain as a non-archive node to test 645 fastDb := ethdb.NewMemDatabase() 646 gspec.MustCommit(fastDb) 647 fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 648 defer fast.Stop() 649 650 headers := make([]*types.Header, len(blocks)) 651 for i, block := range blocks { 652 headers[i] = block.Header() 653 } 654 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 655 t.Fatalf("failed to insert header %d: %v", n, err) 656 } 657 if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { 658 t.Fatalf("failed to insert receipt %d: %v", n, err) 659 } 660 // Iterate over all chain data components, and cross reference 661 for i := 0; i < len(blocks); i++ { 662 num, hash := blocks[i].NumberU64(), blocks[i].Hash() 663 664 if ftd, atd := fast.GetTdByHash(hash), archive.GetTdByHash(hash); ftd.Cmp(atd) != 0 { 665 t.Errorf("block #%d [%x]: td mismatch: have %v, want %v", num, hash, ftd, atd) 666 } 667 if fheader, aheader := fast.GetHeaderByHash(hash), archive.GetHeaderByHash(hash); fheader.Hash() != aheader.Hash() { 668 t.Errorf("block #%d [%x]: header mismatch: have %v, want %v", num, hash, fheader, aheader) 669 } 670 if fblock, ablock := fast.GetBlockByHash(hash), archive.GetBlockByHash(hash); fblock.Hash() != ablock.Hash() { 671 t.Errorf("block #%d [%x]: block mismatch: have %v, want %v", num, hash, fblock, ablock) 672 } else if types.DeriveSha(fblock.Transactions()) != types.DeriveSha(ablock.Transactions()) { 673 t.Errorf("block #%d [%x]: transactions mismatch: have %v, want %v", num, hash, fblock.Transactions(), ablock.Transactions()) 674 } else if types.CalcUncleHash(fblock.Uncles()) != types.CalcUncleHash(ablock.Uncles()) { 675 t.Errorf("block #%d [%x]: uncles mismatch: have %v, want %v", num, hash, fblock.Uncles(), ablock.Uncles()) 676 } 677 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) { 678 t.Errorf("block #%d [%x]: receipts mismatch: have %v, want %v", num, hash, freceipts, areceipts) 679 } 680 } 681 // Check that the canonical chains are the same between the databases 682 for i := 0; i < len(blocks)+1; i++ { 683 if fhash, ahash := rawdb.ReadCanonicalHash(fastDb, uint64(i)), rawdb.ReadCanonicalHash(archiveDb, uint64(i)); fhash != ahash { 684 t.Errorf("block #%d: canonical hash mismatch: have %v, want %v", i, fhash, ahash) 685 } 686 } 687 } 688 689 // Tests that various import methods move the chain head pointers to the correct 690 // positions. 691 func TestLightVsFastVsFullChainHeads(t *testing.T) { 692 // Configure and generate a sample block chain 693 var ( 694 gendb = ethdb.NewMemDatabase() 695 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 696 address = crypto.PubkeyToAddress(key.PublicKey) 697 funds = big.NewInt(1000000000) 698 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{address: {Balance: funds}}} 699 genesis = gspec.MustCommit(gendb) 700 ) 701 height := uint64(1024) 702 blocks, receipts := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), gendb, int(height), nil) 703 704 // Configure a subchain to roll back 705 remove := []common.Hash{} 706 for _, block := range blocks[height/2:] { 707 remove = append(remove, block.Hash()) 708 } 709 // Create a small assertion method to check the three heads 710 assert := func(t *testing.T, kind string, chain *BlockChain, header uint64, fast uint64, block uint64) { 711 if num := chain.CurrentBlock().NumberU64(); num != block { 712 t.Errorf("%s head block mismatch: have #%v, want #%v", kind, num, block) 713 } 714 if num := chain.CurrentFastBlock().NumberU64(); num != fast { 715 t.Errorf("%s head fast-block mismatch: have #%v, want #%v", kind, num, fast) 716 } 717 if num := chain.CurrentHeader().Number.Uint64(); num != header { 718 t.Errorf("%s head header mismatch: have #%v, want #%v", kind, num, header) 719 } 720 } 721 // Import the chain as an archive node and ensure all pointers are updated 722 archiveDb := ethdb.NewMemDatabase() 723 gspec.MustCommit(archiveDb) 724 725 archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 726 if n, err := archive.InsertChain(blocks); err != nil { 727 t.Fatalf("failed to process block %d: %v", n, err) 728 } 729 defer archive.Stop() 730 731 assert(t, "archive", archive, height, height, height) 732 archive.Rollback(remove) 733 assert(t, "archive", archive, height/2, height/2, height/2) 734 735 // Import the chain as a non-archive node and ensure all pointers are updated 736 fastDb := ethdb.NewMemDatabase() 737 gspec.MustCommit(fastDb) 738 fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 739 defer fast.Stop() 740 741 headers := make([]*types.Header, len(blocks)) 742 for i, block := range blocks { 743 headers[i] = block.Header() 744 } 745 if n, err := fast.InsertHeaderChain(headers, 1); err != nil { 746 t.Fatalf("failed to insert header %d: %v", n, err) 747 } 748 if n, err := fast.InsertReceiptChain(blocks, receipts); err != nil { 749 t.Fatalf("failed to insert receipt %d: %v", n, err) 750 } 751 assert(t, "fast", fast, height, height, 0) 752 fast.Rollback(remove) 753 assert(t, "fast", fast, height/2, height/2, 0) 754 755 // Import the chain as a light node and ensure all pointers are updated 756 lightDb := ethdb.NewMemDatabase() 757 gspec.MustCommit(lightDb) 758 759 light, _ := NewBlockChain(lightDb, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 760 if n, err := light.InsertHeaderChain(headers, 1); err != nil { 761 t.Fatalf("failed to insert header %d: %v", n, err) 762 } 763 defer light.Stop() 764 765 assert(t, "light", light, height, 0, 0) 766 light.Rollback(remove) 767 assert(t, "light", light, height/2, 0, 0) 768 } 769 770 // Tests that chain reorganisations handle transaction removals and reinsertions. 771 func TestChainTxReorgs(t *testing.T) { 772 var ( 773 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 774 key2, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") 775 key3, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") 776 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 777 addr2 = crypto.PubkeyToAddress(key2.PublicKey) 778 addr3 = crypto.PubkeyToAddress(key3.PublicKey) 779 db = ethdb.NewMemDatabase() 780 gspec = &Genesis{ 781 Config: params.TestChainConfig, 782 GasLimit: 3141592, 783 Alloc: GenesisAlloc{ 784 addr1: {Balance: big.NewInt(1000000)}, 785 addr2: {Balance: big.NewInt(1000000)}, 786 addr3: {Balance: big.NewInt(1000000)}, 787 }, 788 } 789 genesis = gspec.MustCommit(db) 790 signer = types.NewEIP155Signer(gspec.Config.ChainID) 791 ) 792 793 // Create two transactions shared between the chains: 794 // - postponed: transaction included at a later block in the forked chain 795 // - swapped: transaction included at the same block number in the forked chain 796 postponed, _ := types.SignTx(types.NewTransaction(0, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) 797 swapped, _ := types.SignTx(types.NewTransaction(1, addr1, big.NewInt(1000), params.TxGas, nil, nil), signer, key1) 798 799 // Create two transactions that will be dropped by the forked chain: 800 // - pastDrop: transaction dropped retroactively from a past block 801 // - freshDrop: transaction dropped exactly at the block where the reorg is detected 802 var pastDrop, freshDrop *types.Transaction 803 804 // Create three transactions that will be added in the forked chain: 805 // - pastAdd: transaction added before the reorganization is detected 806 // - freshAdd: transaction added at the exact block the reorg is detected 807 // - futureAdd: transaction added after the reorg has already finished 808 var pastAdd, freshAdd, futureAdd *types.Transaction 809 810 chain, _ := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 3, func(i int, gen *BlockGen) { 811 switch i { 812 case 0: 813 pastDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) 814 815 gen.AddTx(pastDrop) // This transaction will be dropped in the fork from below the split point 816 gen.AddTx(postponed) // This transaction will be postponed till block #3 in the fork 817 818 case 2: 819 freshDrop, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr2), addr2, big.NewInt(1000), params.TxGas, nil, nil), signer, key2) 820 821 gen.AddTx(freshDrop) // This transaction will be dropped in the fork from exactly at the split point 822 gen.AddTx(swapped) // This transaction will be swapped out at the exact height 823 824 gen.OffsetTime(9) // Lower the block difficulty to simulate a weaker chain 825 } 826 }) 827 // Import the chain. This runs all block validation rules. 828 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 829 if i, err := blockchain.InsertChain(chain); err != nil { 830 t.Fatalf("failed to insert original chain[%d]: %v", i, err) 831 } 832 defer blockchain.Stop() 833 834 // overwrite the old chain 835 chain, _ = GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 5, func(i int, gen *BlockGen) { 836 switch i { 837 case 0: 838 pastAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 839 gen.AddTx(pastAdd) // This transaction needs to be injected during reorg 840 841 case 2: 842 gen.AddTx(postponed) // This transaction was postponed from block #1 in the original chain 843 gen.AddTx(swapped) // This transaction was swapped from the exact current spot in the original chain 844 845 freshAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 846 gen.AddTx(freshAdd) // This transaction will be added exactly at reorg time 847 848 case 3: 849 futureAdd, _ = types.SignTx(types.NewTransaction(gen.TxNonce(addr3), addr3, big.NewInt(1000), params.TxGas, nil, nil), signer, key3) 850 gen.AddTx(futureAdd) // This transaction will be added after a full reorg 851 } 852 }) 853 if _, err := blockchain.InsertChain(chain); err != nil { 854 t.Fatalf("failed to insert forked chain: %v", err) 855 } 856 857 // removed tx 858 for i, tx := range (types.Transactions{pastDrop, freshDrop}) { 859 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil { 860 t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn) 861 } 862 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt != nil { 863 t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt) 864 } 865 } 866 // added tx 867 for i, tx := range (types.Transactions{pastAdd, freshAdd, futureAdd}) { 868 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 869 t.Errorf("add %d: expected tx to be found", i) 870 } 871 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { 872 t.Errorf("add %d: expected receipt to be found", i) 873 } 874 } 875 // shared tx 876 for i, tx := range (types.Transactions{postponed, swapped}) { 877 if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil { 878 t.Errorf("share %d: expected tx to be found", i) 879 } 880 if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash()); rcpt == nil { 881 t.Errorf("share %d: expected receipt to be found", i) 882 } 883 } 884 } 885 886 func TestLogReorgs(t *testing.T) { 887 var ( 888 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 889 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 890 db = ethdb.NewMemDatabase() 891 // this code generates a log 892 code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 893 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} 894 genesis = gspec.MustCommit(db) 895 signer = types.NewEIP155Signer(gspec.Config.ChainID) 896 ) 897 898 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 899 defer blockchain.Stop() 900 901 rmLogsCh := make(chan RemovedLogsEvent) 902 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 903 chain, _ := GenerateChain(params.TestChainConfig, genesis, ubqhash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 904 if i == 1 { 905 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) 906 if err != nil { 907 t.Fatalf("failed to create tx: %v", err) 908 } 909 gen.AddTx(tx) 910 } 911 }) 912 if _, err := blockchain.InsertChain(chain); err != nil { 913 t.Fatalf("failed to insert chain: %v", err) 914 } 915 916 chain, _ = GenerateChain(params.TestChainConfig, genesis, ubqhash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) 917 if _, err := blockchain.InsertChain(chain); err != nil { 918 t.Fatalf("failed to insert forked chain: %v", err) 919 } 920 921 timeout := time.NewTimer(1 * time.Second) 922 select { 923 case ev := <-rmLogsCh: 924 if len(ev.Logs) == 0 { 925 t.Error("expected logs") 926 } 927 case <-timeout.C: 928 t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") 929 } 930 } 931 932 func TestLogRebirth(t *testing.T) { 933 var ( 934 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 935 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 936 db = ethdb.NewMemDatabase() 937 938 // this code generates a log 939 code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 940 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} 941 genesis = gspec.MustCommit(db) 942 signer = types.NewEIP155Signer(gspec.Config.ChainID) 943 newLogCh = make(chan bool) 944 ) 945 946 // listenNewLog checks whether the received logs number is equal with expected. 947 listenNewLog := func(sink chan []*types.Log, expect int) { 948 cnt := 0 949 for { 950 select { 951 case logs := <-sink: 952 cnt += len(logs) 953 case <-time.NewTimer(5 * time.Second).C: 954 // new logs timeout 955 newLogCh <- false 956 return 957 } 958 if cnt == expect { 959 break 960 } else if cnt > expect { 961 // redundant logs received 962 newLogCh <- false 963 return 964 } 965 } 966 select { 967 case <-sink: 968 // redundant logs received 969 newLogCh <- false 970 case <-time.NewTimer(100 * time.Millisecond).C: 971 newLogCh <- true 972 } 973 } 974 975 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 976 defer blockchain.Stop() 977 978 logsCh := make(chan []*types.Log) 979 blockchain.SubscribeLogsEvent(logsCh) 980 981 rmLogsCh := make(chan RemovedLogsEvent) 982 blockchain.SubscribeRemovedLogsEvent(rmLogsCh) 983 984 chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 985 if i == 1 { 986 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) 987 if err != nil { 988 t.Fatalf("failed to create tx: %v", err) 989 } 990 gen.AddTx(tx) 991 } 992 }) 993 994 // Spawn a goroutine to receive log events 995 go listenNewLog(logsCh, 1) 996 if _, err := blockchain.InsertChain(chain); err != nil { 997 t.Fatalf("failed to insert chain: %v", err) 998 } 999 if !<-newLogCh { 1000 t.Fatalf("failed to receive new log event") 1001 } 1002 1003 // Generate long reorg chain 1004 forkChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 1005 if i == 1 { 1006 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) 1007 if err != nil { 1008 t.Fatalf("failed to create tx: %v", err) 1009 } 1010 gen.AddTx(tx) 1011 // Higher block difficulty 1012 gen.OffsetTime(-9) 1013 } 1014 }) 1015 1016 // Spawn a goroutine to receive log events 1017 go listenNewLog(logsCh, 1) 1018 if _, err := blockchain.InsertChain(forkChain); err != nil { 1019 t.Fatalf("failed to insert forked chain: %v", err) 1020 } 1021 if !<-newLogCh { 1022 t.Fatalf("failed to receive new log event") 1023 } 1024 // Ensure removedLog events received 1025 select { 1026 case ev := <-rmLogsCh: 1027 if len(ev.Logs) == 0 { 1028 t.Error("expected logs") 1029 } 1030 case <-time.NewTimer(1 * time.Second).C: 1031 t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") 1032 } 1033 1034 newBlocks, _ := GenerateChain(params.TestChainConfig, chain[len(chain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {}) 1035 go listenNewLog(logsCh, 1) 1036 if _, err := blockchain.InsertChain(newBlocks); err != nil { 1037 t.Fatalf("failed to insert forked chain: %v", err) 1038 } 1039 // Ensure removedLog events received 1040 select { 1041 case ev := <-rmLogsCh: 1042 if len(ev.Logs) == 0 { 1043 t.Error("expected logs") 1044 } 1045 case <-time.NewTimer(1 * time.Second).C: 1046 t.Fatal("Timeout. There is no RemovedLogsEvent has been sent.") 1047 } 1048 // Rebirth logs should omit a newLogEvent 1049 if !<-newLogCh { 1050 t.Fatalf("failed to receive new log event") 1051 } 1052 } 1053 1054 func TestSideLogRebirth(t *testing.T) { 1055 var ( 1056 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1057 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1058 db = ethdb.NewMemDatabase() 1059 1060 // this code generates a log 1061 code = common.Hex2Bytes("60606040525b7f24ec1d3ff24c2f6ff210738839dbc339cd45a5294d85c79361016243157aae7b60405180905060405180910390a15b600a8060416000396000f360606040526008565b00") 1062 gspec = &Genesis{Config: params.TestChainConfig, Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}} 1063 genesis = gspec.MustCommit(db) 1064 signer = types.NewEIP155Signer(gspec.Config.ChainID) 1065 newLogCh = make(chan bool) 1066 ) 1067 1068 // listenNewLog checks whether the received logs number is equal with expected. 1069 listenNewLog := func(sink chan []*types.Log, expect int) { 1070 cnt := 0 1071 for { 1072 select { 1073 case logs := <-sink: 1074 cnt += len(logs) 1075 case <-time.NewTimer(5 * time.Second).C: 1076 // new logs timeout 1077 newLogCh <- false 1078 return 1079 } 1080 if cnt == expect { 1081 break 1082 } else if cnt > expect { 1083 // redundant logs received 1084 newLogCh <- false 1085 return 1086 } 1087 } 1088 select { 1089 case <-sink: 1090 // redundant logs received 1091 newLogCh <- false 1092 case <-time.NewTimer(100 * time.Millisecond).C: 1093 newLogCh <- true 1094 } 1095 } 1096 1097 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil) 1098 defer blockchain.Stop() 1099 1100 logsCh := make(chan []*types.Log) 1101 blockchain.SubscribeLogsEvent(logsCh) 1102 1103 chain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 1104 if i == 1 { 1105 // Higher block difficulty 1106 gen.OffsetTime(-9) 1107 } 1108 }) 1109 if _, err := blockchain.InsertChain(chain); err != nil { 1110 t.Fatalf("failed to insert forked chain: %v", err) 1111 } 1112 1113 // Generate side chain with lower difficulty 1114 sideChain, _ := GenerateChain(params.TestChainConfig, genesis, ethash.NewFaker(), db, 2, func(i int, gen *BlockGen) { 1115 if i == 1 { 1116 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), code), signer, key1) 1117 if err != nil { 1118 t.Fatalf("failed to create tx: %v", err) 1119 } 1120 gen.AddTx(tx) 1121 } 1122 }) 1123 if _, err := blockchain.InsertChain(sideChain); err != nil { 1124 t.Fatalf("failed to insert forked chain: %v", err) 1125 } 1126 1127 // Generate a new block based on side chain 1128 newBlocks, _ := GenerateChain(params.TestChainConfig, sideChain[len(sideChain)-1], ethash.NewFaker(), db, 1, func(i int, gen *BlockGen) {}) 1129 go listenNewLog(logsCh, 1) 1130 if _, err := blockchain.InsertChain(newBlocks); err != nil { 1131 t.Fatalf("failed to insert forked chain: %v", err) 1132 } 1133 // Rebirth logs should omit a newLogEvent 1134 if !<-newLogCh { 1135 t.Fatalf("failed to receive new log event") 1136 } 1137 } 1138 1139 func TestReorgSideEvent(t *testing.T) { 1140 var ( 1141 db = ethdb.NewMemDatabase() 1142 key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1143 addr1 = crypto.PubkeyToAddress(key1.PublicKey) 1144 gspec = &Genesis{ 1145 Config: params.TestChainConfig, 1146 Alloc: GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000)}}, 1147 } 1148 genesis = gspec.MustCommit(db) 1149 signer = types.NewEIP155Signer(gspec.Config.ChainID) 1150 ) 1151 1152 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 1153 defer blockchain.Stop() 1154 1155 chain, _ := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 3, func(i int, gen *BlockGen) {}) 1156 if _, err := blockchain.InsertChain(chain); err != nil { 1157 t.Fatalf("failed to insert chain: %v", err) 1158 } 1159 1160 replacementBlocks, _ := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 4, func(i int, gen *BlockGen) { 1161 tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, new(big.Int), nil), signer, key1) 1162 if i == 2 { 1163 gen.OffsetTime(-9) 1164 } 1165 if err != nil { 1166 t.Fatalf("failed to create tx: %v", err) 1167 } 1168 gen.AddTx(tx) 1169 }) 1170 chainSideCh := make(chan ChainSideEvent, 64) 1171 blockchain.SubscribeChainSideEvent(chainSideCh) 1172 if _, err := blockchain.InsertChain(replacementBlocks); err != nil { 1173 t.Fatalf("failed to insert chain: %v", err) 1174 } 1175 1176 // first two block of the secondary chain are for a brief moment considered 1177 // side chains because up to that point the first one is considered the 1178 // heavier chain. 1179 expectedSideHashes := map[common.Hash]bool{ 1180 replacementBlocks[0].Hash(): true, 1181 replacementBlocks[1].Hash(): true, 1182 chain[0].Hash(): true, 1183 chain[1].Hash(): true, 1184 chain[2].Hash(): true, 1185 } 1186 1187 i := 0 1188 1189 const timeoutDura = 10 * time.Second 1190 timeout := time.NewTimer(timeoutDura) 1191 done: 1192 for { 1193 select { 1194 case ev := <-chainSideCh: 1195 block := ev.Block 1196 if _, ok := expectedSideHashes[block.Hash()]; !ok { 1197 t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash()) 1198 } 1199 i++ 1200 1201 if i == len(expectedSideHashes) { 1202 timeout.Stop() 1203 1204 break done 1205 } 1206 timeout.Reset(timeoutDura) 1207 1208 case <-timeout.C: 1209 t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent") 1210 } 1211 } 1212 1213 // make sure no more events are fired 1214 select { 1215 case e := <-chainSideCh: 1216 t.Errorf("unexpected event fired: %v", e) 1217 case <-time.After(250 * time.Millisecond): 1218 } 1219 1220 } 1221 1222 // Tests if the canonical block can be fetched from the database during chain insertion. 1223 func TestCanonicalBlockRetrieval(t *testing.T) { 1224 _, blockchain, err := newCanonical(ubqhash.NewFaker(), 0, true) 1225 if err != nil { 1226 t.Fatalf("failed to create pristine chain: %v", err) 1227 } 1228 defer blockchain.Stop() 1229 1230 chain, _ := GenerateChain(blockchain.chainConfig, blockchain.genesisBlock, ubqhash.NewFaker(), blockchain.db, 10, func(i int, gen *BlockGen) {}) 1231 1232 var pend sync.WaitGroup 1233 pend.Add(len(chain)) 1234 1235 for i := range chain { 1236 go func(block *types.Block) { 1237 defer pend.Done() 1238 1239 // try to retrieve a block by its canonical hash and see if the block data can be retrieved. 1240 for { 1241 ch := rawdb.ReadCanonicalHash(blockchain.db, block.NumberU64()) 1242 if ch == (common.Hash{}) { 1243 continue // busy wait for canonical hash to be written 1244 } 1245 if ch != block.Hash() { 1246 t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex()) 1247 } 1248 fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64()) 1249 if fb == nil { 1250 t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex()) 1251 } 1252 if fb.Hash() != block.Hash() { 1253 t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex()) 1254 } 1255 return 1256 } 1257 }(chain[i]) 1258 1259 if _, err := blockchain.InsertChain(types.Blocks{chain[i]}); err != nil { 1260 t.Fatalf("failed to insert block %d: %v", i, err) 1261 } 1262 } 1263 pend.Wait() 1264 } 1265 1266 func TestEIP155Transition(t *testing.T) { 1267 // Configure and generate a sample block chain 1268 var ( 1269 db = ethdb.NewMemDatabase() 1270 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1271 address = crypto.PubkeyToAddress(key.PublicKey) 1272 funds = big.NewInt(1000000000) 1273 deleteAddr = common.Address{1} 1274 gspec = &Genesis{ 1275 Config: ¶ms.ChainConfig{ChainID: big.NewInt(1), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)}, 1276 Alloc: GenesisAlloc{address: {Balance: funds}, deleteAddr: {Balance: new(big.Int)}}, 1277 } 1278 genesis = gspec.MustCommit(db) 1279 ) 1280 1281 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 1282 defer blockchain.Stop() 1283 1284 blocks, _ := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 4, func(i int, block *BlockGen) { 1285 var ( 1286 tx *types.Transaction 1287 err error 1288 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1289 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1290 } 1291 ) 1292 switch i { 1293 case 0: 1294 tx, err = basicTx(types.HomesteadSigner{}) 1295 if err != nil { 1296 t.Fatal(err) 1297 } 1298 block.AddTx(tx) 1299 case 2: 1300 tx, err = basicTx(types.HomesteadSigner{}) 1301 if err != nil { 1302 t.Fatal(err) 1303 } 1304 block.AddTx(tx) 1305 1306 tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) 1307 if err != nil { 1308 t.Fatal(err) 1309 } 1310 block.AddTx(tx) 1311 case 3: 1312 tx, err = basicTx(types.HomesteadSigner{}) 1313 if err != nil { 1314 t.Fatal(err) 1315 } 1316 block.AddTx(tx) 1317 1318 tx, err = basicTx(types.NewEIP155Signer(gspec.Config.ChainID)) 1319 if err != nil { 1320 t.Fatal(err) 1321 } 1322 block.AddTx(tx) 1323 } 1324 }) 1325 1326 if _, err := blockchain.InsertChain(blocks); err != nil { 1327 t.Fatal(err) 1328 } 1329 block := blockchain.GetBlockByNumber(1) 1330 if block.Transactions()[0].Protected() { 1331 t.Error("Expected block[0].txs[0] to not be replay protected") 1332 } 1333 1334 block = blockchain.GetBlockByNumber(3) 1335 if block.Transactions()[0].Protected() { 1336 t.Error("Expected block[3].txs[0] to not be replay protected") 1337 } 1338 if !block.Transactions()[1].Protected() { 1339 t.Error("Expected block[3].txs[1] to be replay protected") 1340 } 1341 if _, err := blockchain.InsertChain(blocks[4:]); err != nil { 1342 t.Fatal(err) 1343 } 1344 1345 // generate an invalid chain id transaction 1346 config := ¶ms.ChainConfig{ChainID: big.NewInt(2), EIP155Block: big.NewInt(2), HomesteadBlock: new(big.Int)} 1347 blocks, _ = GenerateChain(config, blocks[len(blocks)-1], ubqhash.NewFaker(), db, 4, func(i int, block *BlockGen) { 1348 var ( 1349 tx *types.Transaction 1350 err error 1351 basicTx = func(signer types.Signer) (*types.Transaction, error) { 1352 return types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{}, new(big.Int), 21000, new(big.Int), nil), signer, key) 1353 } 1354 ) 1355 if i == 0 { 1356 tx, err = basicTx(types.NewEIP155Signer(big.NewInt(2))) 1357 if err != nil { 1358 t.Fatal(err) 1359 } 1360 block.AddTx(tx) 1361 } 1362 }) 1363 _, err := blockchain.InsertChain(blocks) 1364 if err != types.ErrInvalidChainId { 1365 t.Error("expected error:", types.ErrInvalidChainId) 1366 } 1367 } 1368 1369 func TestEIP161AccountRemoval(t *testing.T) { 1370 // Configure and generate a sample block chain 1371 var ( 1372 db = ethdb.NewMemDatabase() 1373 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1374 address = crypto.PubkeyToAddress(key.PublicKey) 1375 funds = big.NewInt(1000000000) 1376 theAddr = common.Address{1} 1377 gspec = &Genesis{ 1378 Config: ¶ms.ChainConfig{ 1379 ChainID: big.NewInt(1), 1380 HomesteadBlock: new(big.Int), 1381 EIP155Block: new(big.Int), 1382 EIP158Block: big.NewInt(2), 1383 }, 1384 Alloc: GenesisAlloc{address: {Balance: funds}}, 1385 } 1386 genesis = gspec.MustCommit(db) 1387 ) 1388 blockchain, _ := NewBlockChain(db, nil, gspec.Config, ubqhash.NewFaker(), vm.Config{}, nil) 1389 defer blockchain.Stop() 1390 1391 blocks, _ := GenerateChain(gspec.Config, genesis, ubqhash.NewFaker(), db, 3, func(i int, block *BlockGen) { 1392 var ( 1393 tx *types.Transaction 1394 err error 1395 signer = types.NewEIP155Signer(gspec.Config.ChainID) 1396 ) 1397 switch i { 1398 case 0: 1399 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1400 case 1: 1401 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1402 case 2: 1403 tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), theAddr, new(big.Int), 21000, new(big.Int), nil), signer, key) 1404 } 1405 if err != nil { 1406 t.Fatal(err) 1407 } 1408 block.AddTx(tx) 1409 }) 1410 // account must exist pre eip 161 1411 if _, err := blockchain.InsertChain(types.Blocks{blocks[0]}); err != nil { 1412 t.Fatal(err) 1413 } 1414 if st, _ := blockchain.State(); !st.Exist(theAddr) { 1415 t.Error("expected account to exist") 1416 } 1417 1418 // account needs to be deleted post eip 161 1419 if _, err := blockchain.InsertChain(types.Blocks{blocks[1]}); err != nil { 1420 t.Fatal(err) 1421 } 1422 if st, _ := blockchain.State(); st.Exist(theAddr) { 1423 t.Error("account should not exist") 1424 } 1425 1426 // account musn't be created post eip 161 1427 if _, err := blockchain.InsertChain(types.Blocks{blocks[2]}); err != nil { 1428 t.Fatal(err) 1429 } 1430 if st, _ := blockchain.State(); st.Exist(theAddr) { 1431 t.Error("account should not exist") 1432 } 1433 } 1434 1435 // This is a regression test (i.e. as weird as it is, don't delete it ever), which 1436 // tests that under weird reorg conditions the blockchain and its internal header- 1437 // chain return the same latest block/header. 1438 // 1439 // https://github.com/ubiq/go-ubiq/pull/15941 1440 func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { 1441 // Generate a canonical chain to act as the main dataset 1442 engine := ubqhash.NewFaker() 1443 1444 db := ethdb.NewMemDatabase() 1445 genesis := new(Genesis).MustCommit(db) 1446 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1447 1448 // Generate a bunch of fork blocks, each side forking from the canonical chain 1449 forks := make([]*types.Block, len(blocks)) 1450 for i := 0; i < len(forks); i++ { 1451 parent := genesis 1452 if i > 0 { 1453 parent = blocks[i-1] 1454 } 1455 fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1456 forks[i] = fork[0] 1457 } 1458 // Import the canonical and fork chain side by side, verifying the current block 1459 // and current header consistency 1460 diskdb := ethdb.NewMemDatabase() 1461 new(Genesis).MustCommit(diskdb) 1462 1463 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1464 if err != nil { 1465 t.Fatalf("failed to create tester chain: %v", err) 1466 } 1467 for i := 0; i < len(blocks); i++ { 1468 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1469 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1470 } 1471 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1472 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]) 1473 } 1474 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1475 t.Fatalf(" fork %d: failed to insert into chain: %v", i, err) 1476 } 1477 if chain.CurrentBlock().Hash() != chain.CurrentHeader().Hash() { 1478 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]) 1479 } 1480 } 1481 } 1482 1483 // Tests that importing small side forks doesn't leave junk in the trie database 1484 // cache (which would eventually cause memory issues). 1485 func TestTrieForkGC(t *testing.T) { 1486 // Generate a canonical chain to act as the main dataset 1487 engine := ubqhash.NewFaker() 1488 1489 db := ethdb.NewMemDatabase() 1490 genesis := new(Genesis).MustCommit(db) 1491 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1492 1493 // Generate a bunch of fork blocks, each side forking from the canonical chain 1494 forks := make([]*types.Block, len(blocks)) 1495 for i := 0; i < len(forks); i++ { 1496 parent := genesis 1497 if i > 0 { 1498 parent = blocks[i-1] 1499 } 1500 fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1501 forks[i] = fork[0] 1502 } 1503 // Import the canonical and fork chain side by side, forcing the trie cache to cache both 1504 diskdb := ethdb.NewMemDatabase() 1505 new(Genesis).MustCommit(diskdb) 1506 1507 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1508 if err != nil { 1509 t.Fatalf("failed to create tester chain: %v", err) 1510 } 1511 for i := 0; i < len(blocks); i++ { 1512 if _, err := chain.InsertChain(blocks[i : i+1]); err != nil { 1513 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1514 } 1515 if _, err := chain.InsertChain(forks[i : i+1]); err != nil { 1516 t.Fatalf("fork %d: failed to insert into chain: %v", i, err) 1517 } 1518 } 1519 // Dereference all the recent tries and ensure no past trie is left in 1520 for i := 0; i < triesInMemory; i++ { 1521 chain.stateCache.TrieDB().Dereference(blocks[len(blocks)-1-i].Root()) 1522 chain.stateCache.TrieDB().Dereference(forks[len(blocks)-1-i].Root()) 1523 } 1524 if len(chain.stateCache.TrieDB().Nodes()) > 0 { 1525 t.Fatalf("stale tries still alive after garbase collection") 1526 } 1527 } 1528 1529 // Tests that doing large reorgs works even if the state associated with the 1530 // forking point is not available any more. 1531 func TestLargeReorgTrieGC(t *testing.T) { 1532 // Generate the original common chain segment and the two competing forks 1533 engine := ubqhash.NewFaker() 1534 1535 db := ethdb.NewMemDatabase() 1536 genesis := new(Genesis).MustCommit(db) 1537 1538 shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) }) 1539 original, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{2}) }) 1540 competitor, _ := GenerateChain(params.TestChainConfig, shared[len(shared)-1], engine, db, 2*triesInMemory+1, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{3}) }) 1541 1542 // Import the shared chain and the original canonical one 1543 diskdb := ethdb.NewMemDatabase() 1544 new(Genesis).MustCommit(diskdb) 1545 1546 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1547 if err != nil { 1548 t.Fatalf("failed to create tester chain: %v", err) 1549 } 1550 if _, err := chain.InsertChain(shared); err != nil { 1551 t.Fatalf("failed to insert shared chain: %v", err) 1552 } 1553 if _, err := chain.InsertChain(original); err != nil { 1554 t.Fatalf("failed to insert original chain: %v", err) 1555 } 1556 // Ensure that the state associated with the forking point is pruned away 1557 if node, _ := chain.stateCache.TrieDB().Node(shared[len(shared)-1].Root()); node != nil { 1558 t.Fatalf("common-but-old ancestor still cache") 1559 } 1560 // Import the competitor chain without exceeding the canonical's TD and ensure 1561 // we have not processed any of the blocks (protection against malicious blocks) 1562 if _, err := chain.InsertChain(competitor[:len(competitor)-2]); err != nil { 1563 t.Fatalf("failed to insert competitor chain: %v", err) 1564 } 1565 for i, block := range competitor[:len(competitor)-2] { 1566 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1567 t.Fatalf("competitor %d: low TD chain became processed", i) 1568 } 1569 } 1570 // Import the head of the competitor chain, triggering the reorg and ensure we 1571 // successfully reprocess all the stashed away blocks. 1572 if _, err := chain.InsertChain(competitor[len(competitor)-2:]); err != nil { 1573 t.Fatalf("failed to finalize competitor chain: %v", err) 1574 } 1575 for i, block := range competitor[:len(competitor)-triesInMemory] { 1576 if node, _ := chain.stateCache.TrieDB().Node(block.Root()); node != nil { 1577 t.Fatalf("competitor %d: competing chain state missing", i) 1578 } 1579 } 1580 } 1581 1582 // Benchmarks large blocks with value transfers to non-existing accounts 1583 func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks int, recipientFn func(uint64) common.Address, dataFn func(uint64) []byte) { 1584 var ( 1585 signer = types.HomesteadSigner{} 1586 testBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 1587 testBankAddress = crypto.PubkeyToAddress(testBankKey.PublicKey) 1588 bankFunds = big.NewInt(100000000000000000) 1589 gspec = Genesis{ 1590 Config: params.TestChainConfig, 1591 Alloc: GenesisAlloc{ 1592 testBankAddress: {Balance: bankFunds}, 1593 common.HexToAddress("0xc0de"): { 1594 Code: []byte{0x60, 0x01, 0x50}, 1595 Balance: big.NewInt(0), 1596 }, // push 1, pop 1597 }, 1598 GasLimit: 100e6, // 100 M 1599 } 1600 ) 1601 // Generate the original common chain segment and the two competing forks 1602 engine := ubqhash.NewFaker() 1603 db := ethdb.NewMemDatabase() 1604 genesis := gspec.MustCommit(db) 1605 1606 blockGenerator := func(i int, block *BlockGen) { 1607 block.SetCoinbase(common.Address{1}) 1608 for txi := 0; txi < numTxs; txi++ { 1609 uniq := uint64(i*numTxs + txi) 1610 recipient := recipientFn(uniq) 1611 //recipient := common.BigToAddress(big.NewInt(0).SetUint64(1337 + uniq)) 1612 tx, err := types.SignTx(types.NewTransaction(uniq, recipient, big.NewInt(1), params.TxGas, big.NewInt(1), nil), signer, testBankKey) 1613 if err != nil { 1614 b.Error(err) 1615 } 1616 block.AddTx(tx) 1617 } 1618 } 1619 1620 shared, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, numBlocks, blockGenerator) 1621 b.StopTimer() 1622 b.ResetTimer() 1623 for i := 0; i < b.N; i++ { 1624 // Import the shared chain and the original canonical one 1625 diskdb := ethdb.NewMemDatabase() 1626 gspec.MustCommit(diskdb) 1627 1628 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1629 if err != nil { 1630 b.Fatalf("failed to create tester chain: %v", err) 1631 } 1632 b.StartTimer() 1633 if _, err := chain.InsertChain(shared); err != nil { 1634 b.Fatalf("failed to insert shared chain: %v", err) 1635 } 1636 b.StopTimer() 1637 if got := chain.CurrentBlock().Transactions().Len(); got != numTxs*numBlocks { 1638 b.Fatalf("Transactions were not included, expected %d, got %d", (numTxs * numBlocks), got) 1639 1640 } 1641 } 1642 } 1643 func BenchmarkBlockChain_1x1000ValueTransferToNonexisting(b *testing.B) { 1644 var ( 1645 numTxs = 1000 1646 numBlocks = 1 1647 ) 1648 1649 recipientFn := func(nonce uint64) common.Address { 1650 return common.BigToAddress(big.NewInt(0).SetUint64(1337 + nonce)) 1651 } 1652 dataFn := func(nonce uint64) []byte { 1653 return nil 1654 } 1655 1656 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1657 } 1658 func BenchmarkBlockChain_1x1000ValueTransferToExisting(b *testing.B) { 1659 var ( 1660 numTxs = 1000 1661 numBlocks = 1 1662 ) 1663 b.StopTimer() 1664 b.ResetTimer() 1665 1666 recipientFn := func(nonce uint64) common.Address { 1667 return common.BigToAddress(big.NewInt(0).SetUint64(1337)) 1668 } 1669 dataFn := func(nonce uint64) []byte { 1670 return nil 1671 } 1672 1673 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1674 } 1675 func BenchmarkBlockChain_1x1000Executions(b *testing.B) { 1676 var ( 1677 numTxs = 1000 1678 numBlocks = 1 1679 ) 1680 b.StopTimer() 1681 b.ResetTimer() 1682 1683 recipientFn := func(nonce uint64) common.Address { 1684 return common.BigToAddress(big.NewInt(0).SetUint64(0xc0de)) 1685 } 1686 dataFn := func(nonce uint64) []byte { 1687 return nil 1688 } 1689 1690 benchmarkLargeNumberOfValueToNonexisting(b, numTxs, numBlocks, recipientFn, dataFn) 1691 } 1692 1693 // Tests that importing a very large side fork, which is larger than the canon chain, 1694 // but where the difficulty per block is kept low: this means that it will not 1695 // overtake the 'canon' chain until after it's passed canon by about 200 blocks. 1696 // 1697 // Details at: 1698 // - https://github.com/ubiq/go-ubiq/issues/18977 1699 // - https://github.com/ubiq/go-ubiq/pull/18988 1700 func TestLowDiffLongChain(t *testing.T) { 1701 // Generate a canonical chain to act as the main dataset 1702 engine := ubqhash.NewFaker() 1703 db := ethdb.NewMemDatabase() 1704 genesis := new(Genesis).MustCommit(db) 1705 1706 // We must use a pretty long chain to ensure that the fork doesn't overtake us 1707 // until after at least 128 blocks post tip 1708 blocks, _ := GenerateChain(params.TestChainConfig, genesis, engine, db, 6*triesInMemory, func(i int, b *BlockGen) { 1709 b.SetCoinbase(common.Address{1}) 1710 b.OffsetTime(-9) 1711 }) 1712 1713 // Import the canonical chain 1714 diskdb := ethdb.NewMemDatabase() 1715 new(Genesis).MustCommit(diskdb) 1716 1717 chain, err := NewBlockChain(diskdb, nil, params.TestChainConfig, engine, vm.Config{}, nil) 1718 if err != nil { 1719 t.Fatalf("failed to create tester chain: %v", err) 1720 } 1721 if n, err := chain.InsertChain(blocks); err != nil { 1722 t.Fatalf("block %d: failed to insert into chain: %v", n, err) 1723 } 1724 // Generate fork chain, starting from an early block 1725 parent := blocks[10] 1726 fork, _ := GenerateChain(params.TestChainConfig, parent, engine, db, 8*triesInMemory, func(i int, b *BlockGen) { 1727 b.SetCoinbase(common.Address{2}) 1728 }) 1729 1730 // And now import the fork 1731 if i, err := chain.InsertChain(fork); err != nil { 1732 t.Fatalf("block %d: failed to insert into chain: %v", i, err) 1733 } 1734 head := chain.CurrentBlock() 1735 if got := fork[len(fork)-1].Hash(); got != head.Hash() { 1736 t.Fatalf("head wrong, expected %x got %x", head.Hash(), got) 1737 } 1738 // Sanity check that all the canonical numbers are present 1739 header := chain.CurrentHeader() 1740 for number := head.NumberU64(); number > 0; number-- { 1741 if hash := chain.GetHeaderByNumber(number).Hash(); hash != header.Hash() { 1742 t.Fatalf("header %d: canonical hash mismatch: have %x, want %x", number, hash, header.Hash()) 1743 } 1744 header = chain.GetHeader(header.ParentHash, number-1) 1745 } 1746 }