|
|
|
@ -98,7 +98,7 @@ type headerTask struct { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type Downloader struct { |
|
|
|
|
mode uint32 // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode
|
|
|
|
|
mode atomic.Uint32 // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode
|
|
|
|
|
mux *event.TypeMux // Event multiplexer to announce sync operation events
|
|
|
|
|
|
|
|
|
|
checkpoint uint64 // Checkpoint block number to enforce head against (e.g. snap sync)
|
|
|
|
@ -122,9 +122,9 @@ type Downloader struct { |
|
|
|
|
|
|
|
|
|
// Status
|
|
|
|
|
synchroniseMock func(id string, hash common.Hash) error // Replacement for synchronise during testing
|
|
|
|
|
synchronising int32 |
|
|
|
|
notified int32 |
|
|
|
|
committed int32 |
|
|
|
|
synchronising atomic.Bool |
|
|
|
|
notified atomic.Bool |
|
|
|
|
committed atomic.Bool |
|
|
|
|
ancientLimit uint64 // The maximum block number which can be regarded as ancient data.
|
|
|
|
|
|
|
|
|
|
// Channels
|
|
|
|
@ -292,7 +292,7 @@ func (d *Downloader) Progress() ethereum.SyncProgress { |
|
|
|
|
|
|
|
|
|
// Synchronising returns whether the downloader is currently retrieving blocks.
|
|
|
|
|
func (d *Downloader) Synchronising() bool { |
|
|
|
|
return atomic.LoadInt32(&d.synchronising) > 0 |
|
|
|
|
return d.synchronising.Load() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RegisterPeer injects a new download peer into the set of block source to be
|
|
|
|
@ -392,13 +392,13 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td, ttd *big.Int, |
|
|
|
|
return d.synchroniseMock(id, hash) |
|
|
|
|
} |
|
|
|
|
// Make sure only one goroutine is ever allowed past this point at once
|
|
|
|
|
if !atomic.CompareAndSwapInt32(&d.synchronising, 0, 1) { |
|
|
|
|
if !d.synchronising.CompareAndSwap(false, true) { |
|
|
|
|
return errBusy |
|
|
|
|
} |
|
|
|
|
defer atomic.StoreInt32(&d.synchronising, 0) |
|
|
|
|
defer d.synchronising.Store(false) |
|
|
|
|
|
|
|
|
|
// Post a user notification of the sync (only once per session)
|
|
|
|
|
if atomic.CompareAndSwapInt32(&d.notified, 0, 1) { |
|
|
|
|
if d.notified.CompareAndSwap(false, true) { |
|
|
|
|
log.Info("Block synchronisation started") |
|
|
|
|
} |
|
|
|
|
if mode == SnapSync { |
|
|
|
@ -435,7 +435,7 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td, ttd *big.Int, |
|
|
|
|
defer d.Cancel() // No matter what, we can't leave the cancel channel open
|
|
|
|
|
|
|
|
|
|
// Atomically set the requested sync mode
|
|
|
|
|
atomic.StoreUint32(&d.mode, uint32(mode)) |
|
|
|
|
d.mode.Store(uint32(mode)) |
|
|
|
|
|
|
|
|
|
// Retrieve the origin peer and initiate the downloading process
|
|
|
|
|
var p *peerConnection |
|
|
|
@ -452,7 +452,7 @@ func (d *Downloader) synchronise(id string, hash common.Hash, td, ttd *big.Int, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (d *Downloader) getMode() SyncMode { |
|
|
|
|
return SyncMode(atomic.LoadUint32(&d.mode)) |
|
|
|
|
return SyncMode(d.mode.Load()) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// syncWithPeer starts a block synchronization based on the hash chain from the
|
|
|
|
@ -562,9 +562,9 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd * |
|
|
|
|
rawdb.WriteLastPivotNumber(d.stateDB, pivotNumber) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
d.committed = 1 |
|
|
|
|
d.committed.Store(true) |
|
|
|
|
if mode == SnapSync && pivot.Number.Uint64() != 0 { |
|
|
|
|
d.committed = 0 |
|
|
|
|
d.committed.Store(false) |
|
|
|
|
} |
|
|
|
|
if mode == SnapSync { |
|
|
|
|
// Set the ancient data limitation. If we are running snap sync, all block
|
|
|
|
@ -1128,7 +1128,7 @@ func (d *Downloader) fetchHeaders(p *peerConnection, from uint64, head uint64) e |
|
|
|
|
// If no more headers are inbound, notify the content fetchers and return
|
|
|
|
|
if len(headers) == 0 { |
|
|
|
|
// Don't abort header fetches while the pivot is downloading
|
|
|
|
|
if atomic.LoadInt32(&d.committed) == 0 && pivot <= from { |
|
|
|
|
if !d.committed.Load() && pivot <= from { |
|
|
|
|
p.log.Debug("No headers, waiting for pivot commit") |
|
|
|
|
select { |
|
|
|
|
case <-time.After(fsHeaderContCheck): |
|
|
|
@ -1669,7 +1669,7 @@ func (d *Downloader) processSnapSyncContent() error { |
|
|
|
|
results = append(append([]*fetchResult{oldPivot}, oldTail...), results...) |
|
|
|
|
} |
|
|
|
|
// Split around the pivot block and process the two sides via snap/full sync
|
|
|
|
|
if atomic.LoadInt32(&d.committed) == 0 { |
|
|
|
|
if !d.committed.Load() { |
|
|
|
|
latest := results[len(results)-1].Header |
|
|
|
|
// If the height is above the pivot block by 2 sets, it means the pivot
|
|
|
|
|
// become stale in the network and it was garbage collected, move to a
|
|
|
|
@ -1794,7 +1794,7 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error { |
|
|
|
|
if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil { |
|
|
|
|
return err |
|
|
|
|
} |
|
|
|
|
atomic.StoreInt32(&d.committed, 1) |
|
|
|
|
d.committed.Store(true) |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|