waddrmgr: fix deadlock bug by using read mutex when necessary

In this commit, we fix a deadlock bug that was introduced recently.
This can happen when ForEachActiveAccountAddress or
ForEachActiveAddress is called, as these internally need to grab the
mutex of the manager (within the scoped manager) in order to check if
the manager is locked or not.
This commit is contained in:
Olaoluwa Osuntokun 2018-02-19 18:31:29 -08:00
parent d42a45f16f
commit 27dfed7f27

View file

@ -686,8 +686,8 @@ func (m *Manager) ForEachActiveAccountAddress(ns walletdb.ReadBucket,
// ForEachActiveAddress calls the given function with each active address // ForEachActiveAddress calls the given function with each active address
// stored in the manager, breaking early on error. // stored in the manager, breaking early on error.
func (m *Manager) ForEachActiveAddress(ns walletdb.ReadBucket, fn func(addr btcutil.Address) error) error { func (m *Manager) ForEachActiveAddress(ns walletdb.ReadBucket, fn func(addr btcutil.Address) error) error {
m.mtx.Lock() m.mtx.RLock()
defer m.mtx.Unlock() defer m.mtx.RUnlock()
for _, scopedMgr := range m.scopedManagers { for _, scopedMgr := range m.scopedManagers {
err := scopedMgr.ForEachActiveAddress(ns, fn) err := scopedMgr.ForEachActiveAddress(ns, fn)
@ -704,8 +704,8 @@ func (m *Manager) ForEachActiveAddress(ns walletdb.ReadBucket, fn func(addr btcu
func (m *Manager) ForEachAccountAddress(ns walletdb.ReadBucket, account uint32, func (m *Manager) ForEachAccountAddress(ns walletdb.ReadBucket, account uint32,
fn func(maddr ManagedAddress) error) error { fn func(maddr ManagedAddress) error) error {
m.mtx.Lock() m.mtx.RLock()
defer m.mtx.Unlock() defer m.mtx.RUnlock()
for _, scopedMgr := range m.scopedManagers { for _, scopedMgr := range m.scopedManagers {
err := scopedMgr.ForEachAccountAddress(ns, account, fn) err := scopedMgr.ForEachAccountAddress(ns, account, fn)