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