Mark partially synced addresses.

This change adds a notification handler for the new rescanprogress
notification and takes advantage of the recent rescan manager and
partial syncing support to mark addresses as partially synced.  If the
network connection to btcd is lost or wallet is restarted during a
rescan, a new rescan will start at the earliest block height for any
wallet address, taking partial syncs into consideration.
This commit is contained in:
Josh Rickmar 2014-03-28 11:28:59 -05:00
parent aa0980bfa7
commit 189df5c535
3 changed files with 39 additions and 4 deletions

View file

@ -159,7 +159,22 @@ func (am *AccountManager) rescanListener() {
log.Infof("Started rescan at height %d for %d %s", e.StartHeight, n, noun) log.Infof("Started rescan at height %d for %d %s", e.StartHeight, n, noun)
case *RescanProgressMsg: case *RescanProgressMsg:
// TODO: mark addresses as partially synced. for acct, addrs := range e.Addresses {
for i := range addrs {
err := acct.SetSyncStatus(addrs[i], wallet.PartialSync(e.Height))
if err != nil {
log.Errorf("Error marking address partially synced: %v", err)
continue
}
}
am.ds.ScheduleWalletWrite(acct)
err := am.ds.FlushAccount(acct)
if err != nil {
log.Errorf("Could not write rescan progress: %v", err)
}
}
log.Infof("Rescanned through block height %d", e.Height)
case *RescanFinishedMsg: case *RescanFinishedMsg:
if e.Error != nil { if e.Error != nil {
@ -169,15 +184,19 @@ func (am *AccountManager) rescanListener() {
n := 0 n := 0
for acct, addrs := range e.Addresses { for acct, addrs := range e.Addresses {
n += len(addrs)
for i := range addrs { for i := range addrs {
n++
err := acct.SetSyncStatus(addrs[i], wallet.FullSync{}) err := acct.SetSyncStatus(addrs[i], wallet.FullSync{})
if err != nil { if err != nil {
log.Errorf("Error marking address synced: %v", err) log.Errorf("Error marking address synced: %v", err)
continue continue
} }
} }
AcctMgr.ds.FlushAccount(acct) am.ds.ScheduleWalletWrite(acct)
err := am.ds.FlushAccount(acct)
if err != nil {
log.Errorf("Could not write rescan progress: %v", err)
}
} }
noun := pickNoun(n, "address", "addresses") noun := pickNoun(n, "address", "addresses")

View file

@ -56,6 +56,7 @@ var notificationHandlers = map[string]notificationHandler{
btcws.BlockDisconnectedNtfnMethod: NtfnBlockDisconnected, btcws.BlockDisconnectedNtfnMethod: NtfnBlockDisconnected,
btcws.RecvTxNtfnMethod: NtfnRecvTx, btcws.RecvTxNtfnMethod: NtfnRecvTx,
btcws.RedeemingTxNtfnMethod: NtfnRedeemingTx, btcws.RedeemingTxNtfnMethod: NtfnRedeemingTx,
btcws.RescanProgressNtfnMethod: NtfnRescanProgress,
} }
// NtfnRecvTx handles the btcws.RecvTxNtfn notification. // NtfnRecvTx handles the btcws.RecvTxNtfn notification.
@ -264,3 +265,18 @@ func NtfnRedeemingTx(n btcjson.Cmd) error {
return nil return nil
} }
// NtfnRescanProgress handles btcd rescanprogress notifications resulting
// from a partially completed rescan.
func NtfnRescanProgress(n btcjson.Cmd) error {
cn, ok := n.(*btcws.RescanProgressNtfn)
if !ok {
return fmt.Errorf("%v handler: unexpected type", n.Method())
}
// Notify the rescan manager of the completed partial progress for
// the current rescan.
AcctMgr.rm.MarkProgress(cn.LastProcessed)
return nil
}

View file

@ -218,7 +218,7 @@ func WalletRequestProcessor() {
// notifications. Restart the connection // notifications. Restart the connection
// to reload accounts files from their last // to reload accounts files from their last
// known good state. // known good state.
log.Warn("Reconnecting to recover from "+ log.Warn("Reconnecting to recover from " +
"out-of-order btcd notification") "out-of-order btcd notification")
s := CurrentServerConn() s := CurrentServerConn()
if btcd, ok := s.(*BtcdRPCConn); ok { if btcd, ok := s.(*BtcdRPCConn); ok {