wallet: wait until chain backend is current to begin wallet sync
This serves as groundwork for only storing up to MaxReorgDepth blocks upon initial sync. To do so, we want to make sure the chain backend considers itself current so that we can only fetch the latest MaxReorgDepth blocks from it.
This commit is contained in:
parent
39f81c630b
commit
17efcdba2f
1 changed files with 36 additions and 6 deletions
|
@ -327,7 +327,22 @@ func (w *Wallet) activeData(dbtx walletdb.ReadTx) ([]btcutil.Address, []wtxmgr.C
|
||||||
// finished. The birthday block can be passed in, if set, to ensure we can
|
// finished. The birthday block can be passed in, if set, to ensure we can
|
||||||
// properly detect if it gets rolled back.
|
// properly detect if it gets rolled back.
|
||||||
func (w *Wallet) syncWithChain(birthdayStamp *waddrmgr.BlockStamp) error {
|
func (w *Wallet) syncWithChain(birthdayStamp *waddrmgr.BlockStamp) error {
|
||||||
// To start, if we've yet to find our birthday stamp, we'll do so now.
|
chainClient, err := w.requireChainClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We'll wait until the backend is synced to ensure we get the latest
|
||||||
|
// MaxReorgDepth blocks to store. We don't do this for development
|
||||||
|
// environments as we can't guarantee a lively chain.
|
||||||
|
if !w.isDevEnv() {
|
||||||
|
log.Debug("Waiting for chain backend to sync to tip")
|
||||||
|
if err := w.waitUntilBackendSynced(chainClient); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug("Chain backend synced to tip!")
|
||||||
|
}
|
||||||
|
|
||||||
if birthdayStamp == nil {
|
if birthdayStamp == nil {
|
||||||
var err error
|
var err error
|
||||||
birthdayStamp, err = w.syncToBirthday()
|
birthdayStamp, err = w.syncToBirthday()
|
||||||
|
@ -357,11 +372,6 @@ func (w *Wallet) syncWithChain(birthdayStamp *waddrmgr.BlockStamp) error {
|
||||||
// before catching up with the rescan.
|
// before catching up with the rescan.
|
||||||
rollback := false
|
rollback := false
|
||||||
rollbackStamp := w.Manager.SyncedTo()
|
rollbackStamp := w.Manager.SyncedTo()
|
||||||
chainClient, err := w.requireChainClient()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
|
||||||
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
|
||||||
txmgrNs := tx.ReadWriteBucket(wtxmgrNamespaceKey)
|
txmgrNs := tx.ReadWriteBucket(wtxmgrNamespaceKey)
|
||||||
|
@ -467,6 +477,26 @@ func (w *Wallet) isDevEnv() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// waitUntilBackendSynced blocks until the chain backend considers itself
|
||||||
|
// "current".
|
||||||
|
func (w *Wallet) waitUntilBackendSynced(chainClient chain.Interface) error {
|
||||||
|
// We'll poll every second to determine if our chain considers itself
|
||||||
|
// "current".
|
||||||
|
t := time.NewTicker(time.Second)
|
||||||
|
defer t.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-t.C:
|
||||||
|
if chainClient.IsCurrent() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case <-w.quitChan():
|
||||||
|
return ErrWalletShuttingDown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// scanChain is a helper method that scans the chain from the starting height
|
// scanChain is a helper method that scans the chain from the starting height
|
||||||
// until the tip of the chain. The onBlock callback can be used to perform
|
// until the tip of the chain. The onBlock callback can be used to perform
|
||||||
// certain operations for every block that we process as we scan the chain.
|
// certain operations for every block that we process as we scan the chain.
|
||||||
|
|
Loading…
Reference in a new issue