github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/eth/downloader/downloader.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 contains the manual full chain synchronisation. 18 package downloader 19 20 import ( 21 "crypto/rand" 22 "errors" 23 "fmt" 24 "math" 25 "math/big" 26 "sync" 27 "sync/atomic" 28 "time" 29 30 ethereum "github.com/ethereum/go-ethereum" 31 "github.com/ethereum/go-ethereum/common" 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/log" 36 "github.com/ethereum/go-ethereum/params" 37 "github.com/ethereum/go-ethereum/trie" 38 "github.com/rcrowley/go-metrics" 39 ) 40 41 var ( 42 MaxHashFetch = 512 // Amount of hashes to be fetched per retrieval request 43 MaxBlockFetch = 128 // Amount of blocks to be fetched per retrieval request 44 MaxHeaderFetch = 192 // Amount of block headers to be fetched per retrieval request 45 MaxSkeletonSize = 128 // Number of header fetches to need for a skeleton assembly 46 MaxBodyFetch = 128 // Amount of block bodies to be fetched per retrieval request 47 MaxReceiptFetch = 256 // Amount of transaction receipts to allow fetching per request 48 MaxStateFetch = 384 // Amount of node state values to allow fetching per request 49 50 MaxForkAncestry = 3 * params.EpochDuration // Maximum chain reorganisation 51 rttMinEstimate = 2 * time.Second // Minimum round-trip time to target for download requests 52 rttMaxEstimate = 20 * time.Second // Maximum rount-trip time to target for download requests 53 rttMinConfidence = 0.1 // Worse confidence factor in our estimated RTT value 54 ttlScaling = 3 // Constant scaling factor for RTT -> TTL conversion 55 ttlLimit = time.Minute // Maximum TTL allowance to prevent reaching crazy timeouts 56 57 qosTuningPeers = 5 // Number of peers to tune based on (best peers) 58 qosConfidenceCap = 10 // Number of peers above which not to modify RTT confidence 59 qosTuningImpact = 0.25 // Impact that a new tuning target has on the previous value 60 61 maxQueuedHeaders = 32 * 1024 // [eth/62] Maximum number of headers to queue for import (DOS protection) 62 maxHeadersProcess = 2048 // Number of header download results to import at once into the chain 63 maxResultsProcess = 2048 // Number of content download results to import at once into the chain 64 65 fsHeaderCheckFrequency = 100 // Verification frequency of the downloaded headers during fast sync 66 fsHeaderSafetyNet = 2048 // Number of headers to discard in case a chain violation is detected 67 fsHeaderForceVerify = 24 // Number of headers to verify before and after the pivot to accept it 68 fsPivotInterval = 256 // Number of headers out of which to randomize the pivot point 69 fsMinFullBlocks = 64 // Number of blocks to retrieve fully even in fast sync 70 fsCriticalTrials = uint32(32) // Number of times to retry in the cricical section before bailing 71 ) 72 73 var ( 74 errBusy = errors.New("busy") 75 errUnknownPeer = errors.New("peer is unknown or unhealthy") 76 errBadPeer = errors.New("action from bad peer ignored") 77 errStallingPeer = errors.New("peer is stalling") 78 errNoPeers = errors.New("no peers to keep download active") 79 errTimeout = errors.New("timeout") 80 errEmptyHeaderSet = errors.New("empty header set by peer") 81 errPeersUnavailable = errors.New("no peers available or all tried for download") 82 errInvalidAncestor = errors.New("retrieved ancestor is invalid") 83 errInvalidChain = errors.New("retrieved hash chain is invalid") 84 errInvalidBlock = errors.New("retrieved block is invalid") 85 errInvalidBody = errors.New("retrieved block body is invalid") 86 errInvalidReceipt = errors.New("retrieved receipt is invalid") 87 errCancelBlockFetch = errors.New("block download canceled (requested)") 88 errCancelHeaderFetch = errors.New("block header download canceled (requested)") 89 errCancelBodyFetch = errors.New("block body download canceled (requested)") 90 errCancelReceiptFetch = errors.New("receipt download canceled (requested)") 91 errCancelStateFetch = errors.New("state data download canceled (requested)") 92 errCancelHeaderProcessing = errors.New("header processing canceled (requested)") 93 errCancelContentProcessing = errors.New("content processing canceled (requested)") 94 errNoSyncActive = errors.New("no sync active") 95 errTooOld = errors.New("peer doesn't speak recent enough protocol version (need version >= 62)") //error in adding as external validators. 96 ) 97 98 type Downloader struct { 99 mode SyncMode // Synchronisation mode defining the strategy used (per sync cycle) 100 mux *event.TypeMux // Event multiplexer to announce sync operation events 101 102 queue *queue // Scheduler for selecting the hashes to download 103 peers *peerSet // Set of active peers from which download can proceed 104 105 fsPivotLock *types.Header // Pivot header on critical section entry (cannot change between retries) 106 fsPivotFails uint32 // Number of subsequent fast sync failures in the critical section 107 108 rttEstimate uint64 // Round trip time to target for download requests 109 rttConfidence uint64 // Confidence in the estimated RTT (unit: millionths to allow atomic ops) 110 111 // Statistics 112 syncStatsChainOrigin uint64 // Origin block number where syncing started at 113 syncStatsChainHeight uint64 // Highest block number known when syncing started 114 syncStatsStateDone uint64 // Number of state trie entries already pulled 115 syncStatsLock sync.RWMutex // Lock protecting the sync stats fields 116 117 // Callbacks 118 hasHeader headerCheckFn // Checks if a header is present in the chain 119 hasBlockAndState blockAndStateCheckFn // Checks if a block and associated state is present in the chain 120 getHeader headerRetrievalFn // Retrieves a header from the chain 121 getBlock blockRetrievalFn // Retrieves a block from the chain 122 headHeader headHeaderRetrievalFn // Retrieves the head header from the chain 123 headBlock headBlockRetrievalFn // Retrieves the head block from the chain 124 headFastBlock headFastBlockRetrievalFn // Retrieves the head fast-sync block from the chain 125 commitHeadBlock headBlockCommitterFn // Commits a manually assembled block as the chain head 126 getTd tdRetrievalFn // Retrieves the TD of a block from the chain 127 insertHeaders headerChainInsertFn // Injects a batch of headers into the chain 128 insertBlocks blockChainInsertFn // Injects a batch of blocks into the chain 129 insertReceipts receiptChainInsertFn // Injects a batch of blocks and their receipts into the chain 130 rollback chainRollbackFn // Removes a batch of recently added chain links 131 dropPeer peerDropFn // Drops a peer for misbehaving 132 133 // Status 134 synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing 135 synchronising int32 136 notified int32 137 138 // Channels 139 newPeerCh chan *peer 140 headerCh chan dataPack // [eth/62] Channel receiving inbound block headers 141 bodyCh chan dataPack // [eth/62] Channel receiving inbound block bodies 142 receiptCh chan dataPack // [eth/63] Channel receiving inbound receipts 143 stateCh chan dataPack // [eth/63] Channel receiving inbound node state data 144 bodyWakeCh chan bool // [eth/62] Channel to signal the block body fetcher of new tasks 145 receiptWakeCh chan bool // [eth/63] Channel to signal the receipt fetcher of new tasks 146 stateWakeCh chan bool // [eth/63] Channel to signal the state fetcher of new tasks 147 headerProcCh chan []*types.Header // [eth/62] Channel to feed the header processor new tasks 148 149 // Cancellation and termination 150 cancelPeer string // Identifier of the peer currently being used as the master (cancel on drop) 151 cancelCh chan struct{} // Channel to cancel mid-flight syncs 152 cancelLock sync.RWMutex // Lock to protect the cancel channel and peer in delivers 153 154 quitCh chan struct{} // Quit channel to signal termination 155 quitLock sync.RWMutex // Lock to prevent double closes 156 157 // Testing hooks 158 syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run 159 bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch 160 receiptFetchHook func([]*types.Header) // Method to call upon starting a receipt fetch 161 chainInsertHook func([]*fetchResult) // Method to call upon inserting a chain of blocks (possibly in multiple invocations) 162 } 163 164 // New creates a new downloader to fetch hashes and blocks from remote peers. 165 func New(mode SyncMode, stateDb ethdb.Database, mux *event.TypeMux, hasHeader headerCheckFn, hasBlockAndState blockAndStateCheckFn, 166 getHeader headerRetrievalFn, getBlock blockRetrievalFn, headHeader headHeaderRetrievalFn, headBlock headBlockRetrievalFn, 167 headFastBlock headFastBlockRetrievalFn, commitHeadBlock headBlockCommitterFn, getTd tdRetrievalFn, insertHeaders headerChainInsertFn, 168 insertBlocks blockChainInsertFn, insertReceipts receiptChainInsertFn, rollback chainRollbackFn, dropPeer peerDropFn) *Downloader { 169 170 dl := &Downloader{ 171 mode: mode, 172 mux: mux, 173 queue: newQueue(stateDb), 174 peers: newPeerSet(), 175 rttEstimate: uint64(rttMaxEstimate), 176 rttConfidence: uint64(1000000), 177 hasHeader: hasHeader, 178 hasBlockAndState: hasBlockAndState, 179 getHeader: getHeader, 180 getBlock: getBlock, 181 headHeader: headHeader, 182 headBlock: headBlock, 183 headFastBlock: headFastBlock, 184 commitHeadBlock: commitHeadBlock, 185 getTd: getTd, 186 insertHeaders: insertHeaders, 187 insertBlocks: insertBlocks, 188 insertReceipts: insertReceipts, 189 rollback: rollback, 190 dropPeer: dropPeer, 191 newPeerCh: make(chan *peer, 1), 192 headerCh: make(chan dataPack, 1), 193 bodyCh: make(chan dataPack, 1), 194 receiptCh: make(chan dataPack, 1), 195 stateCh: make(chan dataPack, 1), 196 bodyWakeCh: make(chan bool, 1), 197 receiptWakeCh: make(chan bool, 1), 198 stateWakeCh: make(chan bool, 1), 199 headerProcCh: make(chan []*types.Header, 1), 200 quitCh: make(chan struct{}), 201 } 202 go dl.qosTuner() 203 return dl 204 } 205 206 // Progress retrieves the synchronisation boundaries, specifically the origin 207 // block where synchronisation started at (may have failed/suspended); the block 208 // or header sync is currently at; and the latest known block which the sync targets. 209 // 210 // In addition, during the state download phase of fast synchronisation the number 211 // of processed and the total number of known states are also returned. Otherwise 212 // these are zero. 213 func (d *Downloader) Progress() ethereum.SyncProgress { 214 // Fetch the pending state count outside of the lock to prevent unforeseen deadlocks 215 pendingStates := uint64(d.queue.PendingNodeData()) 216 217 // Lock the current stats and return the progress 218 d.syncStatsLock.RLock() 219 defer d.syncStatsLock.RUnlock() 220 221 current := uint64(0) 222 switch d.mode { 223 case FullSync: 224 current = d.headBlock().NumberU64() 225 case FastSync: 226 current = d.headFastBlock().NumberU64() 227 case LightSync: 228 current = d.headHeader().Number.Uint64() 229 } 230 return ethereum.SyncProgress{ 231 StartingBlock: d.syncStatsChainOrigin, 232 CurrentBlock: current, 233 HighestBlock: d.syncStatsChainHeight, 234 PulledStates: d.syncStatsStateDone, 235 KnownStates: d.syncStatsStateDone + pendingStates, 236 } 237 } 238 239 // Synchronising returns whether the downloader is currently retrieving blocks. 240 func (d *Downloader) Synchronising() bool { 241 return atomic.LoadInt32(&d.synchronising) > 0 242 } 243 244 // RegisterPeer injects a new download peer into the set of block source to be 245 // used for fetching hashes and blocks from. 246 func (d *Downloader) RegisterPeer(id string, version int, currentHead currentHeadRetrievalFn, 247 getRelHeaders relativeHeaderFetcherFn, getAbsHeaders absoluteHeaderFetcherFn, getBlockBodies blockBodyFetcherFn, 248 getReceipts receiptFetcherFn, getNodeData stateFetcherFn) error { 249 250 logger := log.New("peer", id) 251 logger.Trace("Registering sync peer") 252 if err := d.peers.Register(newPeer(id, version, currentHead, getRelHeaders, getAbsHeaders, getBlockBodies, getReceipts, getNodeData, logger)); err != nil { 253 logger.Error("Failed to register sync peer", "err", err) 254 return err 255 } 256 d.qosReduceConfidence() 257 258 return nil 259 } 260 261 // UnregisterPeer remove a peer from the known list, preventing any action from 262 // the specified peer. An effort is also made to return any pending fetches into 263 // the queue. 264 func (d *Downloader) UnregisterPeer(id string) error { 265 // Unregister the peer from the active peer set and revoke any fetch tasks 266 logger := log.New("peer", id) 267 logger.Trace("Unregistering sync peer") 268 if err := d.peers.Unregister(id); err != nil { 269 logger.Error("Failed to unregister sync peer", "err", err) 270 return err 271 } 272 d.queue.Revoke(id) 273 274 // If this peer was the master peer, abort sync immediately 275 d.cancelLock.RLock() 276 master := id == d.cancelPeer 277 d.cancelLock.RUnlock() 278 279 if master { 280 d.Cancel() 281 } 282 return nil 283 } 284 285 // Synchronise tries to sync up our local block chain with a remote peer, both 286 // adding various sanity checks as well as wrapping it with various log entries. 287 func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) error { 288 err := d.synchronise(id, head, td, mode) 289 switch err { 290 case nil: 291 case errBusy: 292 293 case errTimeout, errBadPeer, errStallingPeer, 294 errEmptyHeaderSet, errPeersUnavailable, errTooOld, //? 295 errInvalidAncestor, errInvalidChain: 296 log.Warn("Synchronisation failed, dropping peer", "peer", id, "err", err) 297 d.dropPeer(id) 298 299 default: 300 log.Warn("Synchronisation failed, retrying", "err", err) 301 } 302 return err 303 } 304 305 // synchronise will select the peer and use it for synchronising. If an empty string is given 306 // it will use the best peer possible and synchronize if it's TD is higher than our own. If any of the 307 // checks fail an error will be returned. This method is synchronous 308 func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode SyncMode) error { 309 // Mock out the synchronisation if testing 310 if d.synchroniseMock != nil { 311 return d.synchroniseMock(id, hash) 312 } 313 // Make sure only one goroutine is ever allowed past this point at once 314 if !atomic.CompareAndSwapInt32(&d.synchronising, 0, 1) { 315 return errBusy 316 } 317 defer atomic.StoreInt32(&d.synchronising, 0) 318 319 // Post a user notification of the sync (only once per session) 320 if atomic.CompareAndSwapInt32(&d.notified, 0, 1) { 321 log.Info("Block synchronisation started") 322 } 323 // Reset the queue, peer set and wake channels to clean any internal leftover state 324 d.queue.Reset() 325 d.peers.Reset() 326 327 for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh, d.stateWakeCh} { 328 select { 329 case <-ch: 330 default: 331 } 332 } 333 for _, ch := range []chan dataPack{d.headerCh, d.bodyCh, d.receiptCh, d.stateCh} { 334 for empty := false; !empty; { 335 select { 336 case <-ch: 337 default: 338 empty = true 339 } 340 } 341 } 342 for empty := false; !empty; { 343 select { 344 case <-d.headerProcCh: 345 default: 346 empty = true 347 } 348 } 349 // Create cancel channel for aborting mid-flight and mark the master peer 350 d.cancelLock.Lock() 351 d.cancelCh = make(chan struct{}) 352 d.cancelPeer = id 353 d.cancelLock.Unlock() 354 355 defer d.Cancel() // No matter what, we can't leave the cancel channel open 356 357 // Set the requested sync mode, unless it's forbidden 358 d.mode = mode 359 if d.mode == FastSync && atomic.LoadUint32(&d.fsPivotFails) >= fsCriticalTrials { 360 d.mode = FullSync 361 } 362 // Retrieve the origin peer and initiate the downloading process 363 p := d.peers.Peer(id) 364 if p == nil { 365 return errUnknownPeer 366 } 367 return d.syncWithPeer(p, hash, td) 368 } 369 370 // syncWithPeer starts a block synchronization based on the hash chain from the 371 // specified peer and head hash. 372 func (d *Downloader) syncWithPeer(p *peer, hash common.Hash, td *big.Int) (err error) { 373 d.mux.Post(StartEvent{}) 374 defer func() { 375 // reset on error 376 if err != nil { 377 d.mux.Post(FailedEvent{err}) 378 } else { 379 d.mux.Post(DoneEvent{}) 380 } 381 }() 382 383 384 // Skip protocol version if incompatible with the mode of operation 385 /* if mode == downloader.FastSync && version < eth63 { 386 continue 387 } */ 388 log.Info("peer protocol.version =", "p.version", p.version ) //yichoi 389 if p.version < 62 { // protocol version check, if < 62 , then err Too Old version return, 390 log.Info("peer protocol.version =", "p.version", p.version ) //yichoi 391 return errTooOld 392 //continue // added by yichoi temporarly 393 } 394 395 396 log.Debug("1.Synchronising with the network", "peer", p.id, "eth", p.version, "head", hash, "td", td, "mode", d.mode) 397 defer func(start time.Time) { 398 log.Debug("Synchronisation terminated", "elapsed", time.Since(start)) 399 }(time.Now()) 400 401 // Look up the sync boundaries: the common ancestor and the target block 402 latest, err := d.fetchHeight(p) 403 if err != nil { 404 return err 405 } 406 height := latest.Number.Uint64() 407 408 origin, err := d.findAncestor(p, height) 409 if err != nil { 410 return err 411 } 412 d.syncStatsLock.Lock() 413 if d.syncStatsChainHeight <= origin || d.syncStatsChainOrigin > origin { 414 d.syncStatsChainOrigin = origin 415 } 416 d.syncStatsChainHeight = height 417 d.syncStatsLock.Unlock() 418 419 // Initiate the sync using a concurrent header and content retrieval algorithm 420 pivot := uint64(0) 421 switch d.mode { 422 case LightSync: 423 pivot = height 424 case FastSync: 425 // Calculate the new fast/slow sync pivot point 426 if d.fsPivotLock == nil { 427 pivotOffset, err := rand.Int(rand.Reader, big.NewInt(int64(fsPivotInterval))) 428 if err != nil { 429 panic(fmt.Sprintf("Failed to access crypto random source: %v", err)) 430 } 431 if height > uint64(fsMinFullBlocks)+pivotOffset.Uint64() { 432 pivot = height - uint64(fsMinFullBlocks) - pivotOffset.Uint64() 433 } 434 } else { 435 // Pivot point locked in, use this and do not pick a new one! 436 pivot = d.fsPivotLock.Number.Uint64() 437 } 438 // If the point is below the origin, move origin back to ensure state download 439 if pivot < origin { 440 if pivot > 0 { 441 origin = pivot - 1 442 } else { 443 origin = 0 444 } 445 } 446 log.Debug("Fast syncing until pivot block", "pivot", pivot) 447 } 448 d.queue.Prepare(origin+1, d.mode, pivot, latest) 449 if d.syncInitHook != nil { 450 d.syncInitHook(origin, height) 451 } 452 return d.spawnSync(origin+1, 453 func() error { return d.fetchHeaders(p, origin+1) }, // Headers are always retrieved 454 func() error { return d.processHeaders(origin+1, td) }, // Headers are always retrieved 455 func() error { return d.fetchBodies(origin + 1) }, // Bodies are retrieved during normal and fast sync 456 func() error { return d.fetchReceipts(origin + 1) }, // Receipts are retrieved during fast sync 457 func() error { return d.fetchNodeData() }, // Node state data is retrieved during fast sync 458 ) 459 } 460 461 // spawnSync runs d.process and all given fetcher functions to completion in 462 // separate goroutines, returning the first error that appears. 463 func (d *Downloader) spawnSync(origin uint64, fetchers ...func() error) error { 464 var wg sync.WaitGroup 465 errc := make(chan error, len(fetchers)+1) 466 wg.Add(len(fetchers) + 1) 467 go func() { defer wg.Done(); errc <- d.processContent() }() 468 for _, fn := range fetchers { 469 fn := fn 470 go func() { defer wg.Done(); errc <- fn() }() 471 } 472 // Wait for the first error, then terminate the others. 473 var err error 474 for i := 0; i < len(fetchers)+1; i++ { 475 if i == len(fetchers) { 476 // Close the queue when all fetchers have exited. 477 // This will cause the block processor to end when 478 // it has processed the queue. 479 d.queue.Close() 480 } 481 if err = <-errc; err != nil { 482 break 483 } 484 } 485 d.queue.Close() 486 d.Cancel() 487 wg.Wait() 488 489 // If sync failed in the critical section, bump the fail counter 490 if err != nil && d.mode == FastSync && d.fsPivotLock != nil { 491 atomic.AddUint32(&d.fsPivotFails, 1) 492 } 493 return err 494 } 495 496 // Cancel cancels all of the operations and resets the queue. It returns true 497 // if the cancel operation was completed. 498 func (d *Downloader) Cancel() { 499 // Close the current cancel channel 500 d.cancelLock.Lock() 501 if d.cancelCh != nil { 502 select { 503 case <-d.cancelCh: 504 // Channel was already closed 505 default: 506 close(d.cancelCh) 507 } 508 } 509 d.cancelLock.Unlock() 510 } 511 512 // Terminate interrupts the downloader, canceling all pending operations. 513 // The downloader cannot be reused after calling Terminate. 514 func (d *Downloader) Terminate() { 515 // Close the termination channel (make sure double close is allowed) 516 d.quitLock.Lock() 517 select { 518 case <-d.quitCh: 519 default: 520 close(d.quitCh) 521 } 522 d.quitLock.Unlock() 523 524 // Cancel any pending download requests 525 d.Cancel() 526 } 527 528 // fetchHeight retrieves the head header of the remote peer to aid in estimating 529 // the total time a pending synchronisation would take. 530 func (d *Downloader) fetchHeight(p *peer) (*types.Header, error) { 531 p.log.Debug("2.Retrieving remote chain height") 532 533 // Request the advertised remote head block and wait for the response 534 head, _ := p.currentHead() 535 go p.getRelHeaders(head, 1, 0, false) 536 537 ttl := d.requestTTL() 538 timeout := time.After(ttl) 539 for { 540 select { 541 case <-d.cancelCh: 542 return nil, errCancelBlockFetch 543 544 case packet := <-d.headerCh: 545 // Discard anything not from the origin peer 546 if packet.PeerId() != p.id { 547 log.Debug("Received headers from incorrect peer", "peer", packet.PeerId()) 548 break 549 } 550 // Make sure the peer actually gave something valid 551 headers := packet.(*headerPack).headers 552 if len(headers) != 1 { 553 p.log.Debug("Multiple headers for single request", "headers", len(headers)) 554 return nil, errBadPeer 555 } 556 head := headers[0] 557 p.log.Debug("4.Remote head header identified", "number", head.Number, "hash", head.Hash()) 558 return head, nil 559 560 case <-timeout: 561 p.log.Debug("Waiting for head header timed out", "elapsed", ttl) 562 return nil, errTimeout 563 564 case <-d.bodyCh: 565 case <-d.stateCh: 566 case <-d.receiptCh: 567 // Out of bounds delivery, ignore 568 } 569 } 570 } 571 572 // findAncestor tries to locate the common ancestor link of the local chain and 573 // a remote peers blockchain. In the general case when our node was in sync and 574 // on the correct chain, checking the top N links should already get us a match. 575 // In the rare scenario when we ended up on a long reorganisation (i.e. none of 576 // the head links match), we do a binary search to find the common ancestor. 577 func (d *Downloader) findAncestor(p *peer, height uint64) (uint64, error) { 578 // Figure out the valid ancestor range to prevent rewrite attacks 579 floor, ceil := int64(-1), d.headHeader().Number.Uint64() 580 581 p.log.Debug("5.Looking for common ancestor", "local", ceil, "remote", height, "floor", floor) 582 if d.mode == FullSync { 583 ceil = d.headBlock().NumberU64() 584 p.log.Debug("5-1. FullSync", "local", ceil, "remote", height) 585 } else if d.mode == FastSync { 586 ceil = d.headFastBlock().NumberU64() 587 } 588 if ceil >= MaxForkAncestry { 589 floor = int64(ceil - MaxForkAncestry) 590 } 591 // Request the topmost blocks to short circuit binary ancestor lookup 592 head := ceil 593 if head > height { 594 head = height 595 } 596 from := int64(head) - int64(MaxHeaderFetch) 597 if from < 0 { 598 from = 0 599 } 600 // Span out with 15 block gaps into the future to catch bad head reports 601 limit := 2 * MaxHeaderFetch / 16 602 count := 1 + int((int64(ceil)-from)/16) 603 if count > limit { 604 count = limit 605 } 606 go p.getAbsHeaders(uint64(from), count, 15, false) 607 608 // Wait for the remote response to the head fetch 609 number, hash := uint64(0), common.Hash{} 610 611 ttl := d.requestTTL() 612 timeout := time.After(ttl) 613 614 for finished := false; !finished; { 615 select { 616 case <-d.cancelCh: 617 return 0, errCancelHeaderFetch 618 619 case packet := <-d.headerCh: 620 // Discard anything not from the origin peer 621 if packet.PeerId() != p.id { 622 log.Debug("Received headers from incorrect peer", "peer", packet.PeerId()) 623 break 624 } 625 // Make sure the peer actually gave something valid 626 headers := packet.(*headerPack).headers 627 if len(headers) == 0 { 628 p.log.Warn("Empty head header set") 629 return 0, errEmptyHeaderSet 630 } 631 // Make sure the peer's reply conforms to the request 632 for i := 0; i < len(headers); i++ { 633 if number := headers[i].Number.Int64(); number != from+int64(i)*16 { 634 p.log.Warn("Head headers broke chain ordering", "index", i, "requested", from+int64(i)*16, "received", number) 635 return 0, errInvalidChain 636 } 637 } 638 // Check if a common ancestor was found 639 finished = true 640 for i := len(headers) - 1; i >= 0; i-- { 641 // Skip any headers that underflow/overflow our requested set 642 if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > ceil { 643 continue 644 } 645 // Otherwise check if we already know the header or not 646 if (d.mode == FullSync && d.hasBlockAndState(headers[i].Hash())) || (d.mode != FullSync && d.hasHeader(headers[i].Hash())) { 647 number, hash = headers[i].Number.Uint64(), headers[i].Hash() 648 649 // If every header is known, even future ones, the peer straight out lied about its head 650 if number > height && i == limit-1 { 651 p.log.Warn("Lied about chain head", "reported", height, "found", number) 652 return 0, errStallingPeer 653 } 654 break 655 } 656 } 657 658 case <-timeout: 659 p.log.Debug("Waiting for head header timed out", "elapsed", ttl) 660 return 0, errTimeout 661 662 case <-d.bodyCh: 663 case <-d.stateCh: 664 case <-d.receiptCh: 665 // Out of bounds delivery, ignore 666 } 667 } 668 // If the head fetch already found an ancestor, return 669 if !common.EmptyHash(hash) { 670 if int64(number) <= floor { 671 p.log.Warn("Ancestor below allowance", "number", number, "hash", hash, "allowance", floor) 672 return 0, errInvalidAncestor 673 } 674 p.log.Debug("6.Found common ancestor", "number", number, "hash", hash) 675 return number, nil 676 } 677 // Ancestor not found, we need to binary search over our chain 678 start, end := uint64(0), head 679 if floor > 0 { 680 start = uint64(floor) 681 } 682 for start+1 < end { 683 // Split our chain interval in two, and request the hash to cross check 684 check := (start + end) / 2 685 686 ttl := d.requestTTL() 687 timeout := time.After(ttl) 688 689 go p.getAbsHeaders(uint64(check), 1, 0, false) 690 691 // Wait until a reply arrives to this request 692 for arrived := false; !arrived; { 693 select { 694 case <-d.cancelCh: 695 return 0, errCancelHeaderFetch 696 697 case packer := <-d.headerCh: 698 // Discard anything not from the origin peer 699 if packer.PeerId() != p.id { 700 log.Debug("Received headers from incorrect peer", "peer", packer.PeerId()) 701 break 702 } 703 // Make sure the peer actually gave something valid 704 headers := packer.(*headerPack).headers 705 if len(headers) != 1 { 706 p.log.Debug("Multiple headers for single request", "headers", len(headers)) 707 return 0, errBadPeer 708 } 709 arrived = true 710 711 // Modify the search interval based on the response 712 if (d.mode == FullSync && !d.hasBlockAndState(headers[0].Hash())) || (d.mode != FullSync && !d.hasHeader(headers[0].Hash())) { 713 end = check 714 break 715 } 716 header := d.getHeader(headers[0].Hash()) // Independent of sync mode, header surely exists 717 if header.Number.Uint64() != check { 718 p.log.Debug("Received non requested header", "number", header.Number, "hash", header.Hash(), "request", check) 719 return 0, errBadPeer 720 } 721 start = check 722 723 case <-timeout: 724 p.log.Debug("Waiting for search header timed out", "elapsed", ttl) 725 return 0, errTimeout 726 727 case <-d.bodyCh: 728 case <-d.stateCh: 729 case <-d.receiptCh: 730 // Out of bounds delivery, ignore 731 } 732 } 733 } 734 // Ensure valid ancestry and return 735 if int64(start) <= floor { 736 p.log.Warn("Ancestor below allowance", "number", start, "hash", hash, "allowance", floor) 737 return 0, errInvalidAncestor 738 } 739 p.log.Debug("6.Found common ancestor", "number", start, "hash", hash, "floor", floor) 740 return start, nil 741 } 742 743 // fetchHeaders keeps retrieving headers concurrently from the number 744 // requested, until no more are returned, potentially throttling on the way. To 745 // facilitate concurrency but still protect against malicious nodes sending bad 746 // headers, we construct a header chain skeleton using the "origin" peer we are 747 // syncing with, and fill in the missing headers using anyone else. Headers from 748 // other peers are only accepted if they map cleanly to the skeleton. If no one 749 // can fill in the skeleton - not even the origin peer - it's assumed invalid and 750 // the origin is dropped. 751 //// fetchHeaders는 더 이상 반환되지 않을 때까지 요청 된 수에서 동시에 헤더를 검색하여 잠재적으로 제한됩니다. 752 //동시성을 촉진하면서도 잘못된 헤더를 보내는 악의적 인 노드로부터 보호하기 위해 동기화하는 "origin"피어를 사용하여 헤더 체인 스켈레톤을 753 //구성하고 다른 사람을 사용하여 누락 된 헤더를 채 웁니다. 다른 피어의 헤더는 스켈레톤에 깔끔하게 매핑 된 경우에만 허용됩니다. 754 // 원점 피어조차도 골격을 채울 수있는 사람이 없으면 유효하지 않은 것으로 가정하고 원점이 삭제됩니다. 755 func (d *Downloader) fetchHeaders(p *peer, from uint64) error { 756 p.log.Debug("Directing header downloads", "origin", from) 757 defer p.log.Debug("Header download terminated") 758 759 // Create a timeout timer, and the associated header fetcher 760 skeleton := true // Skeleton assembly phase or finishing up 761 request := time.Now() // time of the last skeleton fetch request 762 timeout := time.NewTimer(0) // timer to dump a non-responsive active peer 763 <-timeout.C // timeout channel should be initially empty 764 defer timeout.Stop() 765 766 var ttl time.Duration 767 getHeaders := func(from uint64) { 768 request = time.Now() 769 770 ttl = d.requestTTL() 771 timeout.Reset(ttl) 772 773 if skeleton { 774 p.log.Trace("Fetching skeleton headers", "count", MaxHeaderFetch, "from", from) 775 go p.getAbsHeaders(from+uint64(MaxHeaderFetch)-1, MaxSkeletonSize, MaxHeaderFetch-1, false) 776 } else { 777 p.log.Trace("Fetching full headers", "count", MaxHeaderFetch, "from", from) 778 go p.getAbsHeaders(from, MaxHeaderFetch, 0, false) 779 } 780 } 781 // Start pulling the header chain skeleton until all is done 782 getHeaders(from) 783 784 for { 785 select { 786 case <-d.cancelCh: 787 return errCancelHeaderFetch 788 789 case packet := <-d.headerCh: 790 // Make sure the active peer is giving us the skeleton headers 791 if packet.PeerId() != p.id { 792 log.Debug("Received skeleton from incorrect peer", "peer", packet.PeerId()) 793 break 794 } 795 headerReqTimer.UpdateSince(request) 796 timeout.Stop() 797 798 // If the skeleton's finished, pull any remaining head headers directly from the origin 799 if packet.Items() == 0 && skeleton { 800 skeleton = false 801 getHeaders(from) 802 continue 803 } 804 // If no more headers are inbound, notify the content fetchers and return 805 if packet.Items() == 0 { 806 p.log.Debug("No more headers available") 807 select { 808 case d.headerProcCh <- nil: 809 return nil 810 case <-d.cancelCh: 811 return errCancelHeaderFetch 812 } 813 } 814 headers := packet.(*headerPack).headers 815 816 // If we received a skeleton batch, resolve internals concurrently 817 if skeleton { 818 filled, proced, err := d.fillHeaderSkeleton(from, headers) 819 if err != nil { 820 p.log.Debug("Skeleton chain invalid", "err", err) 821 return errInvalidChain 822 } 823 headers = filled[proced:] 824 from += uint64(proced) 825 } 826 // Insert all the new headers and fetch the next batch 827 if len(headers) > 0 { 828 p.log.Trace("Scheduling new headers", "count", len(headers), "from", from) 829 select { 830 case d.headerProcCh <- headers: 831 case <-d.cancelCh: 832 return errCancelHeaderFetch 833 } 834 from += uint64(len(headers)) 835 } 836 getHeaders(from) 837 838 case <-timeout.C: 839 // Header retrieval timed out, consider the peer bad and drop 840 p.log.Debug("Header request timed out", "elapsed", ttl) 841 headerTimeoutMeter.Mark(1) 842 d.dropPeer(p.id) 843 844 // Finish the sync gracefully instead of dumping the gathered data though 845 for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh, d.stateWakeCh} { 846 select { 847 case ch <- false: 848 case <-d.cancelCh: 849 } 850 } 851 select { 852 case d.headerProcCh <- nil: 853 case <-d.cancelCh: 854 } 855 return errBadPeer 856 } 857 } 858 } 859 860 // fillHeaderSkeleton concurrently retrieves headers from all our available peers 861 // and maps them to the provided skeleton header chain. 862 // 863 // Any partial results from the beginning of the skeleton is (if possible) forwarded 864 // immediately to the header processor to keep the rest of the pipeline full even 865 // in the case of header stalls. 866 // 867 // The method returs the entire filled skeleton and also the number of headers 868 // already forwarded for processing. 869 func (d *Downloader) fillHeaderSkeleton(from uint64, skeleton []*types.Header) ([]*types.Header, int, error) { 870 log.Debug("Filling up skeleton", "from", from) 871 d.queue.ScheduleSkeleton(from, skeleton) 872 873 var ( 874 deliver = func(packet dataPack) (int, error) { 875 pack := packet.(*headerPack) 876 return d.queue.DeliverHeaders(pack.peerId, pack.headers, d.headerProcCh) 877 } 878 expire = func() map[string]int { return d.queue.ExpireHeaders(d.requestTTL()) } 879 throttle = func() bool { return false } 880 reserve = func(p *peer, count int) (*fetchRequest, bool, error) { 881 return d.queue.ReserveHeaders(p, count), false, nil 882 } 883 fetch = func(p *peer, req *fetchRequest) error { return p.FetchHeaders(req.From, MaxHeaderFetch) } 884 capacity = func(p *peer) int { return p.HeaderCapacity(d.requestRTT()) } 885 setIdle = func(p *peer, accepted int) { p.SetHeadersIdle(accepted) } 886 ) 887 err := d.fetchParts(errCancelHeaderFetch, d.headerCh, deliver, d.queue.headerContCh, expire, 888 d.queue.PendingHeaders, d.queue.InFlightHeaders, throttle, reserve, 889 nil, fetch, d.queue.CancelHeaders, capacity, d.peers.HeaderIdlePeers, setIdle, "headers") 890 891 log.Debug("Skeleton fill terminated", "err", err) 892 893 filled, proced := d.queue.RetrieveHeaders() 894 return filled, proced, err 895 } 896 897 // fetchBodies iteratively downloads the scheduled block bodies, taking any 898 // available peers, reserving a chunk of blocks for each, waiting for delivery 899 // and also periodically checking for timeouts. 900 func (d *Downloader) fetchBodies(from uint64) error { 901 log.Debug("Downloading block bodies", "origin", from) 902 903 var ( 904 deliver = func(packet dataPack) (int, error) { 905 pack := packet.(*bodyPack) 906 return d.queue.DeliverBodies(pack.peerId, pack.transactions, pack.uncles) 907 } 908 expire = func() map[string]int { return d.queue.ExpireBodies(d.requestTTL()) } 909 fetch = func(p *peer, req *fetchRequest) error { return p.FetchBodies(req) } 910 capacity = func(p *peer) int { return p.BlockCapacity(d.requestRTT()) } 911 setIdle = func(p *peer, accepted int) { p.SetBodiesIdle(accepted) } 912 ) 913 err := d.fetchParts(errCancelBodyFetch, d.bodyCh, deliver, d.bodyWakeCh, expire, 914 d.queue.PendingBlocks, d.queue.InFlightBlocks, d.queue.ShouldThrottleBlocks, d.queue.ReserveBodies, 915 d.bodyFetchHook, fetch, d.queue.CancelBodies, capacity, d.peers.BodyIdlePeers, setIdle, "bodies") 916 917 log.Debug("Block body download terminated", "err", err) 918 return err 919 } 920 921 // fetchReceipts iteratively downloads the scheduled block receipts, taking any 922 // available peers, reserving a chunk of receipts for each, waiting for delivery 923 // and also periodically checking for timeouts. 924 func (d *Downloader) fetchReceipts(from uint64) error { 925 log.Debug("Downloading transaction receipts", "origin", from) 926 927 var ( 928 deliver = func(packet dataPack) (int, error) { 929 pack := packet.(*receiptPack) 930 return d.queue.DeliverReceipts(pack.peerId, pack.receipts) 931 } 932 expire = func() map[string]int { return d.queue.ExpireReceipts(d.requestTTL()) } 933 fetch = func(p *peer, req *fetchRequest) error { return p.FetchReceipts(req) } 934 capacity = func(p *peer) int { return p.ReceiptCapacity(d.requestRTT()) } 935 setIdle = func(p *peer, accepted int) { p.SetReceiptsIdle(accepted) } 936 ) 937 err := d.fetchParts(errCancelReceiptFetch, d.receiptCh, deliver, d.receiptWakeCh, expire, 938 d.queue.PendingReceipts, d.queue.InFlightReceipts, d.queue.ShouldThrottleReceipts, d.queue.ReserveReceipts, 939 d.receiptFetchHook, fetch, d.queue.CancelReceipts, capacity, d.peers.ReceiptIdlePeers, setIdle, "receipts") 940 941 log.Debug("Transaction receipt download terminated", "err", err) 942 return err 943 } 944 945 // fetchNodeData iteratively downloads the scheduled state trie nodes, taking any 946 // available peers, reserving a chunk of nodes for each, waiting for delivery and 947 // also periodically checking for timeouts. 948 func (d *Downloader) fetchNodeData() error { 949 log.Debug("Downloading node state data") 950 951 var ( 952 deliver = func(packet dataPack) (int, error) { 953 start := time.Now() 954 return d.queue.DeliverNodeData(packet.PeerId(), packet.(*statePack).states, func(delivered int, progressed bool, err error) { 955 // If the peer returned old-requested data, forgive 956 if err == trie.ErrNotRequested { 957 log.Debug("Forgiving reply to stale state request", "peer", packet.PeerId()) 958 return 959 } 960 if err != nil { 961 // If the node data processing failed, the root hash is very wrong, abort 962 log.Error("State processing failed", "peer", packet.PeerId(), "err", err) 963 d.Cancel() 964 return 965 } 966 // Processing succeeded, notify state fetcher of continuation 967 pending := d.queue.PendingNodeData() 968 if pending > 0 { 969 select { 970 case d.stateWakeCh <- true: 971 default: 972 } 973 } 974 d.syncStatsLock.Lock() 975 d.syncStatsStateDone += uint64(delivered) 976 syncStatsStateDone := d.syncStatsStateDone // Thread safe copy for the log below 977 d.syncStatsLock.Unlock() 978 979 // If real database progress was made, reset any fast-sync pivot failure 980 if progressed && atomic.LoadUint32(&d.fsPivotFails) > 1 { 981 log.Debug("Fast-sync progressed, resetting fail counter", "previous", atomic.LoadUint32(&d.fsPivotFails)) 982 atomic.StoreUint32(&d.fsPivotFails, 1) // Don't ever reset to 0, as that will unlock the pivot block 983 } 984 // Log a message to the user and return 985 if delivered > 0 { 986 log.Info("Imported new state entries", "count", delivered, "elapsed", common.PrettyDuration(time.Since(start)), "processed", syncStatsStateDone, "pending", pending) 987 } 988 }) 989 } 990 expire = func() map[string]int { return d.queue.ExpireNodeData(d.requestTTL()) } 991 throttle = func() bool { return false } 992 reserve = func(p *peer, count int) (*fetchRequest, bool, error) { 993 return d.queue.ReserveNodeData(p, count), false, nil 994 } 995 fetch = func(p *peer, req *fetchRequest) error { return p.FetchNodeData(req) } 996 capacity = func(p *peer) int { return p.NodeDataCapacity(d.requestRTT()) } 997 setIdle = func(p *peer, accepted int) { p.SetNodeDataIdle(accepted) } 998 ) 999 err := d.fetchParts(errCancelStateFetch, d.stateCh, deliver, d.stateWakeCh, expire, 1000 d.queue.PendingNodeData, d.queue.InFlightNodeData, throttle, reserve, nil, fetch, 1001 d.queue.CancelNodeData, capacity, d.peers.NodeDataIdlePeers, setIdle, "states") 1002 1003 log.Debug("Node state data download terminated", "err", err) 1004 return err 1005 } 1006 1007 // fetchParts iteratively downloads scheduled block parts, taking any available 1008 // peers, reserving a chunk of fetch requests for each, waiting for delivery and 1009 // also periodically checking for timeouts. 1010 // 1011 // As the scheduling/timeout logic mostly is the same for all downloaded data 1012 // types, this method is used by each for data gathering and is instrumented with 1013 // various callbacks to handle the slight differences between processing them. 1014 // 1015 // The instrumentation parameters: 1016 // - errCancel: error type to return if the fetch operation is cancelled (mostly makes logging nicer) 1017 // - deliveryCh: channel from which to retrieve downloaded data packets (merged from all concurrent peers) 1018 // - deliver: processing callback to deliver data packets into type specific download queues (usually within `queue`) 1019 // - wakeCh: notification channel for waking the fetcher when new tasks are available (or sync completed) 1020 // - expire: task callback method to abort requests that took too long and return the faulty peers (traffic shaping) 1021 // - pending: task callback for the number of requests still needing download (detect completion/non-completability) 1022 // - inFlight: task callback for the number of in-progress requests (wait for all active downloads to finish) 1023 // - throttle: task callback to check if the processing queue is full and activate throttling (bound memory use) 1024 // - reserve: task callback to reserve new download tasks to a particular peer (also signals partial completions) 1025 // - fetchHook: tester callback to notify of new tasks being initiated (allows testing the scheduling logic) 1026 // - fetch: network callback to actually send a particular download request to a physical remote peer 1027 // - cancel: task callback to abort an in-flight download request and allow rescheduling it (in case of lost peer) 1028 // - capacity: network callback to retrieve the estimated type-specific bandwidth capacity of a peer (traffic shaping) 1029 // - idle: network callback to retrieve the currently (type specific) idle peers that can be assigned tasks 1030 // - setIdle: network callback to set a peer back to idle and update its estimated capacity (traffic shaping) 1031 // - kind: textual label of the type being downloaded to display in log mesages 1032 func (d *Downloader) fetchParts(errCancel error, deliveryCh chan dataPack, deliver func(dataPack) (int, error), wakeCh chan bool, 1033 expire func() map[string]int, pending func() int, inFlight func() bool, throttle func() bool, reserve func(*peer, int) (*fetchRequest, bool, error), 1034 fetchHook func([]*types.Header), fetch func(*peer, *fetchRequest) error, cancel func(*fetchRequest), capacity func(*peer) int, 1035 idle func() ([]*peer, int), setIdle func(*peer, int), kind string) error { 1036 1037 // Create a ticker to detect expired retrieval tasks 1038 ticker := time.NewTicker(100 * time.Millisecond) 1039 defer ticker.Stop() 1040 1041 update := make(chan struct{}, 1) 1042 1043 // Prepare the queue and fetch block parts until the block header fetcher's done 1044 finished := false 1045 for { 1046 select { 1047 case <-d.cancelCh: 1048 return errCancel 1049 1050 case packet := <-deliveryCh: 1051 // If the peer was previously banned and failed to deliver it's pack 1052 // in a reasonable time frame, ignore it's message. 1053 if peer := d.peers.Peer(packet.PeerId()); peer != nil { 1054 // Deliver the received chunk of data and check chain validity 1055 accepted, err := deliver(packet) 1056 if err == errInvalidChain { 1057 return err 1058 } 1059 // Unless a peer delivered something completely else than requested (usually 1060 // caused by a timed out request which came through in the end), set it to 1061 // idle. If the delivery's stale, the peer should have already been idled. 1062 if err != errStaleDelivery { 1063 setIdle(peer, accepted) 1064 } 1065 // Issue a log to the user to see what's going on 1066 switch { 1067 case err == nil && packet.Items() == 0: 1068 peer.log.Trace("Requested data not delivered", "type", kind) 1069 case err == nil: 1070 peer.log.Trace("Delivered new batch of data", "type", kind, "count", packet.Stats()) 1071 default: 1072 peer.log.Trace("Failed to deliver retrieved data", "type", kind, "err", err) 1073 } 1074 } 1075 // Blocks assembled, try to update the progress 1076 select { 1077 case update <- struct{}{}: 1078 default: 1079 } 1080 1081 case cont := <-wakeCh: 1082 // The header fetcher sent a continuation flag, check if it's done 1083 if !cont { 1084 finished = true 1085 } 1086 // Headers arrive, try to update the progress 1087 select { 1088 case update <- struct{}{}: 1089 default: 1090 } 1091 1092 case <-ticker.C: 1093 // Sanity check update the progress 1094 select { 1095 case update <- struct{}{}: 1096 default: 1097 } 1098 1099 case <-update: 1100 // Short circuit if we lost all our peers 1101 if d.peers.Len() == 0 { 1102 return errNoPeers 1103 } 1104 // Check for fetch request timeouts and demote the responsible peers 1105 for pid, fails := range expire() { 1106 if peer := d.peers.Peer(pid); peer != nil { 1107 // If a lot of retrieval elements expired, we might have overestimated the remote peer or perhaps 1108 // ourselves. Only reset to minimal throughput but don't drop just yet. If even the minimal times 1109 // out that sync wise we need to get rid of the peer. 1110 // 1111 // The reason the minimum threshold is 2 is because the downloader tries to estimate the bandwidth 1112 // and latency of a peer separately, which requires pushing the measures capacity a bit and seeing 1113 // how response times reacts, to it always requests one more than the minimum (i.e. min 2). 1114 if fails > 2 { 1115 peer.log.Trace("Data delivery timed out", "type", kind) 1116 setIdle(peer, 0) 1117 } else { 1118 peer.log.Debug("Stalling delivery, dropping", "type", kind) 1119 d.dropPeer(pid) 1120 } 1121 } 1122 } 1123 // If there's nothing more to fetch, wait or terminate 1124 if pending() == 0 { 1125 if !inFlight() && finished { 1126 log.Debug("Data fetching completed", "type", kind) 1127 return nil 1128 } 1129 break 1130 } 1131 // Send a download request to all idle peers, until throttled 1132 progressed, throttled, running := false, false, inFlight() 1133 idles, total := idle() 1134 1135 for _, peer := range idles { 1136 // Short circuit if throttling activated 1137 if throttle() { 1138 throttled = true 1139 break 1140 } 1141 // Reserve a chunk of fetches for a peer. A nil can mean either that 1142 // no more headers are available, or that the peer is known not to 1143 // have them. 1144 request, progress, err := reserve(peer, capacity(peer)) 1145 if err != nil { 1146 return err 1147 } 1148 if progress { 1149 progressed = true 1150 } 1151 if request == nil { 1152 continue 1153 } 1154 if request.From > 0 { 1155 peer.log.Trace("Requesting new batch of data", "type", kind, "from", request.From) 1156 } else if len(request.Headers) > 0 { 1157 peer.log.Trace("Requesting new batch of data", "type", kind, "count", len(request.Headers), "from", request.Headers[0].Number) 1158 } else { 1159 peer.log.Trace("Requesting new batch of data", "type", kind, "count", len(request.Hashes)) 1160 } 1161 // Fetch the chunk and make sure any errors return the hashes to the queue 1162 if fetchHook != nil { 1163 fetchHook(request.Headers) 1164 } 1165 if err := fetch(peer, request); err != nil { 1166 // Although we could try and make an attempt to fix this, this error really 1167 // means that we've double allocated a fetch task to a peer. If that is the 1168 // case, the internal state of the downloader and the queue is very wrong so 1169 // better hard crash and note the error instead of silently accumulating into 1170 // a much bigger issue. 1171 panic(fmt.Sprintf("%v: %s fetch assignment failed", peer, kind)) 1172 } 1173 running = true 1174 } 1175 // Make sure that we have peers available for fetching. If all peers have been tried 1176 // and all failed throw an error 1177 if !progressed && !throttled && !running && len(idles) == total && pending() > 0 { 1178 return errPeersUnavailable 1179 } 1180 } 1181 } 1182 } 1183 1184 // processHeaders takes batches of retrieved headers from an input channel and 1185 // keeps processing and scheduling them into the header chain and downloader's 1186 // queue until the stream ends or a failure occurs. 1187 func (d *Downloader) processHeaders(origin uint64, td *big.Int) error { 1188 // Calculate the pivoting point for switching from fast to slow sync 1189 pivot := d.queue.FastSyncPivot() 1190 1191 // Keep a count of uncertain headers to roll back 1192 rollback := []*types.Header{} 1193 defer func() { 1194 if len(rollback) > 0 { 1195 // Flatten the headers and roll them back 1196 hashes := make([]common.Hash, len(rollback)) 1197 for i, header := range rollback { 1198 hashes[i] = header.Hash() 1199 } 1200 lastHeader, lastFastBlock, lastBlock := d.headHeader().Number, common.Big0, common.Big0 1201 if d.headFastBlock != nil { 1202 lastFastBlock = d.headFastBlock().Number() 1203 } 1204 if d.headBlock != nil { 1205 lastBlock = d.headBlock().Number() 1206 } 1207 d.rollback(hashes) 1208 curFastBlock, curBlock := common.Big0, common.Big0 1209 if d.headFastBlock != nil { 1210 curFastBlock = d.headFastBlock().Number() 1211 } 1212 if d.headBlock != nil { 1213 curBlock = d.headBlock().Number() 1214 } 1215 log.Warn("Rolled back headers", "count", len(hashes), 1216 "header", fmt.Sprintf("%d->%d", lastHeader, d.headHeader().Number), 1217 "fast", fmt.Sprintf("%d->%d", lastFastBlock, curFastBlock), 1218 "block", fmt.Sprintf("%d->%d", lastBlock, curBlock)) 1219 1220 // If we're already past the pivot point, this could be an attack, thread carefully 1221 if rollback[len(rollback)-1].Number.Uint64() > pivot { 1222 // If we didn't ever fail, lock in te pivot header (must! not! change!) 1223 if atomic.LoadUint32(&d.fsPivotFails) == 0 { 1224 for _, header := range rollback { 1225 if header.Number.Uint64() == pivot { 1226 log.Warn("Fast-sync pivot locked in", "number", pivot, "hash", header.Hash()) 1227 d.fsPivotLock = header 1228 } 1229 } 1230 } 1231 } 1232 } 1233 }() 1234 1235 // Wait for batches of headers to process 1236 gotHeaders := false 1237 1238 for { 1239 select { 1240 case <-d.cancelCh: 1241 return errCancelHeaderProcessing 1242 1243 case headers := <-d.headerProcCh: 1244 // Terminate header processing if we synced up 1245 if len(headers) == 0 { 1246 // Notify everyone that headers are fully processed 1247 for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh, d.stateWakeCh} { 1248 select { 1249 case ch <- false: 1250 case <-d.cancelCh: 1251 } 1252 } 1253 // If no headers were retrieved at all, the peer violated it's TD promise that it had a 1254 // better chain compared to ours. The only exception is if it's promised blocks were 1255 // already imported by other means (e.g. fecher): 1256 // 1257 // R <remote peer>, L <local node>: Both at block 10 1258 // R: Mine block 11, and propagate it to L 1259 // L: Queue block 11 for import 1260 // L: Notice that R's head and TD increased compared to ours, start sync 1261 // L: Import of block 11 finishes 1262 // L: Sync begins, and finds common ancestor at 11 1263 // L: Request new headers up from 11 (R's TD was higher, it must have something) 1264 // R: Nothing to give 1265 if d.mode != LightSync { 1266 if !gotHeaders && td.Cmp(d.getTd(d.headBlock().Hash())) > 0 { 1267 return errStallingPeer 1268 } 1269 } 1270 // If fast or light syncing, ensure promised headers are indeed delivered. This is 1271 // needed to detect scenarios where an attacker feeds a bad pivot and then bails out 1272 // of delivering the post-pivot blocks that would flag the invalid content. 1273 // 1274 // This check cannot be executed "as is" for full imports, since blocks may still be 1275 // queued for processing when the header download completes. However, as long as the 1276 // peer gave us something useful, we're already happy/progressed (above check). 1277 if d.mode == FastSync || d.mode == LightSync { 1278 if td.Cmp(d.getTd(d.headHeader().Hash())) > 0 { 1279 return errStallingPeer 1280 } 1281 } 1282 // Disable any rollback and return 1283 rollback = nil 1284 return nil 1285 } 1286 // Otherwise split the chunk of headers into batches and process them 1287 gotHeaders = true 1288 1289 for len(headers) > 0 { 1290 // Terminate if something failed in between processing chunks 1291 select { 1292 case <-d.cancelCh: 1293 return errCancelHeaderProcessing 1294 default: 1295 } 1296 // Select the next chunk of headers to import 1297 limit := maxHeadersProcess 1298 if limit > len(headers) { 1299 limit = len(headers) 1300 } 1301 chunk := headers[:limit] 1302 1303 // In case of header only syncing, validate the chunk immediately 1304 if d.mode == FastSync || d.mode == LightSync { 1305 // Collect the yet unknown headers to mark them as uncertain 1306 unknown := make([]*types.Header, 0, len(headers)) 1307 for _, header := range chunk { 1308 if !d.hasHeader(header.Hash()) { 1309 unknown = append(unknown, header) 1310 } 1311 } 1312 // If we're importing pure headers, verify based on their recentness 1313 frequency := fsHeaderCheckFrequency 1314 if chunk[len(chunk)-1].Number.Uint64()+uint64(fsHeaderForceVerify) > pivot { 1315 frequency = 1 1316 } 1317 if n, err := d.insertHeaders(chunk, frequency); err != nil { 1318 // If some headers were inserted, add them too to the rollback list 1319 if n > 0 { 1320 rollback = append(rollback, chunk[:n]...) 1321 } 1322 log.Debug("Invalid header encountered", "number", chunk[n].Number, "hash", chunk[n].Hash(), "err", err) 1323 return errInvalidChain 1324 } 1325 // All verifications passed, store newly found uncertain headers 1326 rollback = append(rollback, unknown...) 1327 if len(rollback) > fsHeaderSafetyNet { 1328 rollback = append(rollback[:0], rollback[len(rollback)-fsHeaderSafetyNet:]...) 1329 } 1330 } 1331 // If we're fast syncing and just pulled in the pivot, make sure it's the one locked in 1332 if d.mode == FastSync && d.fsPivotLock != nil && chunk[0].Number.Uint64() <= pivot && chunk[len(chunk)-1].Number.Uint64() >= pivot { 1333 if pivot := chunk[int(pivot-chunk[0].Number.Uint64())]; pivot.Hash() != d.fsPivotLock.Hash() { 1334 log.Warn("Pivot doesn't match locked in one", "remoteNumber", pivot.Number, "remoteHash", pivot.Hash(), "localNumber", d.fsPivotLock.Number, "localHash", d.fsPivotLock.Hash()) 1335 return errInvalidChain 1336 } 1337 } 1338 // Unless we're doing light chains, schedule the headers for associated content retrieval 1339 if d.mode == FullSync || d.mode == FastSync { 1340 // If we've reached the allowed number of pending headers, stall a bit 1341 for d.queue.PendingBlocks() >= maxQueuedHeaders || d.queue.PendingReceipts() >= maxQueuedHeaders { 1342 select { 1343 case <-d.cancelCh: 1344 return errCancelHeaderProcessing 1345 case <-time.After(time.Second): 1346 } 1347 } 1348 // Otherwise insert the headers for content retrieval 1349 inserts := d.queue.Schedule(chunk, origin) 1350 if len(inserts) != len(chunk) { 1351 log.Debug("Stale headers") 1352 return errBadPeer 1353 } 1354 } 1355 headers = headers[limit:] 1356 origin += uint64(limit) 1357 } 1358 // Signal the content downloaders of the availablility of new tasks 1359 for _, ch := range []chan bool{d.bodyWakeCh, d.receiptWakeCh, d.stateWakeCh} { 1360 select { 1361 case ch <- true: 1362 default: 1363 } 1364 } 1365 } 1366 } 1367 } 1368 1369 // processContent takes fetch results from the queue and tries to import them 1370 // into the chain. The type of import operation will depend on the result contents. 1371 func (d *Downloader) processContent() error { 1372 pivot := d.queue.FastSyncPivot() 1373 for { 1374 results := d.queue.WaitResults() 1375 if len(results) == 0 { 1376 return nil // queue empty 1377 } 1378 if d.chainInsertHook != nil { 1379 d.chainInsertHook(results) 1380 } 1381 // Actually import the blocks 1382 first, last := results[0].Header, results[len(results)-1].Header 1383 log.Debug("Inserting downloaded chain", "items", len(results), 1384 "firstnum", first.Number, "firsthash", first.Hash(), 1385 "lastnum", last.Number, "lasthash", last.Hash(), 1386 ) 1387 for len(results) != 0 { 1388 // Check for any termination requests 1389 select { 1390 case <-d.quitCh: 1391 return errCancelContentProcessing 1392 default: 1393 } 1394 // Retrieve the a batch of results to import 1395 var ( 1396 blocks = make([]*types.Block, 0, maxResultsProcess) 1397 receipts = make([]types.Receipts, 0, maxResultsProcess) 1398 ) 1399 items := int(math.Min(float64(len(results)), float64(maxResultsProcess))) 1400 for _, result := range results[:items] { 1401 switch { 1402 case d.mode == FullSync: 1403 blocks = append(blocks, types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles)) 1404 case d.mode == FastSync: 1405 blocks = append(blocks, types.NewBlockWithHeader(result.Header).WithBody(result.Transactions, result.Uncles)) 1406 if result.Header.Number.Uint64() <= pivot { 1407 receipts = append(receipts, result.Receipts) 1408 } 1409 } 1410 } 1411 // Try to process the results, aborting if there's an error 1412 var ( 1413 err error 1414 index int 1415 ) 1416 switch { 1417 case len(receipts) > 0: 1418 index, err = d.insertReceipts(blocks, receipts) 1419 if err == nil && blocks[len(blocks)-1].NumberU64() == pivot { 1420 log.Debug("Committing block as new head", "number", blocks[len(blocks)-1].Number(), "hash", blocks[len(blocks)-1].Hash()) 1421 index, err = len(blocks)-1, d.commitHeadBlock(blocks[len(blocks)-1].Hash()) 1422 } 1423 default: 1424 index, err = d.insertBlocks(blocks) 1425 } 1426 if err != nil { 1427 log.Debug("Downloaded item processing failed", "number", results[index].Header.Number, "hash", results[index].Header.Hash(), "err", err) 1428 return errInvalidChain 1429 } 1430 // Shift the results to the next batch 1431 results = results[items:] 1432 } 1433 } 1434 } 1435 1436 // DeliverHeaders injects a new batch of block headers received from a remote 1437 // node into the download schedule. 1438 func (d *Downloader) DeliverHeaders(id string, headers []*types.Header) (err error) { 1439 return d.deliver(id, d.headerCh, &headerPack{id, headers}, headerInMeter, headerDropMeter) 1440 } 1441 1442 // DeliverBodies injects a new batch of block bodies received from a remote node. 1443 func (d *Downloader) DeliverBodies(id string, transactions [][]*types.Transaction, uncles [][]*types.Header) (err error) { 1444 return d.deliver(id, d.bodyCh, &bodyPack{id, transactions, uncles}, bodyInMeter, bodyDropMeter) 1445 } 1446 1447 // DeliverReceipts injects a new batch of receipts received from a remote node. 1448 func (d *Downloader) DeliverReceipts(id string, receipts [][]*types.Receipt) (err error) { 1449 return d.deliver(id, d.receiptCh, &receiptPack{id, receipts}, receiptInMeter, receiptDropMeter) 1450 } 1451 1452 // DeliverNodeData injects a new batch of node state data received from a remote node. 1453 func (d *Downloader) DeliverNodeData(id string, data [][]byte) (err error) { 1454 return d.deliver(id, d.stateCh, &statePack{id, data}, stateInMeter, stateDropMeter) 1455 } 1456 1457 // deliver injects a new batch of data received from a remote node. 1458 func (d *Downloader) deliver(id string, destCh chan dataPack, packet dataPack, inMeter, dropMeter metrics.Meter) (err error) { 1459 // Update the delivery metrics for both good and failed deliveries 1460 inMeter.Mark(int64(packet.Items())) 1461 defer func() { 1462 if err != nil { 1463 dropMeter.Mark(int64(packet.Items())) 1464 } 1465 }() 1466 // Deliver or abort if the sync is canceled while queuing 1467 d.cancelLock.RLock() 1468 cancel := d.cancelCh 1469 d.cancelLock.RUnlock() 1470 if cancel == nil { 1471 return errNoSyncActive 1472 } 1473 select { 1474 case destCh <- packet: 1475 return nil 1476 case <-cancel: 1477 return errNoSyncActive 1478 } 1479 } 1480 1481 // qosTuner is the quality of service tuning loop that occasionally gathers the 1482 // peer latency statistics and updates the estimated request round trip time. 1483 func (d *Downloader) qosTuner() { 1484 for { 1485 // Retrieve the current median RTT and integrate into the previoust target RTT 1486 rtt := time.Duration(float64(1-qosTuningImpact)*float64(atomic.LoadUint64(&d.rttEstimate)) + qosTuningImpact*float64(d.peers.medianRTT())) 1487 atomic.StoreUint64(&d.rttEstimate, uint64(rtt)) 1488 1489 // A new RTT cycle passed, increase our confidence in the estimated RTT 1490 conf := atomic.LoadUint64(&d.rttConfidence) 1491 conf = conf + (1000000-conf)/2 1492 atomic.StoreUint64(&d.rttConfidence, conf) 1493 1494 // Log the new QoS values and sleep until the next RTT 1495 //temp : log.Debug("Recalculated downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL()) 1496 select { 1497 case <-d.quitCh: 1498 return 1499 case <-time.After(rtt): 1500 } 1501 } 1502 } 1503 1504 // qosReduceConfidence is meant to be called when a new peer joins the downloader's 1505 // peer set, needing to reduce the confidence we have in out QoS estimates. 1506 func (d *Downloader) qosReduceConfidence() { 1507 // If we have a single peer, confidence is always 1 1508 peers := uint64(d.peers.Len()) 1509 if peers == 0 { 1510 // Ensure peer connectivity races don't catch us off guard 1511 return 1512 } 1513 if peers == 1 { 1514 atomic.StoreUint64(&d.rttConfidence, 1000000) 1515 return 1516 } 1517 // If we have a ton of peers, don't drop confidence) 1518 if peers >= uint64(qosConfidenceCap) { 1519 return 1520 } 1521 // Otherwise drop the confidence factor 1522 conf := atomic.LoadUint64(&d.rttConfidence) * (peers - 1) / peers 1523 if float64(conf)/1000000 < rttMinConfidence { 1524 conf = uint64(rttMinConfidence * 1000000) 1525 } 1526 atomic.StoreUint64(&d.rttConfidence, conf) 1527 1528 rtt := time.Duration(atomic.LoadUint64(&d.rttEstimate)) 1529 log.Debug("Relaxed downloader QoS values", "rtt", rtt, "confidence", float64(conf)/1000000.0, "ttl", d.requestTTL()) 1530 } 1531 1532 // requestRTT returns the current target round trip time for a download request 1533 // to complete in. 1534 // 1535 // Note, the returned RTT is .9 of the actually estimated RTT. The reason is that 1536 // the downloader tries to adapt queries to the RTT, so multiple RTT values can 1537 // be adapted to, but smaller ones are preffered (stabler download stream). 1538 func (d *Downloader) requestRTT() time.Duration { 1539 return time.Duration(atomic.LoadUint64(&d.rttEstimate)) * 9 / 10 1540 } 1541 1542 // requestTTL returns the current timeout allowance for a single download request 1543 // to finish under. 1544 func (d *Downloader) requestTTL() time.Duration { 1545 var ( 1546 rtt = time.Duration(atomic.LoadUint64(&d.rttEstimate)) 1547 conf = float64(atomic.LoadUint64(&d.rttConfidence)) / 1000000.0 1548 ) 1549 ttl := time.Duration(ttlScaling) * time.Duration(float64(rtt)/conf) 1550 if ttl > ttlLimit { 1551 ttl = ttlLimit 1552 } 1553 return ttl 1554 }