-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sync: Add rescan progress. #4
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ import ( | |
"strings" | ||
|
||
"decred.org/dcrwallet/v3/spv" | ||
dcrwallet "decred.org/dcrwallet/v3/wallet" | ||
) | ||
|
||
//export syncWallet | ||
|
@@ -42,6 +43,10 @@ func syncWallet(cName, cPeers *C.char) *C.char { | |
}, | ||
FetchMissingCFiltersStarted: func() { | ||
w.syncStatusMtx.Lock() | ||
if w.rescanning { | ||
w.syncStatusMtx.Unlock() | ||
return | ||
} | ||
Comment on lines
+46
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like these are being called during the rescan, which is strange. This may be why the status doesnt say synced without the bandaid. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably don't want to allow rescanning when sync is on. If we add that check in the rescan method, then we may not need to bother about this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do you mean stop sync then restart it? Is that what other wallets do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, reject rescan requests if sync is ongoing. Rescan works best if sync is completed and the block filters are downloaded. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh sorry missed this. Now checking if synced before rescan https://github.com/decred/libwallet/compare/f2eca88e6d25a98ab03ee087bf65b69bed3fe73c..1f2c9ca6c4eb07607509400459b8e1164e6fe83b Not sure why I was holding the wallet lock. Looks ok without the lock? |
||
w.syncStatusCode = SSCFetchingCFilters | ||
w.syncStatusMtx.Unlock() | ||
w.log.Info("Fetching missing cfilters started.") | ||
|
@@ -57,6 +62,10 @@ func syncWallet(cName, cPeers *C.char) *C.char { | |
}, | ||
FetchHeadersStarted: func() { | ||
w.syncStatusMtx.Lock() | ||
if w.rescanning { | ||
w.syncStatusMtx.Unlock() | ||
return | ||
} | ||
w.syncStatusCode = SSCFetchingHeaders | ||
w.syncStatusMtx.Unlock() | ||
w.log.Info("Fetching headers started.") | ||
|
@@ -72,6 +81,10 @@ func syncWallet(cName, cPeers *C.char) *C.char { | |
}, | ||
DiscoverAddressesStarted: func() { | ||
w.syncStatusMtx.Lock() | ||
if w.rescanning { | ||
w.syncStatusMtx.Unlock() | ||
return | ||
} | ||
w.syncStatusCode = SSCDiscoveringAddrs | ||
w.syncStatusMtx.Unlock() | ||
w.log.Info("Discover addresses started.") | ||
|
@@ -81,6 +94,10 @@ func syncWallet(cName, cPeers *C.char) *C.char { | |
}, | ||
RescanStarted: func() { | ||
w.syncStatusMtx.Lock() | ||
if w.rescanning { | ||
w.syncStatusMtx.Unlock() | ||
return | ||
} | ||
w.syncStatusCode = SSCRescanning | ||
w.syncStatusMtx.Unlock() | ||
w.log.Info("Rescan started.") | ||
|
@@ -95,7 +112,7 @@ func syncWallet(cName, cPeers *C.char) *C.char { | |
w.log.Info("Rescan finished.") | ||
}, | ||
} | ||
if err := w.StartSync(ctx, ntfns, peers...); err != nil { | ||
if err := w.StartSync(w.ctx, ntfns, peers...); err != nil { | ||
return errCResponse(err.Error()) | ||
} | ||
return successCResponse("sync started") | ||
|
@@ -120,7 +137,7 @@ func syncWalletStatus(cName *C.char) *C.char { | |
if !is { | ||
return errCResponse("backend is not an spv syncer") | ||
} | ||
targetHeight := spvSyncer.EstimateMainChainTip(ctx) | ||
targetHeight := spvSyncer.EstimateMainChainTip(w.ctx) | ||
|
||
// Sometimes it appears we miss a notification during start up. This is | ||
// a bandaid to put us as synced in that case. | ||
|
@@ -156,32 +173,56 @@ func syncWalletStatus(cName *C.char) *C.char { | |
|
||
//export rescanFromHeight | ||
func rescanFromHeight(cName, cHeight *C.char) *C.char { | ||
walletsMtx.Lock() | ||
defer walletsMtx.Unlock() | ||
height, err := strconv.ParseUint(goString(cHeight), 10, 32) | ||
if err != nil { | ||
return errCResponse("height is not an uint32: %v", err) | ||
} | ||
name := goString(cName) | ||
w, exists := wallets[name] | ||
w, exists := loadedWallet(cName) | ||
if !exists { | ||
return errCResponse("wallet with name %q does not exist", name) | ||
} | ||
height, err := strconv.ParseUint(goString(cHeight), 10, 32) | ||
if err != nil { | ||
return errCResponse("height is not an uint32: %v", err) | ||
if !w.IsSynced() { | ||
return errCResponseWithCode(ErrCodeNotSynced, "rescanFromHeight requested on an unsynced wallet") | ||
} | ||
// We don't seem to get any feedback from wallet when doing rescans here. | ||
// Just set status to rescanning and then to complete when done. | ||
w.syncStatusMtx.Lock() | ||
if w.rescanning { | ||
w.syncStatusMtx.Unlock() | ||
return errCResponse("wallet %q already rescanning", name) | ||
} | ||
w.syncStatusCode = SSCRescanning | ||
w.rescanning = true | ||
w.rescanHeight = int(height) | ||
w.syncStatusMtx.Unlock() | ||
w.Add(1) | ||
go func() { | ||
defer func() { | ||
w.syncStatusMtx.Lock() | ||
w.syncStatusCode = SSCComplete | ||
w.rescanning = false | ||
w.syncStatusMtx.Unlock() | ||
w.Done() | ||
}() | ||
prog := make(chan dcrwallet.RescanProgress) | ||
go func() { | ||
w.RescanProgressFromHeight(w.ctx, int32(height), prog) | ||
}() | ||
if err := w.RescanFromHeight(ctx, int32(height)); err != nil { | ||
log.Errorf("rescan wallet %q error: %v", name, err) | ||
for { | ||
select { | ||
case p, open := <-prog: | ||
if !open { | ||
return | ||
} | ||
if p.Err != nil { | ||
log.Errorf("rescan wallet %q error: %v", name, err) | ||
return | ||
} | ||
w.syncStatusMtx.Lock() | ||
w.rescanHeight = int(p.ScannedThrough) | ||
itswisdomagain marked this conversation as resolved.
Show resolved
Hide resolved
|
||
w.syncStatusMtx.Unlock() | ||
case <-w.ctx.Done(): | ||
return | ||
} | ||
} | ||
}() | ||
return successCResponse("rescan from height %d for wallet %q started", height, name) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to the problem but I don't understand why this needs to be done and I'm concerned it could cause panics.