accounts: fix data race when closing manager #31982 (#1423)

Fixes a data race on the `wallets` slice when closing account Manager.

At the moment, there is a data race between a go-routine calling the
Manager's `Close` function and the background go-routine handling most
operations on the `Manager`. The `Manager`'s `wallets` field is accessed
without proper synchronization.

By moving the closing of wallets from the `Close()` function into the
background thread, this issue can be resolved.

Co-authored-by: Herbert <herbert.jordan.jun@gmail.com>
This commit is contained in:
Daniel Liu 2025-09-03 15:49:24 +08:00 committed by GitHub
parent b6f28effa9
commit aec5f28dab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -98,9 +98,6 @@ func NewManager(config *Config, backends ...Backend) *Manager {
// Close terminates the account manager's internal notification processes.
func (am *Manager) Close() error {
for _, w := range am.wallets {
w.Close()
}
errc := make(chan error)
am.quit <- errc
return <-errc
@ -159,6 +156,10 @@ func (am *Manager) update() {
am.lock.Unlock()
close(event.processed)
case errc := <-am.quit:
// Close all owned wallets
for _, w := range am.wallets {
w.Close()
}
// Manager terminating, return
errc <- nil
// Signals event emitters the loop is not receiving values