waddrmgr+wallet: only watch addresses within default key scopes
It was discovered that the wallet can scan the chain for unnecessary additional addresses that are derived by higher-level applications using custom key scopes. This isn't much of an issue for full nodes, but it can cause light clients to scan more than what's required, triggering more false positive matches which lead to block retrieval. Now, we'll only scan the chain for addresses that exist within the default key scopes, as those are the only ones the wallet should be concerned about.
This commit is contained in:
parent
b19df70ddd
commit
51b362d7c5
2 changed files with 35 additions and 8 deletions
|
@ -748,6 +748,29 @@ func (m *Manager) ForEachAccountAddress(ns walletdb.ReadBucket, account uint32,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEachDefaultScopeActiveAddress calls the given function with each active
|
||||||
|
// address stored in the manager within the default scopes, breaking early on
|
||||||
|
// error.
|
||||||
|
func (m *Manager) ForEachDefaultScopeActiveAddress(ns walletdb.ReadBucket,
|
||||||
|
fn func(addr btcutil.Address) error) error {
|
||||||
|
|
||||||
|
m.mtx.RLock()
|
||||||
|
defer m.mtx.RUnlock()
|
||||||
|
|
||||||
|
for _, keyScope := range DefaultKeyScopes {
|
||||||
|
scopedMgr, ok := m.scopedManagers[keyScope]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("manager for default key scope with "+
|
||||||
|
"purpose %v not found", keyScope.Purpose)
|
||||||
|
}
|
||||||
|
if err := scopedMgr.ForEachActiveAddress(ns, fn); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ChainParams returns the chain parameters for this address manager.
|
// ChainParams returns the chain parameters for this address manager.
|
||||||
func (m *Manager) ChainParams() *chaincfg.Params {
|
func (m *Manager) ChainParams() *chaincfg.Params {
|
||||||
// NOTE: No need for mutex here since the net field does not change
|
// NOTE: No need for mutex here since the net field does not change
|
||||||
|
|
|
@ -303,18 +303,22 @@ func (w *Wallet) SetChainSynced(synced bool) {
|
||||||
w.chainClientSyncMtx.Unlock()
|
w.chainClientSyncMtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// activeData returns the currently-active receiving addresses and all unspent
|
// activeData returns the currently-active receiving addresses that exist within
|
||||||
// outputs. This is primarely intended to provide the parameters for a
|
// the wallet's default key scopes and all unspent outputs. This is primarily
|
||||||
// rescan request.
|
// intended to provide the parameters for a rescan request.
|
||||||
func (w *Wallet) activeData(dbtx walletdb.ReadTx) ([]btcutil.Address, []wtxmgr.Credit, error) {
|
func (w *Wallet) activeData(dbtx walletdb.ReadTx) ([]btcutil.Address,
|
||||||
|
[]wtxmgr.Credit, error) {
|
||||||
|
|
||||||
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
|
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
|
||||||
txmgrNs := dbtx.ReadBucket(wtxmgrNamespaceKey)
|
txmgrNs := dbtx.ReadBucket(wtxmgrNamespaceKey)
|
||||||
|
|
||||||
var addrs []btcutil.Address
|
var addrs []btcutil.Address
|
||||||
err := w.Manager.ForEachActiveAddress(addrmgrNs, func(addr btcutil.Address) error {
|
err := w.Manager.ForEachDefaultScopeActiveAddress(
|
||||||
addrs = append(addrs, addr)
|
addrmgrNs, func(addr btcutil.Address) error {
|
||||||
return nil
|
addrs = append(addrs, addr)
|
||||||
})
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue