Skip to content

Commit

Permalink
wallet: wait until chain backend is current to begin wallet sync
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wpaulino committed Jun 14, 2019
1 parent 39f81c6 commit 17efcdb
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions wallet/wallet.go
Expand Up @@ -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()
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 17efcdb

Please sign in to comment.