@@ -35,6 +35,7 @@ import (
35
35
"github.com/ethereum/go-ethereum/logger"
36
36
"github.com/ethereum/go-ethereum/logger/glog"
37
37
"github.com/ethereum/go-ethereum/params"
38
+ "github.com/ethereum/go-ethereum/trie"
38
39
"github.com/rcrowley/go-metrics"
39
40
)
40
41
@@ -114,7 +115,6 @@ type Downloader struct {
114
115
// Statistics
115
116
syncStatsChainOrigin uint64 // Origin block number where syncing started at
116
117
syncStatsChainHeight uint64 // Highest block number known when syncing started
117
- syncStatsStateTotal uint64 // Total number of node state entries known so far
118
118
syncStatsStateDone uint64 // Number of state trie entries already pulled
119
119
syncStatsLock sync.RWMutex // Lock protecting the sync stats fields
120
120
@@ -321,12 +321,6 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td *big.Int, mode
321
321
empty = true
322
322
}
323
323
}
324
- // Reset any ephemeral sync statistics
325
- d .syncStatsLock .Lock ()
326
- d .syncStatsStateTotal = 0
327
- d .syncStatsStateDone = 0
328
- d .syncStatsLock .Unlock ()
329
-
330
324
// Create cancel channel for aborting mid-flight
331
325
d .cancelLock .Lock ()
332
326
d .cancelCh = make (chan struct {})
@@ -382,7 +376,7 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash, td *big.Int) (err e
382
376
d .syncStatsLock .Unlock ()
383
377
384
378
// Initiate the sync using a concurrent hash and block retrieval algorithm
385
- d .queue .Prepare (origin + 1 , d .mode , 0 )
379
+ d .queue .Prepare (origin + 1 , d .mode , 0 , nil )
386
380
if d .syncInitHook != nil {
387
381
d .syncInitHook (origin , latest )
388
382
}
@@ -397,30 +391,32 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash, td *big.Int) (err e
397
391
if err != nil {
398
392
return err
399
393
}
400
- origin , err := d .findAncestor (p , latest )
394
+ height := latest .Number .Uint64 ()
395
+
396
+ origin , err := d .findAncestor (p , height )
401
397
if err != nil {
402
398
return err
403
399
}
404
400
d .syncStatsLock .Lock ()
405
401
if d .syncStatsChainHeight <= origin || d .syncStatsChainOrigin > origin {
406
402
d .syncStatsChainOrigin = origin
407
403
}
408
- d .syncStatsChainHeight = latest
404
+ d .syncStatsChainHeight = height
409
405
d .syncStatsLock .Unlock ()
410
406
411
407
// Initiate the sync using a concurrent header and content retrieval algorithm
412
408
pivot := uint64 (0 )
413
409
switch d .mode {
414
410
case LightSync :
415
- pivot = latest
411
+ pivot = height
416
412
case FastSync :
417
413
// Calculate the new fast/slow sync pivot point
418
414
pivotOffset , err := rand .Int (rand .Reader , big .NewInt (int64 (fsPivotInterval )))
419
415
if err != nil {
420
416
panic (fmt .Sprintf ("Failed to access crypto random source: %v" , err ))
421
417
}
422
- if latest > uint64 (fsMinFullBlocks )+ pivotOffset .Uint64 () {
423
- pivot = latest - uint64 (fsMinFullBlocks ) - pivotOffset .Uint64 ()
418
+ if height > uint64 (fsMinFullBlocks )+ pivotOffset .Uint64 () {
419
+ pivot = height - uint64 (fsMinFullBlocks ) - pivotOffset .Uint64 ()
424
420
}
425
421
// If the point is below the origin, move origin back to ensure state download
426
422
if pivot < origin {
@@ -432,9 +428,9 @@ func (d *Downloader) syncWithPeer(p *peer, hash common.Hash, td *big.Int) (err e
432
428
}
433
429
glog .V (logger .Debug ).Infof ("Fast syncing until pivot block #%d" , pivot )
434
430
}
435
- d .queue .Prepare (origin + 1 , d .mode , pivot )
431
+ d .queue .Prepare (origin + 1 , d .mode , pivot , latest )
436
432
if d .syncInitHook != nil {
437
- d .syncInitHook (origin , latest )
433
+ d .syncInitHook (origin , height )
438
434
}
439
435
return d .spawnSync (origin + 1 ,
440
436
func () error { return d .fetchHeaders (p , origin + 1 ) }, // Headers are always retrieved
@@ -952,7 +948,7 @@ func (d *Downloader) fetchBlocks61(from uint64) error {
952
948
953
949
// fetchHeight retrieves the head header of the remote peer to aid in estimating
954
950
// the total time a pending synchronisation would take.
955
- func (d * Downloader ) fetchHeight (p * peer ) (uint64 , error ) {
951
+ func (d * Downloader ) fetchHeight (p * peer ) (* types. Header , error ) {
956
952
glog .V (logger .Debug ).Infof ("%v: retrieving remote chain height" , p )
957
953
958
954
// Request the advertised remote head block and wait for the response
@@ -962,7 +958,7 @@ func (d *Downloader) fetchHeight(p *peer) (uint64, error) {
962
958
for {
963
959
select {
964
960
case <- d .cancelCh :
965
- return 0 , errCancelBlockFetch
961
+ return nil , errCancelBlockFetch
966
962
967
963
case packet := <- d .headerCh :
968
964
// Discard anything not from the origin peer
@@ -974,13 +970,13 @@ func (d *Downloader) fetchHeight(p *peer) (uint64, error) {
974
970
headers := packet .(* headerPack ).headers
975
971
if len (headers ) != 1 {
976
972
glog .V (logger .Debug ).Infof ("%v: invalid number of head headers: %d != 1" , p , len (headers ))
977
- return 0 , errBadPeer
973
+ return nil , errBadPeer
978
974
}
979
- return headers [0 ]. Number . Uint64 () , nil
975
+ return headers [0 ], nil
980
976
981
977
case <- timeout :
982
978
glog .V (logger .Debug ).Infof ("%v: head header timeout" , p )
983
- return 0 , errTimeout
979
+ return nil , errTimeout
984
980
985
981
case <- d .bodyCh :
986
982
case <- d .stateCh :
@@ -1369,10 +1365,10 @@ func (d *Downloader) fetchNodeData() error {
1369
1365
deliver = func (packet dataPack ) (int , error ) {
1370
1366
start := time .Now ()
1371
1367
return d .queue .DeliverNodeData (packet .PeerId (), packet .(* statePack ).states , func (err error , delivered int ) {
1372
- // If the peer gave us nothing, stalling fast sync, drop
1373
- if delivered == 0 {
1374
- glog .V (logger .Debug ).Infof ("peer %s: stalling state delivery, dropping " , packet .PeerId ())
1375
- d . dropPeer ( packet . PeerId ())
1368
+ // If the peer returned old-requested data, forgive
1369
+ if err == trie . ErrNotRequested {
1370
+ glog .V (logger .Info ).Infof ("peer %s: replied to stale state request, forgiving " , packet .PeerId ())
1371
+ return
1376
1372
}
1377
1373
if err != nil {
1378
1374
// If the node data processing failed, the root hash is very wrong, abort
@@ -1381,17 +1377,21 @@ func (d *Downloader) fetchNodeData() error {
1381
1377
return
1382
1378
}
1383
1379
// Processing succeeded, notify state fetcher of continuation
1384
- if d .queue .PendingNodeData () > 0 {
1380
+ pending := d .queue .PendingNodeData ()
1381
+ if pending > 0 {
1385
1382
select {
1386
1383
case d .stateWakeCh <- true :
1387
1384
default :
1388
1385
}
1389
1386
}
1390
- // Log a message to the user and return
1391
1387
d .syncStatsLock .Lock ()
1392
- defer d .syncStatsLock .Unlock ()
1393
1388
d .syncStatsStateDone += uint64 (delivered )
1394
- glog .V (logger .Info ).Infof ("imported %d state entries in %v: processed %d in total" , delivered , time .Since (start ), d .syncStatsStateDone )
1389
+ d .syncStatsLock .Unlock ()
1390
+
1391
+ // Log a message to the user and return
1392
+ if delivered > 0 {
1393
+ glog .V (logger .Info ).Infof ("imported %d state entries in %v: processed %d, pending at least %d" , delivered , time .Since (start ), d .syncStatsStateDone , pending )
1394
+ }
1395
1395
})
1396
1396
}
1397
1397
expire = func () map [string ]int { return d .queue .ExpireNodeData (stateTTL ) }
0 commit comments