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