github.com/juliankolbe/go-ethereum@v1.9.992/eth/downloader/downloader_test.go (about) 1 // Copyright 2015 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 downloader 18 19 import ( 20 "errors" 21 "fmt" 22 "math/big" 23 "strings" 24 "sync" 25 "sync/atomic" 26 "testing" 27 "time" 28 29 "github.com/juliankolbe/go-ethereum" 30 "github.com/juliankolbe/go-ethereum/common" 31 "github.com/juliankolbe/go-ethereum/core/rawdb" 32 "github.com/juliankolbe/go-ethereum/core/types" 33 "github.com/juliankolbe/go-ethereum/ethdb" 34 "github.com/juliankolbe/go-ethereum/event" 35 "github.com/juliankolbe/go-ethereum/trie" 36 ) 37 38 // Reduce some of the parameters to make the tester faster. 39 func init() { 40 fullMaxForkAncestry = 10000 41 lightMaxForkAncestry = 10000 42 blockCacheMaxItems = 1024 43 fsHeaderContCheck = 500 * time.Millisecond 44 } 45 46 // downloadTester is a test simulator for mocking out local block chain. 47 type downloadTester struct { 48 downloader *Downloader 49 50 genesis *types.Block // Genesis blocks used by the tester and peers 51 stateDb ethdb.Database // Database used by the tester for syncing from peers 52 peerDb ethdb.Database // Database of the peers containing all data 53 peers map[string]*downloadTesterPeer 54 55 ownHashes []common.Hash // Hash chain belonging to the tester 56 ownHeaders map[common.Hash]*types.Header // Headers belonging to the tester 57 ownBlocks map[common.Hash]*types.Block // Blocks belonging to the tester 58 ownReceipts map[common.Hash]types.Receipts // Receipts belonging to the tester 59 ownChainTd map[common.Hash]*big.Int // Total difficulties of the blocks in the local chain 60 61 ancientHeaders map[common.Hash]*types.Header // Ancient headers belonging to the tester 62 ancientBlocks map[common.Hash]*types.Block // Ancient blocks belonging to the tester 63 ancientReceipts map[common.Hash]types.Receipts // Ancient receipts belonging to the tester 64 ancientChainTd map[common.Hash]*big.Int // Ancient total difficulties of the blocks in the local chain 65 66 lock sync.RWMutex 67 } 68 69 // newTester creates a new downloader test mocker. 70 func newTester() *downloadTester { 71 tester := &downloadTester{ 72 genesis: testGenesis, 73 peerDb: testDB, 74 peers: make(map[string]*downloadTesterPeer), 75 ownHashes: []common.Hash{testGenesis.Hash()}, 76 ownHeaders: map[common.Hash]*types.Header{testGenesis.Hash(): testGenesis.Header()}, 77 ownBlocks: map[common.Hash]*types.Block{testGenesis.Hash(): testGenesis}, 78 ownReceipts: map[common.Hash]types.Receipts{testGenesis.Hash(): nil}, 79 ownChainTd: map[common.Hash]*big.Int{testGenesis.Hash(): testGenesis.Difficulty()}, 80 81 // Initialize ancient store with test genesis block 82 ancientHeaders: map[common.Hash]*types.Header{testGenesis.Hash(): testGenesis.Header()}, 83 ancientBlocks: map[common.Hash]*types.Block{testGenesis.Hash(): testGenesis}, 84 ancientReceipts: map[common.Hash]types.Receipts{testGenesis.Hash(): nil}, 85 ancientChainTd: map[common.Hash]*big.Int{testGenesis.Hash(): testGenesis.Difficulty()}, 86 } 87 tester.stateDb = rawdb.NewMemoryDatabase() 88 tester.stateDb.Put(testGenesis.Root().Bytes(), []byte{0x00}) 89 90 tester.downloader = New(0, tester.stateDb, trie.NewSyncBloom(1, tester.stateDb), new(event.TypeMux), tester, nil, tester.dropPeer) 91 return tester 92 } 93 94 // terminate aborts any operations on the embedded downloader and releases all 95 // held resources. 96 func (dl *downloadTester) terminate() { 97 dl.downloader.Terminate() 98 } 99 100 // sync starts synchronizing with a remote peer, blocking until it completes. 101 func (dl *downloadTester) sync(id string, td *big.Int, mode SyncMode) error { 102 dl.lock.RLock() 103 hash := dl.peers[id].chain.headBlock().Hash() 104 // If no particular TD was requested, load from the peer's blockchain 105 if td == nil { 106 td = dl.peers[id].chain.td(hash) 107 } 108 dl.lock.RUnlock() 109 110 // Synchronise with the chosen peer and ensure proper cleanup afterwards 111 err := dl.downloader.synchronise(id, hash, td, mode) 112 select { 113 case <-dl.downloader.cancelCh: 114 // Ok, downloader fully cancelled after sync cycle 115 default: 116 // Downloader is still accepting packets, can block a peer up 117 panic("downloader active post sync cycle") // panic will be caught by tester 118 } 119 return err 120 } 121 122 // HasHeader checks if a header is present in the testers canonical chain. 123 func (dl *downloadTester) HasHeader(hash common.Hash, number uint64) bool { 124 return dl.GetHeaderByHash(hash) != nil 125 } 126 127 // HasBlock checks if a block is present in the testers canonical chain. 128 func (dl *downloadTester) HasBlock(hash common.Hash, number uint64) bool { 129 return dl.GetBlockByHash(hash) != nil 130 } 131 132 // HasFastBlock checks if a block is present in the testers canonical chain. 133 func (dl *downloadTester) HasFastBlock(hash common.Hash, number uint64) bool { 134 dl.lock.RLock() 135 defer dl.lock.RUnlock() 136 137 if _, ok := dl.ancientReceipts[hash]; ok { 138 return true 139 } 140 _, ok := dl.ownReceipts[hash] 141 return ok 142 } 143 144 // GetHeader retrieves a header from the testers canonical chain. 145 func (dl *downloadTester) GetHeaderByHash(hash common.Hash) *types.Header { 146 dl.lock.RLock() 147 defer dl.lock.RUnlock() 148 return dl.getHeaderByHash(hash) 149 } 150 151 // getHeaderByHash returns the header if found either within ancients or own blocks) 152 // This method assumes that the caller holds at least the read-lock (dl.lock) 153 func (dl *downloadTester) getHeaderByHash(hash common.Hash) *types.Header { 154 header := dl.ancientHeaders[hash] 155 if header != nil { 156 return header 157 } 158 return dl.ownHeaders[hash] 159 } 160 161 // GetBlock retrieves a block from the testers canonical chain. 162 func (dl *downloadTester) GetBlockByHash(hash common.Hash) *types.Block { 163 dl.lock.RLock() 164 defer dl.lock.RUnlock() 165 166 block := dl.ancientBlocks[hash] 167 if block != nil { 168 return block 169 } 170 return dl.ownBlocks[hash] 171 } 172 173 // CurrentHeader retrieves the current head header from the canonical chain. 174 func (dl *downloadTester) CurrentHeader() *types.Header { 175 dl.lock.RLock() 176 defer dl.lock.RUnlock() 177 178 for i := len(dl.ownHashes) - 1; i >= 0; i-- { 179 if header := dl.ancientHeaders[dl.ownHashes[i]]; header != nil { 180 return header 181 } 182 if header := dl.ownHeaders[dl.ownHashes[i]]; header != nil { 183 return header 184 } 185 } 186 return dl.genesis.Header() 187 } 188 189 // CurrentBlock retrieves the current head block from the canonical chain. 190 func (dl *downloadTester) CurrentBlock() *types.Block { 191 dl.lock.RLock() 192 defer dl.lock.RUnlock() 193 194 for i := len(dl.ownHashes) - 1; i >= 0; i-- { 195 if block := dl.ancientBlocks[dl.ownHashes[i]]; block != nil { 196 if _, err := dl.stateDb.Get(block.Root().Bytes()); err == nil { 197 return block 198 } 199 return block 200 } 201 if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil { 202 if _, err := dl.stateDb.Get(block.Root().Bytes()); err == nil { 203 return block 204 } 205 } 206 } 207 return dl.genesis 208 } 209 210 // CurrentFastBlock retrieves the current head fast-sync block from the canonical chain. 211 func (dl *downloadTester) CurrentFastBlock() *types.Block { 212 dl.lock.RLock() 213 defer dl.lock.RUnlock() 214 215 for i := len(dl.ownHashes) - 1; i >= 0; i-- { 216 if block := dl.ancientBlocks[dl.ownHashes[i]]; block != nil { 217 return block 218 } 219 if block := dl.ownBlocks[dl.ownHashes[i]]; block != nil { 220 return block 221 } 222 } 223 return dl.genesis 224 } 225 226 // FastSyncCommitHead manually sets the head block to a given hash. 227 func (dl *downloadTester) FastSyncCommitHead(hash common.Hash) error { 228 // For now only check that the state trie is correct 229 if block := dl.GetBlockByHash(hash); block != nil { 230 _, err := trie.NewSecure(block.Root(), trie.NewDatabase(dl.stateDb)) 231 return err 232 } 233 return fmt.Errorf("non existent block: %x", hash[:4]) 234 } 235 236 // GetTd retrieves the block's total difficulty from the canonical chain. 237 func (dl *downloadTester) GetTd(hash common.Hash, number uint64) *big.Int { 238 dl.lock.RLock() 239 defer dl.lock.RUnlock() 240 241 return dl.getTd(hash) 242 } 243 244 // getTd retrieves the block's total difficulty if found either within 245 // ancients or own blocks). 246 // This method assumes that the caller holds at least the read-lock (dl.lock) 247 func (dl *downloadTester) getTd(hash common.Hash) *big.Int { 248 if td := dl.ancientChainTd[hash]; td != nil { 249 return td 250 } 251 return dl.ownChainTd[hash] 252 } 253 254 // InsertHeaderChain injects a new batch of headers into the simulated chain. 255 func (dl *downloadTester) InsertHeaderChain(headers []*types.Header, checkFreq int) (i int, err error) { 256 dl.lock.Lock() 257 defer dl.lock.Unlock() 258 // Do a quick check, as the blockchain.InsertHeaderChain doesn't insert anything in case of errors 259 if dl.getHeaderByHash(headers[0].ParentHash) == nil { 260 return 0, fmt.Errorf("InsertHeaderChain: unknown parent at first position, parent of number %d", headers[0].Number) 261 } 262 var hashes []common.Hash 263 for i := 1; i < len(headers); i++ { 264 hash := headers[i-1].Hash() 265 if headers[i].ParentHash != headers[i-1].Hash() { 266 return i, fmt.Errorf("non-contiguous import at position %d", i) 267 } 268 hashes = append(hashes, hash) 269 } 270 hashes = append(hashes, headers[len(headers)-1].Hash()) 271 // Do a full insert if pre-checks passed 272 for i, header := range headers { 273 hash := hashes[i] 274 if dl.getHeaderByHash(hash) != nil { 275 continue 276 } 277 if dl.getHeaderByHash(header.ParentHash) == nil { 278 // This _should_ be impossible, due to precheck and induction 279 return i, fmt.Errorf("InsertHeaderChain: unknown parent at position %d", i) 280 } 281 dl.ownHashes = append(dl.ownHashes, hash) 282 dl.ownHeaders[hash] = header 283 284 td := dl.getTd(header.ParentHash) 285 dl.ownChainTd[hash] = new(big.Int).Add(td, header.Difficulty) 286 } 287 return len(headers), nil 288 } 289 290 // InsertChain injects a new batch of blocks into the simulated chain. 291 func (dl *downloadTester) InsertChain(blocks types.Blocks) (i int, err error) { 292 dl.lock.Lock() 293 defer dl.lock.Unlock() 294 for i, block := range blocks { 295 if parent, ok := dl.ownBlocks[block.ParentHash()]; !ok { 296 return i, fmt.Errorf("InsertChain: unknown parent at position %d / %d", i, len(blocks)) 297 } else if _, err := dl.stateDb.Get(parent.Root().Bytes()); err != nil { 298 return i, fmt.Errorf("InsertChain: unknown parent state %x: %v", parent.Root(), err) 299 } 300 if hdr := dl.getHeaderByHash(block.Hash()); hdr == nil { 301 dl.ownHashes = append(dl.ownHashes, block.Hash()) 302 dl.ownHeaders[block.Hash()] = block.Header() 303 } 304 dl.ownBlocks[block.Hash()] = block 305 dl.ownReceipts[block.Hash()] = make(types.Receipts, 0) 306 dl.stateDb.Put(block.Root().Bytes(), []byte{0x00}) 307 td := dl.getTd(block.ParentHash()) 308 dl.ownChainTd[block.Hash()] = new(big.Int).Add(td, block.Difficulty()) 309 } 310 return len(blocks), nil 311 } 312 313 // InsertReceiptChain injects a new batch of receipts into the simulated chain. 314 func (dl *downloadTester) InsertReceiptChain(blocks types.Blocks, receipts []types.Receipts, ancientLimit uint64) (i int, err error) { 315 dl.lock.Lock() 316 defer dl.lock.Unlock() 317 318 for i := 0; i < len(blocks) && i < len(receipts); i++ { 319 if _, ok := dl.ownHeaders[blocks[i].Hash()]; !ok { 320 return i, errors.New("unknown owner") 321 } 322 if _, ok := dl.ancientBlocks[blocks[i].ParentHash()]; !ok { 323 if _, ok := dl.ownBlocks[blocks[i].ParentHash()]; !ok { 324 return i, errors.New("InsertReceiptChain: unknown parent") 325 } 326 } 327 if blocks[i].NumberU64() <= ancientLimit { 328 dl.ancientBlocks[blocks[i].Hash()] = blocks[i] 329 dl.ancientReceipts[blocks[i].Hash()] = receipts[i] 330 331 // Migrate from active db to ancient db 332 dl.ancientHeaders[blocks[i].Hash()] = blocks[i].Header() 333 dl.ancientChainTd[blocks[i].Hash()] = new(big.Int).Add(dl.ancientChainTd[blocks[i].ParentHash()], blocks[i].Difficulty()) 334 delete(dl.ownHeaders, blocks[i].Hash()) 335 delete(dl.ownChainTd, blocks[i].Hash()) 336 } else { 337 dl.ownBlocks[blocks[i].Hash()] = blocks[i] 338 dl.ownReceipts[blocks[i].Hash()] = receipts[i] 339 } 340 } 341 return len(blocks), nil 342 } 343 344 // SetHead rewinds the local chain to a new head. 345 func (dl *downloadTester) SetHead(head uint64) error { 346 dl.lock.Lock() 347 defer dl.lock.Unlock() 348 349 // Find the hash of the head to reset to 350 var hash common.Hash 351 for h, header := range dl.ownHeaders { 352 if header.Number.Uint64() == head { 353 hash = h 354 } 355 } 356 for h, header := range dl.ancientHeaders { 357 if header.Number.Uint64() == head { 358 hash = h 359 } 360 } 361 if hash == (common.Hash{}) { 362 return fmt.Errorf("unknown head to set: %d", head) 363 } 364 // Find the offset in the header chain 365 var offset int 366 for o, h := range dl.ownHashes { 367 if h == hash { 368 offset = o 369 break 370 } 371 } 372 // Remove all the hashes and associated data afterwards 373 for i := offset + 1; i < len(dl.ownHashes); i++ { 374 delete(dl.ownChainTd, dl.ownHashes[i]) 375 delete(dl.ownHeaders, dl.ownHashes[i]) 376 delete(dl.ownReceipts, dl.ownHashes[i]) 377 delete(dl.ownBlocks, dl.ownHashes[i]) 378 379 delete(dl.ancientChainTd, dl.ownHashes[i]) 380 delete(dl.ancientHeaders, dl.ownHashes[i]) 381 delete(dl.ancientReceipts, dl.ownHashes[i]) 382 delete(dl.ancientBlocks, dl.ownHashes[i]) 383 } 384 dl.ownHashes = dl.ownHashes[:offset+1] 385 return nil 386 } 387 388 // Rollback removes some recently added elements from the chain. 389 func (dl *downloadTester) Rollback(hashes []common.Hash) { 390 } 391 392 // newPeer registers a new block download source into the downloader. 393 func (dl *downloadTester) newPeer(id string, version uint, chain *testChain) error { 394 dl.lock.Lock() 395 defer dl.lock.Unlock() 396 397 peer := &downloadTesterPeer{dl: dl, id: id, chain: chain} 398 dl.peers[id] = peer 399 return dl.downloader.RegisterPeer(id, version, peer) 400 } 401 402 // dropPeer simulates a hard peer removal from the connection pool. 403 func (dl *downloadTester) dropPeer(id string) { 404 dl.lock.Lock() 405 defer dl.lock.Unlock() 406 407 delete(dl.peers, id) 408 dl.downloader.UnregisterPeer(id) 409 } 410 411 type downloadTesterPeer struct { 412 dl *downloadTester 413 id string 414 chain *testChain 415 missingStates map[common.Hash]bool // State entries that fast sync should not return 416 } 417 418 // Head constructs a function to retrieve a peer's current head hash 419 // and total difficulty. 420 func (dlp *downloadTesterPeer) Head() (common.Hash, *big.Int) { 421 b := dlp.chain.headBlock() 422 return b.Hash(), dlp.chain.td(b.Hash()) 423 } 424 425 // RequestHeadersByHash constructs a GetBlockHeaders function based on a hashed 426 // origin; associated with a particular peer in the download tester. The returned 427 // function can be used to retrieve batches of headers from the particular peer. 428 func (dlp *downloadTesterPeer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error { 429 result := dlp.chain.headersByHash(origin, amount, skip, reverse) 430 go dlp.dl.downloader.DeliverHeaders(dlp.id, result) 431 return nil 432 } 433 434 // RequestHeadersByNumber constructs a GetBlockHeaders function based on a numbered 435 // origin; associated with a particular peer in the download tester. The returned 436 // function can be used to retrieve batches of headers from the particular peer. 437 func (dlp *downloadTesterPeer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error { 438 result := dlp.chain.headersByNumber(origin, amount, skip, reverse) 439 go dlp.dl.downloader.DeliverHeaders(dlp.id, result) 440 return nil 441 } 442 443 // RequestBodies constructs a getBlockBodies method associated with a particular 444 // peer in the download tester. The returned function can be used to retrieve 445 // batches of block bodies from the particularly requested peer. 446 func (dlp *downloadTesterPeer) RequestBodies(hashes []common.Hash) error { 447 txs, uncles := dlp.chain.bodies(hashes) 448 go dlp.dl.downloader.DeliverBodies(dlp.id, txs, uncles) 449 return nil 450 } 451 452 // RequestReceipts constructs a getReceipts method associated with a particular 453 // peer in the download tester. The returned function can be used to retrieve 454 // batches of block receipts from the particularly requested peer. 455 func (dlp *downloadTesterPeer) RequestReceipts(hashes []common.Hash) error { 456 receipts := dlp.chain.receipts(hashes) 457 go dlp.dl.downloader.DeliverReceipts(dlp.id, receipts) 458 return nil 459 } 460 461 // RequestNodeData constructs a getNodeData method associated with a particular 462 // peer in the download tester. The returned function can be used to retrieve 463 // batches of node state data from the particularly requested peer. 464 func (dlp *downloadTesterPeer) RequestNodeData(hashes []common.Hash) error { 465 dlp.dl.lock.RLock() 466 defer dlp.dl.lock.RUnlock() 467 468 results := make([][]byte, 0, len(hashes)) 469 for _, hash := range hashes { 470 if data, err := dlp.dl.peerDb.Get(hash.Bytes()); err == nil { 471 if !dlp.missingStates[hash] { 472 results = append(results, data) 473 } 474 } 475 } 476 go dlp.dl.downloader.DeliverNodeData(dlp.id, results) 477 return nil 478 } 479 480 // assertOwnChain checks if the local chain contains the correct number of items 481 // of the various chain components. 482 func assertOwnChain(t *testing.T, tester *downloadTester, length int) { 483 // Mark this method as a helper to report errors at callsite, not in here 484 t.Helper() 485 486 assertOwnForkedChain(t, tester, 1, []int{length}) 487 } 488 489 // assertOwnForkedChain checks if the local forked chain contains the correct 490 // number of items of the various chain components. 491 func assertOwnForkedChain(t *testing.T, tester *downloadTester, common int, lengths []int) { 492 // Mark this method as a helper to report errors at callsite, not in here 493 t.Helper() 494 495 // Initialize the counters for the first fork 496 headers, blocks, receipts := lengths[0], lengths[0], lengths[0] 497 498 // Update the counters for each subsequent fork 499 for _, length := range lengths[1:] { 500 headers += length - common 501 blocks += length - common 502 receipts += length - common 503 } 504 if tester.downloader.getMode() == LightSync { 505 blocks, receipts = 1, 1 506 } 507 if hs := len(tester.ownHeaders) + len(tester.ancientHeaders) - 1; hs != headers { 508 t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, headers) 509 } 510 if bs := len(tester.ownBlocks) + len(tester.ancientBlocks) - 1; bs != blocks { 511 t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, blocks) 512 } 513 if rs := len(tester.ownReceipts) + len(tester.ancientReceipts) - 1; rs != receipts { 514 t.Fatalf("synchronised receipts mismatch: have %v, want %v", rs, receipts) 515 } 516 } 517 518 func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonSync(t, 64, FullSync) } 519 func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonSync(t, 64, FastSync) } 520 521 func TestCanonicalSynchronisation65Full(t *testing.T) { testCanonSync(t, 65, FullSync) } 522 func TestCanonicalSynchronisation65Fast(t *testing.T) { testCanonSync(t, 65, FastSync) } 523 func TestCanonicalSynchronisation65Light(t *testing.T) { testCanonSync(t, 65, LightSync) } 524 525 func TestCanonicalSynchronisation66Full(t *testing.T) { testCanonSync(t, 66, FullSync) } 526 func TestCanonicalSynchronisation66Fast(t *testing.T) { testCanonSync(t, 66, FastSync) } 527 func TestCanonicalSynchronisation66Light(t *testing.T) { testCanonSync(t, 66, LightSync) } 528 529 func testCanonSync(t *testing.T, protocol uint, mode SyncMode) { 530 t.Parallel() 531 532 tester := newTester() 533 defer tester.terminate() 534 535 // Create a small enough block chain to download 536 chain := testChainBase.shorten(blockCacheMaxItems - 15) 537 tester.newPeer("peer", protocol, chain) 538 539 // Synchronise with the peer and make sure all relevant data was retrieved 540 if err := tester.sync("peer", nil, mode); err != nil { 541 t.Fatalf("failed to synchronise blocks: %v", err) 542 } 543 assertOwnChain(t, tester, chain.len()) 544 } 545 546 // Tests that if a large batch of blocks are being downloaded, it is throttled 547 // until the cached blocks are retrieved. 548 func TestThrottling64Full(t *testing.T) { testThrottling(t, 64, FullSync) } 549 func TestThrottling64Fast(t *testing.T) { testThrottling(t, 64, FastSync) } 550 551 func TestThrottling65Full(t *testing.T) { testThrottling(t, 65, FullSync) } 552 func TestThrottling65Fast(t *testing.T) { testThrottling(t, 65, FastSync) } 553 554 func TestThrottling66Full(t *testing.T) { testThrottling(t, 66, FullSync) } 555 func TestThrottling66Fast(t *testing.T) { testThrottling(t, 66, FastSync) } 556 557 func testThrottling(t *testing.T, protocol uint, mode SyncMode) { 558 t.Parallel() 559 tester := newTester() 560 561 // Create a long block chain to download and the tester 562 targetBlocks := testChainBase.len() - 1 563 tester.newPeer("peer", protocol, testChainBase) 564 565 // Wrap the importer to allow stepping 566 blocked, proceed := uint32(0), make(chan struct{}) 567 tester.downloader.chainInsertHook = func(results []*fetchResult) { 568 atomic.StoreUint32(&blocked, uint32(len(results))) 569 <-proceed 570 } 571 // Start a synchronisation concurrently 572 errc := make(chan error, 1) 573 go func() { 574 errc <- tester.sync("peer", nil, mode) 575 }() 576 // Iteratively take some blocks, always checking the retrieval count 577 for { 578 // Check the retrieval count synchronously (! reason for this ugly block) 579 tester.lock.RLock() 580 retrieved := len(tester.ownBlocks) 581 tester.lock.RUnlock() 582 if retrieved >= targetBlocks+1 { 583 break 584 } 585 // Wait a bit for sync to throttle itself 586 var cached, frozen int 587 for start := time.Now(); time.Since(start) < 3*time.Second; { 588 time.Sleep(25 * time.Millisecond) 589 590 tester.lock.Lock() 591 tester.downloader.queue.lock.Lock() 592 tester.downloader.queue.resultCache.lock.Lock() 593 { 594 cached = tester.downloader.queue.resultCache.countCompleted() 595 frozen = int(atomic.LoadUint32(&blocked)) 596 retrieved = len(tester.ownBlocks) 597 } 598 tester.downloader.queue.resultCache.lock.Unlock() 599 tester.downloader.queue.lock.Unlock() 600 tester.lock.Unlock() 601 602 if cached == blockCacheMaxItems || 603 cached == blockCacheMaxItems-reorgProtHeaderDelay || 604 retrieved+cached+frozen == targetBlocks+1 || 605 retrieved+cached+frozen == targetBlocks+1-reorgProtHeaderDelay { 606 break 607 } 608 } 609 // Make sure we filled up the cache, then exhaust it 610 time.Sleep(25 * time.Millisecond) // give it a chance to screw up 611 tester.lock.RLock() 612 retrieved = len(tester.ownBlocks) 613 tester.lock.RUnlock() 614 if cached != blockCacheMaxItems && cached != blockCacheMaxItems-reorgProtHeaderDelay && retrieved+cached+frozen != targetBlocks+1 && retrieved+cached+frozen != targetBlocks+1-reorgProtHeaderDelay { 615 t.Fatalf("block count mismatch: have %v, want %v (owned %v, blocked %v, target %v)", cached, blockCacheMaxItems, retrieved, frozen, targetBlocks+1) 616 } 617 618 // Permit the blocked blocks to import 619 if atomic.LoadUint32(&blocked) > 0 { 620 atomic.StoreUint32(&blocked, uint32(0)) 621 proceed <- struct{}{} 622 } 623 } 624 // Check that we haven't pulled more blocks than available 625 assertOwnChain(t, tester, targetBlocks+1) 626 if err := <-errc; err != nil { 627 t.Fatalf("block synchronization failed: %v", err) 628 } 629 tester.terminate() 630 631 } 632 633 // Tests that simple synchronization against a forked chain works correctly. In 634 // this test common ancestor lookup should *not* be short circuited, and a full 635 // binary search should be executed. 636 func TestForkedSync64Full(t *testing.T) { testForkedSync(t, 64, FullSync) } 637 func TestForkedSync64Fast(t *testing.T) { testForkedSync(t, 64, FastSync) } 638 639 func TestForkedSync65Full(t *testing.T) { testForkedSync(t, 65, FullSync) } 640 func TestForkedSync65Fast(t *testing.T) { testForkedSync(t, 65, FastSync) } 641 func TestForkedSync65Light(t *testing.T) { testForkedSync(t, 65, LightSync) } 642 643 func TestForkedSync66Full(t *testing.T) { testForkedSync(t, 66, FullSync) } 644 func TestForkedSync66Fast(t *testing.T) { testForkedSync(t, 66, FastSync) } 645 func TestForkedSync66Light(t *testing.T) { testForkedSync(t, 66, LightSync) } 646 647 func testForkedSync(t *testing.T, protocol uint, mode SyncMode) { 648 t.Parallel() 649 650 tester := newTester() 651 defer tester.terminate() 652 653 chainA := testChainForkLightA.shorten(testChainBase.len() + 80) 654 chainB := testChainForkLightB.shorten(testChainBase.len() + 80) 655 tester.newPeer("fork A", protocol, chainA) 656 tester.newPeer("fork B", protocol, chainB) 657 // Synchronise with the peer and make sure all blocks were retrieved 658 if err := tester.sync("fork A", nil, mode); err != nil { 659 t.Fatalf("failed to synchronise blocks: %v", err) 660 } 661 assertOwnChain(t, tester, chainA.len()) 662 663 // Synchronise with the second peer and make sure that fork is pulled too 664 if err := tester.sync("fork B", nil, mode); err != nil { 665 t.Fatalf("failed to synchronise blocks: %v", err) 666 } 667 assertOwnForkedChain(t, tester, testChainBase.len(), []int{chainA.len(), chainB.len()}) 668 } 669 670 // Tests that synchronising against a much shorter but much heavyer fork works 671 // corrently and is not dropped. 672 func TestHeavyForkedSync64Full(t *testing.T) { testHeavyForkedSync(t, 64, FullSync) } 673 func TestHeavyForkedSync64Fast(t *testing.T) { testHeavyForkedSync(t, 64, FastSync) } 674 675 func TestHeavyForkedSync65Full(t *testing.T) { testHeavyForkedSync(t, 65, FullSync) } 676 func TestHeavyForkedSync65Fast(t *testing.T) { testHeavyForkedSync(t, 65, FastSync) } 677 func TestHeavyForkedSync65Light(t *testing.T) { testHeavyForkedSync(t, 65, LightSync) } 678 679 func TestHeavyForkedSync66Full(t *testing.T) { testHeavyForkedSync(t, 66, FullSync) } 680 func TestHeavyForkedSync66Fast(t *testing.T) { testHeavyForkedSync(t, 66, FastSync) } 681 func TestHeavyForkedSync66Light(t *testing.T) { testHeavyForkedSync(t, 66, LightSync) } 682 683 func testHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) { 684 t.Parallel() 685 686 tester := newTester() 687 defer tester.terminate() 688 689 chainA := testChainForkLightA.shorten(testChainBase.len() + 80) 690 chainB := testChainForkHeavy.shorten(testChainBase.len() + 80) 691 tester.newPeer("light", protocol, chainA) 692 tester.newPeer("heavy", protocol, chainB) 693 694 // Synchronise with the peer and make sure all blocks were retrieved 695 if err := tester.sync("light", nil, mode); err != nil { 696 t.Fatalf("failed to synchronise blocks: %v", err) 697 } 698 assertOwnChain(t, tester, chainA.len()) 699 700 // Synchronise with the second peer and make sure that fork is pulled too 701 if err := tester.sync("heavy", nil, mode); err != nil { 702 t.Fatalf("failed to synchronise blocks: %v", err) 703 } 704 assertOwnForkedChain(t, tester, testChainBase.len(), []int{chainA.len(), chainB.len()}) 705 } 706 707 // Tests that chain forks are contained within a certain interval of the current 708 // chain head, ensuring that malicious peers cannot waste resources by feeding 709 // long dead chains. 710 func TestBoundedForkedSync64Full(t *testing.T) { testBoundedForkedSync(t, 64, FullSync) } 711 func TestBoundedForkedSync64Fast(t *testing.T) { testBoundedForkedSync(t, 64, FastSync) } 712 713 func TestBoundedForkedSync65Full(t *testing.T) { testBoundedForkedSync(t, 65, FullSync) } 714 func TestBoundedForkedSync65Fast(t *testing.T) { testBoundedForkedSync(t, 65, FastSync) } 715 func TestBoundedForkedSync65Light(t *testing.T) { testBoundedForkedSync(t, 65, LightSync) } 716 717 func TestBoundedForkedSync66Full(t *testing.T) { testBoundedForkedSync(t, 66, FullSync) } 718 func TestBoundedForkedSync66Fast(t *testing.T) { testBoundedForkedSync(t, 66, FastSync) } 719 func TestBoundedForkedSync66Light(t *testing.T) { testBoundedForkedSync(t, 66, LightSync) } 720 721 func testBoundedForkedSync(t *testing.T, protocol uint, mode SyncMode) { 722 t.Parallel() 723 724 tester := newTester() 725 defer tester.terminate() 726 727 chainA := testChainForkLightA 728 chainB := testChainForkLightB 729 tester.newPeer("original", protocol, chainA) 730 tester.newPeer("rewriter", protocol, chainB) 731 732 // Synchronise with the peer and make sure all blocks were retrieved 733 if err := tester.sync("original", nil, mode); err != nil { 734 t.Fatalf("failed to synchronise blocks: %v", err) 735 } 736 assertOwnChain(t, tester, chainA.len()) 737 738 // Synchronise with the second peer and ensure that the fork is rejected to being too old 739 if err := tester.sync("rewriter", nil, mode); err != errInvalidAncestor { 740 t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor) 741 } 742 } 743 744 // Tests that chain forks are contained within a certain interval of the current 745 // chain head for short but heavy forks too. These are a bit special because they 746 // take different ancestor lookup paths. 747 func TestBoundedHeavyForkedSync64Full(t *testing.T) { testBoundedHeavyForkedSync(t, 64, FullSync) } 748 func TestBoundedHeavyForkedSync64Fast(t *testing.T) { testBoundedHeavyForkedSync(t, 64, FastSync) } 749 750 func TestBoundedHeavyForkedSync65Full(t *testing.T) { testBoundedHeavyForkedSync(t, 65, FullSync) } 751 func TestBoundedHeavyForkedSync65Fast(t *testing.T) { testBoundedHeavyForkedSync(t, 65, FastSync) } 752 func TestBoundedHeavyForkedSync65Light(t *testing.T) { testBoundedHeavyForkedSync(t, 65, LightSync) } 753 754 func TestBoundedHeavyForkedSync66Full(t *testing.T) { testBoundedHeavyForkedSync(t, 66, FullSync) } 755 func TestBoundedHeavyForkedSync66Fast(t *testing.T) { testBoundedHeavyForkedSync(t, 66, FastSync) } 756 func TestBoundedHeavyForkedSync66Light(t *testing.T) { testBoundedHeavyForkedSync(t, 66, LightSync) } 757 758 func testBoundedHeavyForkedSync(t *testing.T, protocol uint, mode SyncMode) { 759 t.Parallel() 760 tester := newTester() 761 762 // Create a long enough forked chain 763 chainA := testChainForkLightA 764 chainB := testChainForkHeavy 765 tester.newPeer("original", protocol, chainA) 766 767 // Synchronise with the peer and make sure all blocks were retrieved 768 if err := tester.sync("original", nil, mode); err != nil { 769 t.Fatalf("failed to synchronise blocks: %v", err) 770 } 771 assertOwnChain(t, tester, chainA.len()) 772 773 tester.newPeer("heavy-rewriter", protocol, chainB) 774 // Synchronise with the second peer and ensure that the fork is rejected to being too old 775 if err := tester.sync("heavy-rewriter", nil, mode); err != errInvalidAncestor { 776 t.Fatalf("sync failure mismatch: have %v, want %v", err, errInvalidAncestor) 777 } 778 tester.terminate() 779 } 780 781 // Tests that an inactive downloader will not accept incoming block headers, 782 // bodies and receipts. 783 func TestInactiveDownloader63(t *testing.T) { 784 t.Parallel() 785 786 tester := newTester() 787 defer tester.terminate() 788 789 // Check that neither block headers nor bodies are accepted 790 if err := tester.downloader.DeliverHeaders("bad peer", []*types.Header{}); err != errNoSyncActive { 791 t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive) 792 } 793 if err := tester.downloader.DeliverBodies("bad peer", [][]*types.Transaction{}, [][]*types.Header{}); err != errNoSyncActive { 794 t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive) 795 } 796 if err := tester.downloader.DeliverReceipts("bad peer", [][]*types.Receipt{}); err != errNoSyncActive { 797 t.Errorf("error mismatch: have %v, want %v", err, errNoSyncActive) 798 } 799 } 800 801 // Tests that a canceled download wipes all previously accumulated state. 802 func TestCancel64Full(t *testing.T) { testCancel(t, 64, FullSync) } 803 func TestCancel64Fast(t *testing.T) { testCancel(t, 64, FastSync) } 804 805 func TestCancel65Full(t *testing.T) { testCancel(t, 65, FullSync) } 806 func TestCancel65Fast(t *testing.T) { testCancel(t, 65, FastSync) } 807 func TestCancel65Light(t *testing.T) { testCancel(t, 65, LightSync) } 808 809 func TestCancel66Full(t *testing.T) { testCancel(t, 66, FullSync) } 810 func TestCancel66Fast(t *testing.T) { testCancel(t, 66, FastSync) } 811 func TestCancel66Light(t *testing.T) { testCancel(t, 66, LightSync) } 812 813 func testCancel(t *testing.T, protocol uint, mode SyncMode) { 814 t.Parallel() 815 816 tester := newTester() 817 defer tester.terminate() 818 819 chain := testChainBase.shorten(MaxHeaderFetch) 820 tester.newPeer("peer", protocol, chain) 821 822 // Make sure canceling works with a pristine downloader 823 tester.downloader.Cancel() 824 if !tester.downloader.queue.Idle() { 825 t.Errorf("download queue not idle") 826 } 827 // Synchronise with the peer, but cancel afterwards 828 if err := tester.sync("peer", nil, mode); err != nil { 829 t.Fatalf("failed to synchronise blocks: %v", err) 830 } 831 tester.downloader.Cancel() 832 if !tester.downloader.queue.Idle() { 833 t.Errorf("download queue not idle") 834 } 835 } 836 837 // Tests that synchronisation from multiple peers works as intended (multi thread sanity test). 838 func TestMultiSynchronisation64Full(t *testing.T) { testMultiSynchronisation(t, 64, FullSync) } 839 func TestMultiSynchronisation64Fast(t *testing.T) { testMultiSynchronisation(t, 64, FastSync) } 840 841 func TestMultiSynchronisation65Full(t *testing.T) { testMultiSynchronisation(t, 65, FullSync) } 842 func TestMultiSynchronisation65Fast(t *testing.T) { testMultiSynchronisation(t, 65, FastSync) } 843 func TestMultiSynchronisation65Light(t *testing.T) { testMultiSynchronisation(t, 65, LightSync) } 844 845 func TestMultiSynchronisation66Full(t *testing.T) { testMultiSynchronisation(t, 66, FullSync) } 846 func TestMultiSynchronisation66Fast(t *testing.T) { testMultiSynchronisation(t, 66, FastSync) } 847 func TestMultiSynchronisation66Light(t *testing.T) { testMultiSynchronisation(t, 66, LightSync) } 848 849 func testMultiSynchronisation(t *testing.T, protocol uint, mode SyncMode) { 850 t.Parallel() 851 852 tester := newTester() 853 defer tester.terminate() 854 855 // Create various peers with various parts of the chain 856 targetPeers := 8 857 chain := testChainBase.shorten(targetPeers * 100) 858 859 for i := 0; i < targetPeers; i++ { 860 id := fmt.Sprintf("peer #%d", i) 861 tester.newPeer(id, protocol, chain.shorten(chain.len()/(i+1))) 862 } 863 if err := tester.sync("peer #0", nil, mode); err != nil { 864 t.Fatalf("failed to synchronise blocks: %v", err) 865 } 866 assertOwnChain(t, tester, chain.len()) 867 } 868 869 // Tests that synchronisations behave well in multi-version protocol environments 870 // and not wreak havoc on other nodes in the network. 871 func TestMultiProtoSynchronisation64Full(t *testing.T) { testMultiProtoSync(t, 64, FullSync) } 872 func TestMultiProtoSynchronisation64Fast(t *testing.T) { testMultiProtoSync(t, 64, FastSync) } 873 874 func TestMultiProtoSynchronisation65Full(t *testing.T) { testMultiProtoSync(t, 65, FullSync) } 875 func TestMultiProtoSynchronisation65Fast(t *testing.T) { testMultiProtoSync(t, 65, FastSync) } 876 func TestMultiProtoSynchronisation65Light(t *testing.T) { testMultiProtoSync(t, 65, LightSync) } 877 878 func TestMultiProtoSynchronisation66Full(t *testing.T) { testMultiProtoSync(t, 66, FullSync) } 879 func TestMultiProtoSynchronisation66Fast(t *testing.T) { testMultiProtoSync(t, 66, FastSync) } 880 func TestMultiProtoSynchronisation66Light(t *testing.T) { testMultiProtoSync(t, 66, LightSync) } 881 882 func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) { 883 t.Parallel() 884 885 tester := newTester() 886 defer tester.terminate() 887 888 // Create a small enough block chain to download 889 chain := testChainBase.shorten(blockCacheMaxItems - 15) 890 891 // Create peers of every type 892 tester.newPeer("peer 64", 64, chain) 893 tester.newPeer("peer 65", 65, chain) 894 tester.newPeer("peer 66", 66, chain) 895 896 // Synchronise with the requested peer and make sure all blocks were retrieved 897 if err := tester.sync(fmt.Sprintf("peer %d", protocol), nil, mode); err != nil { 898 t.Fatalf("failed to synchronise blocks: %v", err) 899 } 900 assertOwnChain(t, tester, chain.len()) 901 902 // Check that no peers have been dropped off 903 for _, version := range []int{64, 65, 66} { 904 peer := fmt.Sprintf("peer %d", version) 905 if _, ok := tester.peers[peer]; !ok { 906 t.Errorf("%s dropped", peer) 907 } 908 } 909 } 910 911 // Tests that if a block is empty (e.g. header only), no body request should be 912 // made, and instead the header should be assembled into a whole block in itself. 913 func TestEmptyShortCircuit64Full(t *testing.T) { testEmptyShortCircuit(t, 64, FullSync) } 914 func TestEmptyShortCircuit64Fast(t *testing.T) { testEmptyShortCircuit(t, 64, FastSync) } 915 916 func TestEmptyShortCircuit65Full(t *testing.T) { testEmptyShortCircuit(t, 65, FullSync) } 917 func TestEmptyShortCircuit65Fast(t *testing.T) { testEmptyShortCircuit(t, 65, FastSync) } 918 func TestEmptyShortCircuit65Light(t *testing.T) { testEmptyShortCircuit(t, 65, LightSync) } 919 920 func TestEmptyShortCircuit66Full(t *testing.T) { testEmptyShortCircuit(t, 66, FullSync) } 921 func TestEmptyShortCircuit66Fast(t *testing.T) { testEmptyShortCircuit(t, 66, FastSync) } 922 func TestEmptyShortCircuit66Light(t *testing.T) { testEmptyShortCircuit(t, 66, LightSync) } 923 924 func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) { 925 t.Parallel() 926 927 tester := newTester() 928 defer tester.terminate() 929 930 // Create a block chain to download 931 chain := testChainBase 932 tester.newPeer("peer", protocol, chain) 933 934 // Instrument the downloader to signal body requests 935 bodiesHave, receiptsHave := int32(0), int32(0) 936 tester.downloader.bodyFetchHook = func(headers []*types.Header) { 937 atomic.AddInt32(&bodiesHave, int32(len(headers))) 938 } 939 tester.downloader.receiptFetchHook = func(headers []*types.Header) { 940 atomic.AddInt32(&receiptsHave, int32(len(headers))) 941 } 942 // Synchronise with the peer and make sure all blocks were retrieved 943 if err := tester.sync("peer", nil, mode); err != nil { 944 t.Fatalf("failed to synchronise blocks: %v", err) 945 } 946 assertOwnChain(t, tester, chain.len()) 947 948 // Validate the number of block bodies that should have been requested 949 bodiesNeeded, receiptsNeeded := 0, 0 950 for _, block := range chain.blockm { 951 if mode != LightSync && block != tester.genesis && (len(block.Transactions()) > 0 || len(block.Uncles()) > 0) { 952 bodiesNeeded++ 953 } 954 } 955 for _, receipt := range chain.receiptm { 956 if mode == FastSync && len(receipt) > 0 { 957 receiptsNeeded++ 958 } 959 } 960 if int(bodiesHave) != bodiesNeeded { 961 t.Errorf("body retrieval count mismatch: have %v, want %v", bodiesHave, bodiesNeeded) 962 } 963 if int(receiptsHave) != receiptsNeeded { 964 t.Errorf("receipt retrieval count mismatch: have %v, want %v", receiptsHave, receiptsNeeded) 965 } 966 } 967 968 // Tests that headers are enqueued continuously, preventing malicious nodes from 969 // stalling the downloader by feeding gapped header chains. 970 func TestMissingHeaderAttack64Full(t *testing.T) { testMissingHeaderAttack(t, 64, FullSync) } 971 func TestMissingHeaderAttack64Fast(t *testing.T) { testMissingHeaderAttack(t, 64, FastSync) } 972 973 func TestMissingHeaderAttack65Full(t *testing.T) { testMissingHeaderAttack(t, 65, FullSync) } 974 func TestMissingHeaderAttack65Fast(t *testing.T) { testMissingHeaderAttack(t, 65, FastSync) } 975 func TestMissingHeaderAttack65Light(t *testing.T) { testMissingHeaderAttack(t, 65, LightSync) } 976 977 func TestMissingHeaderAttack66Full(t *testing.T) { testMissingHeaderAttack(t, 66, FullSync) } 978 func TestMissingHeaderAttack66Fast(t *testing.T) { testMissingHeaderAttack(t, 66, FastSync) } 979 func TestMissingHeaderAttack66Light(t *testing.T) { testMissingHeaderAttack(t, 66, LightSync) } 980 981 func testMissingHeaderAttack(t *testing.T, protocol uint, mode SyncMode) { 982 t.Parallel() 983 984 tester := newTester() 985 defer tester.terminate() 986 987 chain := testChainBase.shorten(blockCacheMaxItems - 15) 988 brokenChain := chain.shorten(chain.len()) 989 delete(brokenChain.headerm, brokenChain.chain[brokenChain.len()/2]) 990 tester.newPeer("attack", protocol, brokenChain) 991 992 if err := tester.sync("attack", nil, mode); err == nil { 993 t.Fatalf("succeeded attacker synchronisation") 994 } 995 // Synchronise with the valid peer and make sure sync succeeds 996 tester.newPeer("valid", protocol, chain) 997 if err := tester.sync("valid", nil, mode); err != nil { 998 t.Fatalf("failed to synchronise blocks: %v", err) 999 } 1000 assertOwnChain(t, tester, chain.len()) 1001 } 1002 1003 // Tests that if requested headers are shifted (i.e. first is missing), the queue 1004 // detects the invalid numbering. 1005 func TestShiftedHeaderAttack64Full(t *testing.T) { testShiftedHeaderAttack(t, 64, FullSync) } 1006 func TestShiftedHeaderAttack64Fast(t *testing.T) { testShiftedHeaderAttack(t, 64, FastSync) } 1007 1008 func TestShiftedHeaderAttack65Full(t *testing.T) { testShiftedHeaderAttack(t, 65, FullSync) } 1009 func TestShiftedHeaderAttack65Fast(t *testing.T) { testShiftedHeaderAttack(t, 65, FastSync) } 1010 func TestShiftedHeaderAttack65Light(t *testing.T) { testShiftedHeaderAttack(t, 65, LightSync) } 1011 1012 func TestShiftedHeaderAttack66Full(t *testing.T) { testShiftedHeaderAttack(t, 66, FullSync) } 1013 func TestShiftedHeaderAttack66Fast(t *testing.T) { testShiftedHeaderAttack(t, 66, FastSync) } 1014 func TestShiftedHeaderAttack66Light(t *testing.T) { testShiftedHeaderAttack(t, 66, LightSync) } 1015 1016 func testShiftedHeaderAttack(t *testing.T, protocol uint, mode SyncMode) { 1017 t.Parallel() 1018 1019 tester := newTester() 1020 defer tester.terminate() 1021 1022 chain := testChainBase.shorten(blockCacheMaxItems - 15) 1023 1024 // Attempt a full sync with an attacker feeding shifted headers 1025 brokenChain := chain.shorten(chain.len()) 1026 delete(brokenChain.headerm, brokenChain.chain[1]) 1027 delete(brokenChain.blockm, brokenChain.chain[1]) 1028 delete(brokenChain.receiptm, brokenChain.chain[1]) 1029 tester.newPeer("attack", protocol, brokenChain) 1030 if err := tester.sync("attack", nil, mode); err == nil { 1031 t.Fatalf("succeeded attacker synchronisation") 1032 } 1033 1034 // Synchronise with the valid peer and make sure sync succeeds 1035 tester.newPeer("valid", protocol, chain) 1036 if err := tester.sync("valid", nil, mode); err != nil { 1037 t.Fatalf("failed to synchronise blocks: %v", err) 1038 } 1039 assertOwnChain(t, tester, chain.len()) 1040 } 1041 1042 // Tests that upon detecting an invalid header, the recent ones are rolled back 1043 // for various failure scenarios. Afterwards a full sync is attempted to make 1044 // sure no state was corrupted. 1045 func TestInvalidHeaderRollback64Fast(t *testing.T) { testInvalidHeaderRollback(t, 64, FastSync) } 1046 func TestInvalidHeaderRollback65Fast(t *testing.T) { testInvalidHeaderRollback(t, 65, FastSync) } 1047 func TestInvalidHeaderRollback66Fast(t *testing.T) { testInvalidHeaderRollback(t, 66, FastSync) } 1048 1049 func testInvalidHeaderRollback(t *testing.T, protocol uint, mode SyncMode) { 1050 t.Parallel() 1051 1052 tester := newTester() 1053 1054 // Create a small enough block chain to download 1055 targetBlocks := 3*fsHeaderSafetyNet + 256 + fsMinFullBlocks 1056 chain := testChainBase.shorten(targetBlocks) 1057 1058 // Attempt to sync with an attacker that feeds junk during the fast sync phase. 1059 // This should result in the last fsHeaderSafetyNet headers being rolled back. 1060 missing := fsHeaderSafetyNet + MaxHeaderFetch + 1 1061 fastAttackChain := chain.shorten(chain.len()) 1062 delete(fastAttackChain.headerm, fastAttackChain.chain[missing]) 1063 tester.newPeer("fast-attack", protocol, fastAttackChain) 1064 1065 if err := tester.sync("fast-attack", nil, mode); err == nil { 1066 t.Fatalf("succeeded fast attacker synchronisation") 1067 } 1068 if head := tester.CurrentHeader().Number.Int64(); int(head) > MaxHeaderFetch { 1069 t.Errorf("rollback head mismatch: have %v, want at most %v", head, MaxHeaderFetch) 1070 } 1071 1072 // Attempt to sync with an attacker that feeds junk during the block import phase. 1073 // This should result in both the last fsHeaderSafetyNet number of headers being 1074 // rolled back, and also the pivot point being reverted to a non-block status. 1075 missing = 3*fsHeaderSafetyNet + MaxHeaderFetch + 1 1076 blockAttackChain := chain.shorten(chain.len()) 1077 delete(fastAttackChain.headerm, fastAttackChain.chain[missing]) // Make sure the fast-attacker doesn't fill in 1078 delete(blockAttackChain.headerm, blockAttackChain.chain[missing]) 1079 tester.newPeer("block-attack", protocol, blockAttackChain) 1080 1081 if err := tester.sync("block-attack", nil, mode); err == nil { 1082 t.Fatalf("succeeded block attacker synchronisation") 1083 } 1084 if head := tester.CurrentHeader().Number.Int64(); int(head) > 2*fsHeaderSafetyNet+MaxHeaderFetch { 1085 t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch) 1086 } 1087 if mode == FastSync { 1088 if head := tester.CurrentBlock().NumberU64(); head != 0 { 1089 t.Errorf("fast sync pivot block #%d not rolled back", head) 1090 } 1091 } 1092 1093 // Attempt to sync with an attacker that withholds promised blocks after the 1094 // fast sync pivot point. This could be a trial to leave the node with a bad 1095 // but already imported pivot block. 1096 withholdAttackChain := chain.shorten(chain.len()) 1097 tester.newPeer("withhold-attack", protocol, withholdAttackChain) 1098 tester.downloader.syncInitHook = func(uint64, uint64) { 1099 for i := missing; i < withholdAttackChain.len(); i++ { 1100 delete(withholdAttackChain.headerm, withholdAttackChain.chain[i]) 1101 } 1102 tester.downloader.syncInitHook = nil 1103 } 1104 if err := tester.sync("withhold-attack", nil, mode); err == nil { 1105 t.Fatalf("succeeded withholding attacker synchronisation") 1106 } 1107 if head := tester.CurrentHeader().Number.Int64(); int(head) > 2*fsHeaderSafetyNet+MaxHeaderFetch { 1108 t.Errorf("rollback head mismatch: have %v, want at most %v", head, 2*fsHeaderSafetyNet+MaxHeaderFetch) 1109 } 1110 if mode == FastSync { 1111 if head := tester.CurrentBlock().NumberU64(); head != 0 { 1112 t.Errorf("fast sync pivot block #%d not rolled back", head) 1113 } 1114 } 1115 1116 // synchronise with the valid peer and make sure sync succeeds. Since the last rollback 1117 // should also disable fast syncing for this process, verify that we did a fresh full 1118 // sync. Note, we can't assert anything about the receipts since we won't purge the 1119 // database of them, hence we can't use assertOwnChain. 1120 tester.newPeer("valid", protocol, chain) 1121 if err := tester.sync("valid", nil, mode); err != nil { 1122 t.Fatalf("failed to synchronise blocks: %v", err) 1123 } 1124 if hs := len(tester.ownHeaders); hs != chain.len() { 1125 t.Fatalf("synchronised headers mismatch: have %v, want %v", hs, chain.len()) 1126 } 1127 if mode != LightSync { 1128 if bs := len(tester.ownBlocks); bs != chain.len() { 1129 t.Fatalf("synchronised blocks mismatch: have %v, want %v", bs, chain.len()) 1130 } 1131 } 1132 tester.terminate() 1133 } 1134 1135 // Tests that a peer advertising a high TD doesn't get to stall the downloader 1136 // afterwards by not sending any useful hashes. 1137 func TestHighTDStarvationAttack64Full(t *testing.T) { testHighTDStarvationAttack(t, 64, FullSync) } 1138 func TestHighTDStarvationAttack64Fast(t *testing.T) { testHighTDStarvationAttack(t, 64, FastSync) } 1139 1140 func TestHighTDStarvationAttack65Full(t *testing.T) { testHighTDStarvationAttack(t, 65, FullSync) } 1141 func TestHighTDStarvationAttack65Fast(t *testing.T) { testHighTDStarvationAttack(t, 65, FastSync) } 1142 func TestHighTDStarvationAttack65Light(t *testing.T) { testHighTDStarvationAttack(t, 65, LightSync) } 1143 1144 func TestHighTDStarvationAttack66Full(t *testing.T) { testHighTDStarvationAttack(t, 66, FullSync) } 1145 func TestHighTDStarvationAttack66Fast(t *testing.T) { testHighTDStarvationAttack(t, 66, FastSync) } 1146 func TestHighTDStarvationAttack66Light(t *testing.T) { testHighTDStarvationAttack(t, 66, LightSync) } 1147 1148 func testHighTDStarvationAttack(t *testing.T, protocol uint, mode SyncMode) { 1149 t.Parallel() 1150 1151 tester := newTester() 1152 1153 chain := testChainBase.shorten(1) 1154 tester.newPeer("attack", protocol, chain) 1155 if err := tester.sync("attack", big.NewInt(1000000), mode); err != errStallingPeer { 1156 t.Fatalf("synchronisation error mismatch: have %v, want %v", err, errStallingPeer) 1157 } 1158 tester.terminate() 1159 } 1160 1161 // Tests that misbehaving peers are disconnected, whilst behaving ones are not. 1162 func TestBlockHeaderAttackerDropping64(t *testing.T) { testBlockHeaderAttackerDropping(t, 64) } 1163 func TestBlockHeaderAttackerDropping65(t *testing.T) { testBlockHeaderAttackerDropping(t, 65) } 1164 func TestBlockHeaderAttackerDropping66(t *testing.T) { testBlockHeaderAttackerDropping(t, 66) } 1165 1166 func testBlockHeaderAttackerDropping(t *testing.T, protocol uint) { 1167 t.Parallel() 1168 1169 // Define the disconnection requirement for individual hash fetch errors 1170 tests := []struct { 1171 result error 1172 drop bool 1173 }{ 1174 {nil, false}, // Sync succeeded, all is well 1175 {errBusy, false}, // Sync is already in progress, no problem 1176 {errUnknownPeer, false}, // Peer is unknown, was already dropped, don't double drop 1177 {errBadPeer, true}, // Peer was deemed bad for some reason, drop it 1178 {errStallingPeer, true}, // Peer was detected to be stalling, drop it 1179 {errUnsyncedPeer, true}, // Peer was detected to be unsynced, drop it 1180 {errNoPeers, false}, // No peers to download from, soft race, no issue 1181 {errTimeout, true}, // No hashes received in due time, drop the peer 1182 {errEmptyHeaderSet, true}, // No headers were returned as a response, drop as it's a dead end 1183 {errPeersUnavailable, true}, // Nobody had the advertised blocks, drop the advertiser 1184 {errInvalidAncestor, true}, // Agreed upon ancestor is not acceptable, drop the chain rewriter 1185 {errInvalidChain, true}, // Hash chain was detected as invalid, definitely drop 1186 {errInvalidBody, false}, // A bad peer was detected, but not the sync origin 1187 {errInvalidReceipt, false}, // A bad peer was detected, but not the sync origin 1188 {errCancelContentProcessing, false}, // Synchronisation was canceled, origin may be innocent, don't drop 1189 } 1190 // Run the tests and check disconnection status 1191 tester := newTester() 1192 defer tester.terminate() 1193 chain := testChainBase.shorten(1) 1194 1195 for i, tt := range tests { 1196 // Register a new peer and ensure its presence 1197 id := fmt.Sprintf("test %d", i) 1198 if err := tester.newPeer(id, protocol, chain); err != nil { 1199 t.Fatalf("test %d: failed to register new peer: %v", i, err) 1200 } 1201 if _, ok := tester.peers[id]; !ok { 1202 t.Fatalf("test %d: registered peer not found", i) 1203 } 1204 // Simulate a synchronisation and check the required result 1205 tester.downloader.synchroniseMock = func(string, common.Hash) error { return tt.result } 1206 1207 tester.downloader.Synchronise(id, tester.genesis.Hash(), big.NewInt(1000), FullSync) 1208 if _, ok := tester.peers[id]; !ok != tt.drop { 1209 t.Errorf("test %d: peer drop mismatch for %v: have %v, want %v", i, tt.result, !ok, tt.drop) 1210 } 1211 } 1212 } 1213 1214 // Tests that synchronisation progress (origin block number, current block number 1215 // and highest block number) is tracked and updated correctly. 1216 func TestSyncProgress64Full(t *testing.T) { testSyncProgress(t, 64, FullSync) } 1217 func TestSyncProgress64Fast(t *testing.T) { testSyncProgress(t, 64, FastSync) } 1218 1219 func TestSyncProgress65Full(t *testing.T) { testSyncProgress(t, 65, FullSync) } 1220 func TestSyncProgress65Fast(t *testing.T) { testSyncProgress(t, 65, FastSync) } 1221 func TestSyncProgress65Light(t *testing.T) { testSyncProgress(t, 65, LightSync) } 1222 1223 func TestSyncProgress66Full(t *testing.T) { testSyncProgress(t, 66, FullSync) } 1224 func TestSyncProgress66Fast(t *testing.T) { testSyncProgress(t, 66, FastSync) } 1225 func TestSyncProgress66Light(t *testing.T) { testSyncProgress(t, 66, LightSync) } 1226 1227 func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) { 1228 t.Parallel() 1229 1230 tester := newTester() 1231 defer tester.terminate() 1232 chain := testChainBase.shorten(blockCacheMaxItems - 15) 1233 1234 // Set a sync init hook to catch progress changes 1235 starting := make(chan struct{}) 1236 progress := make(chan struct{}) 1237 1238 tester.downloader.syncInitHook = func(origin, latest uint64) { 1239 starting <- struct{}{} 1240 <-progress 1241 } 1242 checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) 1243 1244 // Synchronise half the blocks and check initial progress 1245 tester.newPeer("peer-half", protocol, chain.shorten(chain.len()/2)) 1246 pending := new(sync.WaitGroup) 1247 pending.Add(1) 1248 1249 go func() { 1250 defer pending.Done() 1251 if err := tester.sync("peer-half", nil, mode); err != nil { 1252 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1253 } 1254 }() 1255 <-starting 1256 checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ 1257 HighestBlock: uint64(chain.len()/2 - 1), 1258 }) 1259 progress <- struct{}{} 1260 pending.Wait() 1261 1262 // Synchronise all the blocks and check continuation progress 1263 tester.newPeer("peer-full", protocol, chain) 1264 pending.Add(1) 1265 go func() { 1266 defer pending.Done() 1267 if err := tester.sync("peer-full", nil, mode); err != nil { 1268 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1269 } 1270 }() 1271 <-starting 1272 checkProgress(t, tester.downloader, "completing", ethereum.SyncProgress{ 1273 StartingBlock: uint64(chain.len()/2 - 1), 1274 CurrentBlock: uint64(chain.len()/2 - 1), 1275 HighestBlock: uint64(chain.len() - 1), 1276 }) 1277 1278 // Check final progress after successful sync 1279 progress <- struct{}{} 1280 pending.Wait() 1281 checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{ 1282 StartingBlock: uint64(chain.len()/2 - 1), 1283 CurrentBlock: uint64(chain.len() - 1), 1284 HighestBlock: uint64(chain.len() - 1), 1285 }) 1286 } 1287 1288 func checkProgress(t *testing.T, d *Downloader, stage string, want ethereum.SyncProgress) { 1289 // Mark this method as a helper to report errors at callsite, not in here 1290 t.Helper() 1291 1292 p := d.Progress() 1293 p.KnownStates, p.PulledStates = 0, 0 1294 want.KnownStates, want.PulledStates = 0, 0 1295 if p != want { 1296 t.Fatalf("%s progress mismatch:\nhave %+v\nwant %+v", stage, p, want) 1297 } 1298 } 1299 1300 // Tests that synchronisation progress (origin block number and highest block 1301 // number) is tracked and updated correctly in case of a fork (or manual head 1302 // revertal). 1303 func TestForkedSyncProgress64Full(t *testing.T) { testForkedSyncProgress(t, 64, FullSync) } 1304 func TestForkedSyncProgress64Fast(t *testing.T) { testForkedSyncProgress(t, 64, FastSync) } 1305 1306 func TestForkedSyncProgress65Full(t *testing.T) { testForkedSyncProgress(t, 65, FullSync) } 1307 func TestForkedSyncProgress65Fast(t *testing.T) { testForkedSyncProgress(t, 65, FastSync) } 1308 func TestForkedSyncProgress65Light(t *testing.T) { testForkedSyncProgress(t, 65, LightSync) } 1309 1310 func TestForkedSyncProgress66Full(t *testing.T) { testForkedSyncProgress(t, 66, FullSync) } 1311 func TestForkedSyncProgress66Fast(t *testing.T) { testForkedSyncProgress(t, 66, FastSync) } 1312 func TestForkedSyncProgress66Light(t *testing.T) { testForkedSyncProgress(t, 66, LightSync) } 1313 1314 func testForkedSyncProgress(t *testing.T, protocol uint, mode SyncMode) { 1315 t.Parallel() 1316 1317 tester := newTester() 1318 defer tester.terminate() 1319 chainA := testChainForkLightA.shorten(testChainBase.len() + MaxHeaderFetch) 1320 chainB := testChainForkLightB.shorten(testChainBase.len() + MaxHeaderFetch) 1321 1322 // Set a sync init hook to catch progress changes 1323 starting := make(chan struct{}) 1324 progress := make(chan struct{}) 1325 1326 tester.downloader.syncInitHook = func(origin, latest uint64) { 1327 starting <- struct{}{} 1328 <-progress 1329 } 1330 checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) 1331 1332 // Synchronise with one of the forks and check progress 1333 tester.newPeer("fork A", protocol, chainA) 1334 pending := new(sync.WaitGroup) 1335 pending.Add(1) 1336 go func() { 1337 defer pending.Done() 1338 if err := tester.sync("fork A", nil, mode); err != nil { 1339 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1340 } 1341 }() 1342 <-starting 1343 1344 checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ 1345 HighestBlock: uint64(chainA.len() - 1), 1346 }) 1347 progress <- struct{}{} 1348 pending.Wait() 1349 1350 // Simulate a successful sync above the fork 1351 tester.downloader.syncStatsChainOrigin = tester.downloader.syncStatsChainHeight 1352 1353 // Synchronise with the second fork and check progress resets 1354 tester.newPeer("fork B", protocol, chainB) 1355 pending.Add(1) 1356 go func() { 1357 defer pending.Done() 1358 if err := tester.sync("fork B", nil, mode); err != nil { 1359 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1360 } 1361 }() 1362 <-starting 1363 checkProgress(t, tester.downloader, "forking", ethereum.SyncProgress{ 1364 StartingBlock: uint64(testChainBase.len()) - 1, 1365 CurrentBlock: uint64(chainA.len() - 1), 1366 HighestBlock: uint64(chainB.len() - 1), 1367 }) 1368 1369 // Check final progress after successful sync 1370 progress <- struct{}{} 1371 pending.Wait() 1372 checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{ 1373 StartingBlock: uint64(testChainBase.len()) - 1, 1374 CurrentBlock: uint64(chainB.len() - 1), 1375 HighestBlock: uint64(chainB.len() - 1), 1376 }) 1377 } 1378 1379 // Tests that if synchronisation is aborted due to some failure, then the progress 1380 // origin is not updated in the next sync cycle, as it should be considered the 1381 // continuation of the previous sync and not a new instance. 1382 func TestFailedSyncProgress64Full(t *testing.T) { testFailedSyncProgress(t, 64, FullSync) } 1383 func TestFailedSyncProgress64Fast(t *testing.T) { testFailedSyncProgress(t, 64, FastSync) } 1384 1385 func TestFailedSyncProgress65Full(t *testing.T) { testFailedSyncProgress(t, 65, FullSync) } 1386 func TestFailedSyncProgress65Fast(t *testing.T) { testFailedSyncProgress(t, 65, FastSync) } 1387 func TestFailedSyncProgress65Light(t *testing.T) { testFailedSyncProgress(t, 65, LightSync) } 1388 1389 func TestFailedSyncProgress66Full(t *testing.T) { testFailedSyncProgress(t, 66, FullSync) } 1390 func TestFailedSyncProgress66Fast(t *testing.T) { testFailedSyncProgress(t, 66, FastSync) } 1391 func TestFailedSyncProgress66Light(t *testing.T) { testFailedSyncProgress(t, 66, LightSync) } 1392 1393 func testFailedSyncProgress(t *testing.T, protocol uint, mode SyncMode) { 1394 t.Parallel() 1395 1396 tester := newTester() 1397 defer tester.terminate() 1398 chain := testChainBase.shorten(blockCacheMaxItems - 15) 1399 1400 // Set a sync init hook to catch progress changes 1401 starting := make(chan struct{}) 1402 progress := make(chan struct{}) 1403 1404 tester.downloader.syncInitHook = func(origin, latest uint64) { 1405 starting <- struct{}{} 1406 <-progress 1407 } 1408 checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) 1409 1410 // Attempt a full sync with a faulty peer 1411 brokenChain := chain.shorten(chain.len()) 1412 missing := brokenChain.len() / 2 1413 delete(brokenChain.headerm, brokenChain.chain[missing]) 1414 delete(brokenChain.blockm, brokenChain.chain[missing]) 1415 delete(brokenChain.receiptm, brokenChain.chain[missing]) 1416 tester.newPeer("faulty", protocol, brokenChain) 1417 1418 pending := new(sync.WaitGroup) 1419 pending.Add(1) 1420 go func() { 1421 defer pending.Done() 1422 if err := tester.sync("faulty", nil, mode); err == nil { 1423 panic("succeeded faulty synchronisation") 1424 } 1425 }() 1426 <-starting 1427 checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ 1428 HighestBlock: uint64(brokenChain.len() - 1), 1429 }) 1430 progress <- struct{}{} 1431 pending.Wait() 1432 afterFailedSync := tester.downloader.Progress() 1433 1434 // Synchronise with a good peer and check that the progress origin remind the same 1435 // after a failure 1436 tester.newPeer("valid", protocol, chain) 1437 pending.Add(1) 1438 go func() { 1439 defer pending.Done() 1440 if err := tester.sync("valid", nil, mode); err != nil { 1441 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1442 } 1443 }() 1444 <-starting 1445 checkProgress(t, tester.downloader, "completing", afterFailedSync) 1446 1447 // Check final progress after successful sync 1448 progress <- struct{}{} 1449 pending.Wait() 1450 checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{ 1451 CurrentBlock: uint64(chain.len() - 1), 1452 HighestBlock: uint64(chain.len() - 1), 1453 }) 1454 } 1455 1456 // Tests that if an attacker fakes a chain height, after the attack is detected, 1457 // the progress height is successfully reduced at the next sync invocation. 1458 func TestFakedSyncProgress64Full(t *testing.T) { testFakedSyncProgress(t, 64, FullSync) } 1459 func TestFakedSyncProgress64Fast(t *testing.T) { testFakedSyncProgress(t, 64, FastSync) } 1460 1461 func TestFakedSyncProgress65Full(t *testing.T) { testFakedSyncProgress(t, 65, FullSync) } 1462 func TestFakedSyncProgress65Fast(t *testing.T) { testFakedSyncProgress(t, 65, FastSync) } 1463 func TestFakedSyncProgress65Light(t *testing.T) { testFakedSyncProgress(t, 65, LightSync) } 1464 1465 func TestFakedSyncProgress66Full(t *testing.T) { testFakedSyncProgress(t, 66, FullSync) } 1466 func TestFakedSyncProgress66Fast(t *testing.T) { testFakedSyncProgress(t, 66, FastSync) } 1467 func TestFakedSyncProgress66Light(t *testing.T) { testFakedSyncProgress(t, 66, LightSync) } 1468 1469 func testFakedSyncProgress(t *testing.T, protocol uint, mode SyncMode) { 1470 t.Parallel() 1471 1472 tester := newTester() 1473 defer tester.terminate() 1474 chain := testChainBase.shorten(blockCacheMaxItems - 15) 1475 1476 // Set a sync init hook to catch progress changes 1477 starting := make(chan struct{}) 1478 progress := make(chan struct{}) 1479 tester.downloader.syncInitHook = func(origin, latest uint64) { 1480 starting <- struct{}{} 1481 <-progress 1482 } 1483 checkProgress(t, tester.downloader, "pristine", ethereum.SyncProgress{}) 1484 1485 // Create and sync with an attacker that promises a higher chain than available. 1486 brokenChain := chain.shorten(chain.len()) 1487 numMissing := 5 1488 for i := brokenChain.len() - 2; i > brokenChain.len()-numMissing; i-- { 1489 delete(brokenChain.headerm, brokenChain.chain[i]) 1490 } 1491 tester.newPeer("attack", protocol, brokenChain) 1492 1493 pending := new(sync.WaitGroup) 1494 pending.Add(1) 1495 go func() { 1496 defer pending.Done() 1497 if err := tester.sync("attack", nil, mode); err == nil { 1498 panic("succeeded attacker synchronisation") 1499 } 1500 }() 1501 <-starting 1502 checkProgress(t, tester.downloader, "initial", ethereum.SyncProgress{ 1503 HighestBlock: uint64(brokenChain.len() - 1), 1504 }) 1505 progress <- struct{}{} 1506 pending.Wait() 1507 afterFailedSync := tester.downloader.Progress() 1508 1509 // Synchronise with a good peer and check that the progress height has been reduced to 1510 // the true value. 1511 validChain := chain.shorten(chain.len() - numMissing) 1512 tester.newPeer("valid", protocol, validChain) 1513 pending.Add(1) 1514 1515 go func() { 1516 defer pending.Done() 1517 if err := tester.sync("valid", nil, mode); err != nil { 1518 panic(fmt.Sprintf("failed to synchronise blocks: %v", err)) 1519 } 1520 }() 1521 <-starting 1522 checkProgress(t, tester.downloader, "completing", ethereum.SyncProgress{ 1523 CurrentBlock: afterFailedSync.CurrentBlock, 1524 HighestBlock: uint64(validChain.len() - 1), 1525 }) 1526 1527 // Check final progress after successful sync. 1528 progress <- struct{}{} 1529 pending.Wait() 1530 checkProgress(t, tester.downloader, "final", ethereum.SyncProgress{ 1531 CurrentBlock: uint64(validChain.len() - 1), 1532 HighestBlock: uint64(validChain.len() - 1), 1533 }) 1534 } 1535 1536 // This test reproduces an issue where unexpected deliveries would 1537 // block indefinitely if they arrived at the right time. 1538 func TestDeliverHeadersHang64Full(t *testing.T) { testDeliverHeadersHang(t, 64, FullSync) } 1539 func TestDeliverHeadersHang64Fast(t *testing.T) { testDeliverHeadersHang(t, 64, FastSync) } 1540 1541 func TestDeliverHeadersHang65Full(t *testing.T) { testDeliverHeadersHang(t, 65, FullSync) } 1542 func TestDeliverHeadersHang65Fast(t *testing.T) { testDeliverHeadersHang(t, 65, FastSync) } 1543 func TestDeliverHeadersHang65Light(t *testing.T) { testDeliverHeadersHang(t, 65, LightSync) } 1544 1545 func TestDeliverHeadersHang66Full(t *testing.T) { testDeliverHeadersHang(t, 66, FullSync) } 1546 func TestDeliverHeadersHang66Fast(t *testing.T) { testDeliverHeadersHang(t, 66, FastSync) } 1547 func TestDeliverHeadersHang66Light(t *testing.T) { testDeliverHeadersHang(t, 66, LightSync) } 1548 1549 func testDeliverHeadersHang(t *testing.T, protocol uint, mode SyncMode) { 1550 t.Parallel() 1551 1552 master := newTester() 1553 defer master.terminate() 1554 chain := testChainBase.shorten(15) 1555 1556 for i := 0; i < 200; i++ { 1557 tester := newTester() 1558 tester.peerDb = master.peerDb 1559 tester.newPeer("peer", protocol, chain) 1560 1561 // Whenever the downloader requests headers, flood it with 1562 // a lot of unrequested header deliveries. 1563 tester.downloader.peers.peers["peer"].peer = &floodingTestPeer{ 1564 peer: tester.downloader.peers.peers["peer"].peer, 1565 tester: tester, 1566 } 1567 if err := tester.sync("peer", nil, mode); err != nil { 1568 t.Errorf("test %d: sync failed: %v", i, err) 1569 } 1570 tester.terminate() 1571 } 1572 } 1573 1574 type floodingTestPeer struct { 1575 peer Peer 1576 tester *downloadTester 1577 } 1578 1579 func (ftp *floodingTestPeer) Head() (common.Hash, *big.Int) { return ftp.peer.Head() } 1580 func (ftp *floodingTestPeer) RequestHeadersByHash(hash common.Hash, count int, skip int, reverse bool) error { 1581 return ftp.peer.RequestHeadersByHash(hash, count, skip, reverse) 1582 } 1583 func (ftp *floodingTestPeer) RequestBodies(hashes []common.Hash) error { 1584 return ftp.peer.RequestBodies(hashes) 1585 } 1586 func (ftp *floodingTestPeer) RequestReceipts(hashes []common.Hash) error { 1587 return ftp.peer.RequestReceipts(hashes) 1588 } 1589 func (ftp *floodingTestPeer) RequestNodeData(hashes []common.Hash) error { 1590 return ftp.peer.RequestNodeData(hashes) 1591 } 1592 1593 func (ftp *floodingTestPeer) RequestHeadersByNumber(from uint64, count, skip int, reverse bool) error { 1594 deliveriesDone := make(chan struct{}, 500) 1595 for i := 0; i < cap(deliveriesDone)-1; i++ { 1596 peer := fmt.Sprintf("fake-peer%d", i) 1597 go func() { 1598 ftp.tester.downloader.DeliverHeaders(peer, []*types.Header{{}, {}, {}, {}}) 1599 deliveriesDone <- struct{}{} 1600 }() 1601 } 1602 1603 // None of the extra deliveries should block. 1604 timeout := time.After(60 * time.Second) 1605 launched := false 1606 for i := 0; i < cap(deliveriesDone); i++ { 1607 select { 1608 case <-deliveriesDone: 1609 if !launched { 1610 // Start delivering the requested headers 1611 // after one of the flooding responses has arrived. 1612 go func() { 1613 ftp.peer.RequestHeadersByNumber(from, count, skip, reverse) 1614 deliveriesDone <- struct{}{} 1615 }() 1616 launched = true 1617 } 1618 case <-timeout: 1619 panic("blocked") 1620 } 1621 } 1622 return nil 1623 } 1624 1625 func TestRemoteHeaderRequestSpan(t *testing.T) { 1626 testCases := []struct { 1627 remoteHeight uint64 1628 localHeight uint64 1629 expected []int 1630 }{ 1631 // Remote is way higher. We should ask for the remote head and go backwards 1632 {1500, 1000, 1633 []int{1323, 1339, 1355, 1371, 1387, 1403, 1419, 1435, 1451, 1467, 1483, 1499}, 1634 }, 1635 {15000, 13006, 1636 []int{14823, 14839, 14855, 14871, 14887, 14903, 14919, 14935, 14951, 14967, 14983, 14999}, 1637 }, 1638 // Remote is pretty close to us. We don't have to fetch as many 1639 {1200, 1150, 1640 []int{1149, 1154, 1159, 1164, 1169, 1174, 1179, 1184, 1189, 1194, 1199}, 1641 }, 1642 // Remote is equal to us (so on a fork with higher td) 1643 // We should get the closest couple of ancestors 1644 {1500, 1500, 1645 []int{1497, 1499}, 1646 }, 1647 // We're higher than the remote! Odd 1648 {1000, 1500, 1649 []int{997, 999}, 1650 }, 1651 // Check some weird edgecases that it behaves somewhat rationally 1652 {0, 1500, 1653 []int{0, 2}, 1654 }, 1655 {6000000, 0, 1656 []int{5999823, 5999839, 5999855, 5999871, 5999887, 5999903, 5999919, 5999935, 5999951, 5999967, 5999983, 5999999}, 1657 }, 1658 {0, 0, 1659 []int{0, 2}, 1660 }, 1661 } 1662 reqs := func(from, count, span int) []int { 1663 var r []int 1664 num := from 1665 for len(r) < count { 1666 r = append(r, num) 1667 num += span + 1 1668 } 1669 return r 1670 } 1671 for i, tt := range testCases { 1672 from, count, span, max := calculateRequestSpan(tt.remoteHeight, tt.localHeight) 1673 data := reqs(int(from), count, span) 1674 1675 if max != uint64(data[len(data)-1]) { 1676 t.Errorf("test %d: wrong last value %d != %d", i, data[len(data)-1], max) 1677 } 1678 failed := false 1679 if len(data) != len(tt.expected) { 1680 failed = true 1681 t.Errorf("test %d: length wrong, expected %d got %d", i, len(tt.expected), len(data)) 1682 } else { 1683 for j, n := range data { 1684 if n != tt.expected[j] { 1685 failed = true 1686 break 1687 } 1688 } 1689 } 1690 if failed { 1691 res := strings.Replace(fmt.Sprint(data), " ", ",", -1) 1692 exp := strings.Replace(fmt.Sprint(tt.expected), " ", ",", -1) 1693 t.Logf("got: %v\n", res) 1694 t.Logf("exp: %v\n", exp) 1695 t.Errorf("test %d: wrong values", i) 1696 } 1697 } 1698 } 1699 1700 // Tests that peers below a pre-configured checkpoint block are prevented from 1701 // being fast-synced from, avoiding potential cheap eclipse attacks. 1702 func TestCheckpointEnforcement64Full(t *testing.T) { testCheckpointEnforcement(t, 64, FullSync) } 1703 func TestCheckpointEnforcement64Fast(t *testing.T) { testCheckpointEnforcement(t, 64, FastSync) } 1704 1705 func TestCheckpointEnforcement65Full(t *testing.T) { testCheckpointEnforcement(t, 65, FullSync) } 1706 func TestCheckpointEnforcement65Fast(t *testing.T) { testCheckpointEnforcement(t, 65, FastSync) } 1707 func TestCheckpointEnforcement65Light(t *testing.T) { testCheckpointEnforcement(t, 65, LightSync) } 1708 1709 func TestCheckpointEnforcement66Full(t *testing.T) { testCheckpointEnforcement(t, 66, FullSync) } 1710 func TestCheckpointEnforcement66Fast(t *testing.T) { testCheckpointEnforcement(t, 66, FastSync) } 1711 func TestCheckpointEnforcement66Light(t *testing.T) { testCheckpointEnforcement(t, 66, LightSync) } 1712 1713 func testCheckpointEnforcement(t *testing.T, protocol uint, mode SyncMode) { 1714 t.Parallel() 1715 1716 // Create a new tester with a particular hard coded checkpoint block 1717 tester := newTester() 1718 defer tester.terminate() 1719 1720 tester.downloader.checkpoint = uint64(fsMinFullBlocks) + 256 1721 chain := testChainBase.shorten(int(tester.downloader.checkpoint) - 1) 1722 1723 // Attempt to sync with the peer and validate the result 1724 tester.newPeer("peer", protocol, chain) 1725 1726 var expect error 1727 if mode == FastSync || mode == LightSync { 1728 expect = errUnsyncedPeer 1729 } 1730 if err := tester.sync("peer", nil, mode); !errors.Is(err, expect) { 1731 t.Fatalf("block sync error mismatch: have %v, want %v", err, expect) 1732 } 1733 if mode == FastSync || mode == LightSync { 1734 assertOwnChain(t, tester, 1) 1735 } else { 1736 assertOwnChain(t, tester, chain.len()) 1737 } 1738 }