|
|
@ -78,6 +78,12 @@ type Downloader struct { |
|
|
|
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
|
|
|
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
|
|
|
|
banned *set.Set // Set of hashes we've received and banned
|
|
|
|
banned *set.Set // Set of hashes we've received and banned
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Statistics
|
|
|
|
|
|
|
|
importStart time.Time // Instance when the last blocks were taken from the cache
|
|
|
|
|
|
|
|
importQueue []*Block // Previously taken blocks to check import progress
|
|
|
|
|
|
|
|
importDone int // Number of taken blocks already imported from the last batch
|
|
|
|
|
|
|
|
importLock sync.Mutex |
|
|
|
|
|
|
|
|
|
|
|
// Callbacks
|
|
|
|
// Callbacks
|
|
|
|
hasBlock hashCheckFn |
|
|
|
hasBlock hashCheckFn |
|
|
|
getBlock getBlockFn |
|
|
|
getBlock getBlockFn |
|
|
@ -121,8 +127,27 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloa |
|
|
|
return downloader |
|
|
|
return downloader |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (d *Downloader) Stats() (current int, max int) { |
|
|
|
// Stats retrieves the current status of the downloader.
|
|
|
|
return d.queue.Size() |
|
|
|
func (d *Downloader) Stats() (pending int, cached int, importing int, estimate time.Duration) { |
|
|
|
|
|
|
|
// Fetch the download status
|
|
|
|
|
|
|
|
pending, cached = d.queue.Size() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Figure out the import progress
|
|
|
|
|
|
|
|
d.importLock.Lock() |
|
|
|
|
|
|
|
defer d.importLock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for len(d.importQueue) > 0 && d.hasBlock(d.importQueue[0].RawBlock.Hash()) { |
|
|
|
|
|
|
|
d.importQueue = d.importQueue[1:] |
|
|
|
|
|
|
|
d.importDone++ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
importing = len(d.importQueue) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make an estimate on the total sync
|
|
|
|
|
|
|
|
estimate = 0 |
|
|
|
|
|
|
|
if d.importDone > 0 { |
|
|
|
|
|
|
|
estimate = time.Since(d.importStart) / time.Duration(d.importDone) * time.Duration(pending+cached+importing) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Synchronising returns the state of the downloader
|
|
|
|
// Synchronising returns the state of the downloader
|
|
|
@ -202,7 +227,15 @@ func (d *Downloader) Synchronise(id string, hash common.Hash) error { |
|
|
|
|
|
|
|
|
|
|
|
// TakeBlocks takes blocks from the queue and yields them to the caller.
|
|
|
|
// TakeBlocks takes blocks from the queue and yields them to the caller.
|
|
|
|
func (d *Downloader) TakeBlocks() []*Block { |
|
|
|
func (d *Downloader) TakeBlocks() []*Block { |
|
|
|
return d.queue.TakeBlocks() |
|
|
|
blocks := d.queue.TakeBlocks() |
|
|
|
|
|
|
|
if len(blocks) > 0 { |
|
|
|
|
|
|
|
d.importLock.Lock() |
|
|
|
|
|
|
|
d.importStart = time.Now() |
|
|
|
|
|
|
|
d.importQueue = blocks |
|
|
|
|
|
|
|
d.importDone = 0 |
|
|
|
|
|
|
|
d.importLock.Unlock() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return blocks |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Has checks if the downloader knows about a particular hash, meaning that its
|
|
|
|
// Has checks if the downloader knows about a particular hash, meaning that its
|
|
|
@ -255,9 +288,14 @@ func (d *Downloader) Cancel() bool { |
|
|
|
} |
|
|
|
} |
|
|
|
d.cancelLock.Unlock() |
|
|
|
d.cancelLock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
// reset the queue
|
|
|
|
// Reset the queue and import statistics
|
|
|
|
d.queue.Reset() |
|
|
|
d.queue.Reset() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d.importLock.Lock() |
|
|
|
|
|
|
|
d.importQueue = nil |
|
|
|
|
|
|
|
d.importDone = 0 |
|
|
|
|
|
|
|
d.importLock.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
return true |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|