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