wallet: ensure timestamp is always set when calling waddrmgr.SetSyncedTo

This commit is contained in:
Olaoluwa Osuntokun 2018-03-10 16:38:54 -08:00
parent 0dcd36bf59
commit 5eaecee2c9
2 changed files with 40 additions and 5 deletions

View file

@ -49,15 +49,23 @@ func (w *Wallet) handleChainNotifications() {
" might take a while", height)
err := walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
startBlock := w.Manager.SyncedTo()
for i := startBlock.Height + 1; i <= height; i++ {
hash, err := client.GetBlockHash(int64(i))
if err != nil {
return err
}
header, err := chainClient.GetBlockHeader(hash)
if err != nil {
return err
}
bs := waddrmgr.BlockStamp{
Height: i,
Hash: *hash,
Height: i,
Hash: *hash,
Timestamp: header.Timestamp,
}
err = w.Manager.SetSyncedTo(ns, &bs)
if err != nil {
@ -70,6 +78,7 @@ func (w *Wallet) handleChainNotifications() {
log.Errorf("Failed to update address manager "+
"sync state for height %d: %v", height, err)
}
log.Info("Done catching up block hashes")
return err
}

View file

@ -355,29 +355,35 @@ func (w *Wallet) syncWithChain() error {
if err != nil {
return err
}
checkHeight := bestHeight
if len(w.chainParams.Checkpoints) > 0 {
checkHeight = w.chainParams.Checkpoints[len(
w.chainParams.Checkpoints)-1].Height
}
logHeight := checkHeight
if bestHeight > logHeight {
logHeight = bestHeight
}
log.Infof("Catching up block hashes to height %d, this will "+
"take a while...", logHeight)
// Initialize the first database transaction.
tx, err := w.db.BeginReadWriteTx()
if err != nil {
return err
}
ns := tx.ReadWriteBucket(waddrmgrNamespaceKey)
for height := int32(1); height <= bestHeight; height++ {
hash, err := chainClient.GetBlockHash(int64(height))
if err != nil {
tx.Rollback()
return err
}
// If we've found the best height the backend knows
// about, but we haven't reached the last checkpoint, we
// know the backend is still synchronizing. We can give
@ -392,6 +398,7 @@ func (w *Wallet) syncWithChain() error {
tx.Rollback()
return err
}
// If we're using the Neutrino backend, we can
// check if it's current or not. If it's not and
// we've exceeded the original checkHeight, we
@ -408,14 +415,22 @@ func (w *Wallet) syncWithChain() error {
}
}
}
header, err := chainClient.GetBlockHeader(hash)
if err != nil {
return err
}
err = w.Manager.SetSyncedTo(ns, &waddrmgr.BlockStamp{
Hash: *hash,
Height: height,
Hash: *hash,
Height: height,
Timestamp: header.Timestamp,
})
if err != nil {
tx.Rollback()
return err
}
// Every 10K blocks, commit and start a new database TX.
if height%10000 == 0 {
err = tx.Commit()
@ -423,14 +438,18 @@ func (w *Wallet) syncWithChain() error {
tx.Rollback()
return err
}
log.Infof("Caught up to height %d", height)
tx, err = w.db.BeginReadWriteTx()
if err != nil {
return err
}
ns = tx.ReadWriteBucket(waddrmgrNamespaceKey)
}
}
// Commit (or roll back) the final database transaction.
err = tx.Commit()
if err != nil {
@ -470,8 +489,15 @@ func (w *Wallet) syncWithChain() error {
if err != nil {
return err
}
header, err := chainClient.GetBlockHeader(hash)
if err != nil {
return err
}
rollbackStamp.Hash = *chainHash
rollbackStamp.Height = height
rollbackStamp.Timestamp = header.Timestamp
if bytes.Equal(hash[:], chainHash[:]) {
break
}
@ -1986,9 +2012,9 @@ func (w *Wallet) ImportPrivateKey(scope waddrmgr.KeyScope, wif *btcutil.WIF,
Height: 0,
}
} else {
header, err := w.chainClient.GetBlockHeader(&bs.Hash)
// Only update the new birthday time from default value if we
// actually have timestamp info in the header.
header, err := w.chainClient.GetBlockHeader(&bs.Hash)
if err == nil {
newBirthday = header.Timestamp
}