mirror of
https://github.com/LBRYFoundation/lbcwallet.git
synced 2025-08-23 17:47:29 +00:00
wallet: move DB access from rescan ntfns into correct goroutine
This commit is contained in:
parent
81a9bb67c1
commit
8e2c741f88
2 changed files with 51 additions and 96 deletions
|
@ -33,6 +33,47 @@ func (w *Wallet) handleChainNotifications() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catchUpHashes := func(w *Wallet, client chain.Interface,
|
||||||
|
height int32) error {
|
||||||
|
// TODO(aakselrod): There's a race conditon here, which
|
||||||
|
// happens when a reorg occurs between the
|
||||||
|
// rescanProgress notification and the last GetBlockHash
|
||||||
|
// call. The solution when using btcd is to make btcd
|
||||||
|
// send blockconnected notifications with each block
|
||||||
|
// the way Neutrino does, and get rid of the loop. The
|
||||||
|
// other alternative is to check the final hash and,
|
||||||
|
// if it doesn't match the original hash returned by
|
||||||
|
// the notification, to roll back and restart the
|
||||||
|
// rescan.
|
||||||
|
log.Infof("Catching up block hashes to height %d, this"+
|
||||||
|
" 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
|
||||||
|
}
|
||||||
|
bs := waddrmgr.BlockStamp{
|
||||||
|
Height: i,
|
||||||
|
Hash: *hash,
|
||||||
|
}
|
||||||
|
err = w.Manager.SetSyncedTo(ns, &bs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to update address manager "+
|
||||||
|
"sync state for height %d: %v", height, err)
|
||||||
|
}
|
||||||
|
log.Info("Done catching up block hashes")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for n := range chainClient.Notifications() {
|
for n := range chainClient.Notifications() {
|
||||||
var notificationName string
|
var notificationName string
|
||||||
var err error
|
var err error
|
||||||
|
@ -72,9 +113,16 @@ func (w *Wallet) handleChainNotifications() {
|
||||||
}
|
}
|
||||||
notificationName = "filteredblockconnected"
|
notificationName = "filteredblockconnected"
|
||||||
|
|
||||||
// The following are handled by the wallet's rescan
|
// The following require some database maintenance, but also
|
||||||
// goroutines, so just pass them there.
|
// need to be reported to the wallet's rescan goroutine.
|
||||||
case *chain.RescanProgress, *chain.RescanFinished:
|
case *chain.RescanProgress:
|
||||||
|
err = catchUpHashes(w, chainClient, n.Height)
|
||||||
|
notificationName = "rescanprogress"
|
||||||
|
w.rescanNotifications <- n
|
||||||
|
case *chain.RescanFinished:
|
||||||
|
err = catchUpHashes(w, chainClient, n.Height)
|
||||||
|
notificationName = "rescanprogress"
|
||||||
|
w.SetChainSynced(true)
|
||||||
w.rescanNotifications <- n
|
w.rescanNotifications <- n
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
"github.com/roasbeef/btcwallet/chain"
|
"github.com/roasbeef/btcwallet/chain"
|
||||||
"github.com/roasbeef/btcwallet/waddrmgr"
|
"github.com/roasbeef/btcwallet/waddrmgr"
|
||||||
"github.com/roasbeef/btcwallet/walletdb"
|
|
||||||
"github.com/roasbeef/btcwallet/wtxmgr"
|
"github.com/roasbeef/btcwallet/wtxmgr"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -175,51 +174,6 @@ out:
|
||||||
log.Infof("Rescanned through block %v (height %d)",
|
log.Infof("Rescanned through block %v (height %d)",
|
||||||
n.Hash, n.Height)
|
n.Hash, n.Height)
|
||||||
|
|
||||||
client := w.ChainClient()
|
|
||||||
// Since btcd rescans don't send blockconnected
|
|
||||||
// notifications, we need to cycle through all of the
|
|
||||||
// rescanned blocks and write the hashes to the
|
|
||||||
// database. Neutrino rescans do send the notifications,
|
|
||||||
// which means this loop won't actually cycle.
|
|
||||||
//
|
|
||||||
// TODO(aakselrod): There's a race conditon here, which
|
|
||||||
// happens when a reorg occurs between the
|
|
||||||
// rescanProgress notification and the last GetBlockHash
|
|
||||||
// call. The solution when using btcd is to make btcd
|
|
||||||
// send blockconnected notifications with each block
|
|
||||||
// the way Neutrino does, and get rid of the loop. The
|
|
||||||
// other alternative is to check the final hash and,
|
|
||||||
// if it doesn't match the original hash returned by
|
|
||||||
// the notification, to roll back and restart the
|
|
||||||
// rescan.
|
|
||||||
log.Infof("Catching up block hashes to height %d, this"+
|
|
||||||
" might take a while", n.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 <= n.Height; i++ {
|
|
||||||
hash, err := client.GetBlockHash(int64(i))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bs := waddrmgr.BlockStamp{
|
|
||||||
Height: i,
|
|
||||||
Hash: *hash,
|
|
||||||
}
|
|
||||||
err = w.Manager.SetSyncedTo(ns, &bs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to update address manager "+
|
|
||||||
"sync state for hash %v (height %d): %v",
|
|
||||||
n.Hash, n.Height, err)
|
|
||||||
}
|
|
||||||
log.Info("Done catching up block hashes")
|
|
||||||
|
|
||||||
case msg := <-w.rescanFinished:
|
case msg := <-w.rescanFinished:
|
||||||
n := msg.Notification
|
n := msg.Notification
|
||||||
addrs := msg.Addresses
|
addrs := msg.Addresses
|
||||||
|
@ -228,53 +182,6 @@ out:
|
||||||
"%s, height %d)", len(addrs), noun, n.Hash,
|
"%s, height %d)", len(addrs), noun, n.Hash,
|
||||||
n.Height)
|
n.Height)
|
||||||
|
|
||||||
client := w.ChainClient()
|
|
||||||
// Since btcd rescans don't send blockconnected
|
|
||||||
// notifications, we need to cycle through all of the
|
|
||||||
// rescanned blocks and write the hashes to the
|
|
||||||
// database. Neutrino rescans do send the notifications,
|
|
||||||
// which means this loop won't actually cycle.
|
|
||||||
//
|
|
||||||
// TODO(aakselrod): There's a race conditon here, which
|
|
||||||
// happens when a reorg occurs between the
|
|
||||||
// rescanFinished notification and the last GetBlockHash
|
|
||||||
// call. The solution when using btcd is to make btcd
|
|
||||||
// send blockconnected notifications with each block
|
|
||||||
// the way Neutrino does, and get rid of the loop. The
|
|
||||||
// other alternative is to check the final hash and,
|
|
||||||
// if it doesn't match the original hash returned by
|
|
||||||
// the notification, to roll back and restart the
|
|
||||||
// rescan.
|
|
||||||
log.Infof("Catching up block hashes to height %d, this"+
|
|
||||||
" might take a while", n.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 <= n.Height; i++ {
|
|
||||||
hash, err := client.GetBlockHash(int64(i))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
bs := waddrmgr.BlockStamp{
|
|
||||||
Height: i,
|
|
||||||
Hash: *hash,
|
|
||||||
}
|
|
||||||
err = w.Manager.SetSyncedTo(ns, &bs)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to update address manager "+
|
|
||||||
"sync state for hash %v (height %d): %v",
|
|
||||||
n.Hash, n.Height, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
w.SetChainSynced(true)
|
|
||||||
log.Info("Done catching up block hashes")
|
|
||||||
go w.resendUnminedTxs()
|
go w.resendUnminedTxs()
|
||||||
|
|
||||||
case <-quit:
|
case <-quit:
|
||||||
|
|
Loading…
Add table
Reference in a new issue