Skip to content
Browse files
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.
  • Loading branch information
wpaulino committed Jun 14, 2019
1 parent 39f81c6 commit 17efcdba2fc05889b8157f436d44b120e5fb01b1
Showing with 36 additions and 6 deletions.
  1. +36 −6 wallet/wallet.go
@@ -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
// properly detect if it gets rolled back.
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 {
var err error
birthdayStamp, err = w.syncToBirthday()
@@ -357,11 +372,6 @@ func (w *Wallet) syncWithChain(birthdayStamp *waddrmgr.BlockStamp) error {
// before catching up with the rescan.
rollback := false
rollbackStamp := w.Manager.SyncedTo()
chainClient, err := w.requireChainClient()
if err != nil {
return err

err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error {
addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)
txmgrNs := tx.ReadWriteBucket(wtxmgrNamespaceKey)
@@ -467,6 +477,26 @@ func (w *Wallet) isDevEnv() bool {
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
// 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.

0 comments on commit 17efcdb

Please sign in to comment.