diff --git a/wallet/wallet.go b/wallet/wallet.go index 2259ecb..db9174d 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -450,6 +450,18 @@ func (w *Wallet) syncWithChain(birthdayStamp *waddrmgr.BlockStamp) error { return w.rescanWithTarget(addrs, unspent, nil) } +// isDevEnv determines whether the wallet is currently under a local developer +// environment, e.g. simnet or regtest. +func (w *Wallet) isDevEnv() bool { + switch uint32(w.ChainParams().Net) { + case uint32(chaincfg.RegressionNetParams.Net): + case uint32(chaincfg.SimNetParams.Net): + default: + return false + } + return true +} + // 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. @@ -463,7 +475,7 @@ func (w *Wallet) scanChain(startHeight int32, // isCurrent is a helper function that we'll use to determine if the // chain backend is currently synced. When running with a btcd or - // bitcoind backend, It will use the height of the latest checkpoint as + // bitcoind backend, it will use the height of the latest checkpoint as // its lower bound. var latestCheckptHeight int32 if len(w.chainParams.Checkpoints) > 0 { @@ -471,9 +483,10 @@ func (w *Wallet) scanChain(startHeight int32, Checkpoints[len(w.chainParams.Checkpoints)-1].Height } isCurrent := func(bestHeight int32) bool { - // If the best height is zero, we assume the chain backend - // still is looking for peers to sync to. - if bestHeight == 0 { + // If the best height is zero, we assume the chain backend is + // still looking for peers to sync to in the case of a global + // network, e.g., testnet and mainnet. + if bestHeight == 0 && !w.isDevEnv() { return false } @@ -599,13 +612,26 @@ func (w *Wallet) syncToBirthday() (*waddrmgr.BlockStamp, error) { } // If a birthday stamp has yet to be found, we'll return an error - // indicating so. - if birthdayStamp == nil { + // indicating so, but only if this is a live chain like it is the case + // with testnet and mainnet. + if birthdayStamp == nil && !w.isDevEnv() { tx.Rollback() return nil, fmt.Errorf("did not find a suitable birthday "+ "block with a timestamp greater than %v", birthday) } + // Otherwise, if we're in a development environment and we've yet to + // find a birthday block due to the chain not being current, we'll + // use the last block we've synced to as our birthday to proceed. + if birthdayStamp == nil { + syncedTo := w.Manager.SyncedTo() + err := w.Manager.SetBirthdayBlock(ns, syncedTo, true) + if err != nil { + return nil, err + } + birthdayStamp = &syncedTo + } + if err := tx.Commit(); err != nil { tx.Rollback() return nil, err