aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/geth/admin.go13
-rw-r--r--eth/downloader/downloader.go46
2 files changed, 51 insertions, 8 deletions
diff --git a/cmd/geth/admin.go b/cmd/geth/admin.go
index 13d10de32..4f22110ad 100644
--- a/cmd/geth/admin.go
+++ b/cmd/geth/admin.go
@@ -51,7 +51,7 @@ func (js *jsre) adminBindings() {
admin.Set("import", js.importChain)
admin.Set("export", js.exportChain)
admin.Set("verbosity", js.verbosity)
- admin.Set("progress", js.downloadProgress)
+ admin.Set("progress", js.syncProgress)
admin.Set("setSolc", js.setSolc)
admin.Set("contractInfo", struct{}{})
@@ -324,9 +324,14 @@ func (js *jsre) setHead(call otto.FunctionCall) otto.Value {
return otto.UndefinedValue()
}
-func (js *jsre) downloadProgress(call otto.FunctionCall) otto.Value {
- pending, cached := js.ethereum.Downloader().Stats()
- v, _ := call.Otto.ToValue(map[string]interface{}{"pending": pending, "cached": cached})
+func (js *jsre) syncProgress(call otto.FunctionCall) otto.Value {
+ pending, cached, importing, eta := js.ethereum.Downloader().Stats()
+ v, _ := call.Otto.ToValue(map[string]interface{}{
+ "pending": pending,
+ "cached": cached,
+ "importing": importing,
+ "estimate": (eta / time.Second * time.Second).String(),
+ })
return v
}
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index 29b627771..f0a515d12 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -78,6 +78,12 @@ type Downloader struct {
checks map[common.Hash]*crossCheck // Pending cross checks to verify a hash chain
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
hasBlock hashCheckFn
getBlock getBlockFn
@@ -121,8 +127,27 @@ func New(mux *event.TypeMux, hasBlock hashCheckFn, getBlock getBlockFn) *Downloa
return downloader
}
-func (d *Downloader) Stats() (current int, max int) {
- return d.queue.Size()
+// Stats retrieves the current status of the downloader.
+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
@@ -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.
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
@@ -255,9 +288,14 @@ func (d *Downloader) Cancel() bool {
}
d.cancelLock.Unlock()
- // reset the queue
+ // Reset the queue and import statistics
d.queue.Reset()
+ d.importLock.Lock()
+ d.importQueue = nil
+ d.importDone = 0
+ d.importLock.Unlock()
+
return true
}