Skip to content

Commit f1b75b8

Browse files
committed
backend/account: fix bugs in account discovery
Recent commit 726289c made the account Initialization asynchronous, moving the `account.ensureAddresses()` call on a separate thread. This caused a regression inside `backend.checkAccountUsed()` where the method wasn't waiting for the complete account synchronization before marking it as used. This commit fixes the issue waiting for account sync before checking if it used. This also fixes the `backend.Accounts()` method, that was returning the original `backend.accounts` object instead of a copy. This caused the caller to read the account list without a proper lock, causing weird behaviors during account discovery.
1 parent b77cd13 commit f1b75b8

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

backend/accounts.go

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,45 +1533,53 @@ func (backend *Backend) checkAccountUsed(account accounts.Interface) {
15331533
log.WithError(err).Error("error initializing account")
15341534
return
15351535
}
1536-
txs, err := account.Transactions()
1537-
if err != nil {
1538-
log.WithError(err).Error("discoverAccount")
1539-
return
1540-
}
15411536

1542-
if len(txs) == 0 {
1543-
// Invoke this here too because even if an account is unused, we scan up to 5 accounts.
1544-
backend.maybeAddHiddenUnusedAccounts()
1545-
return
1546-
}
1547-
log.Info("marking account as used")
1548-
err = backend.config.ModifyAccountsConfig(func(accountsConfig *config.AccountsConfig) error {
1549-
acct := accountsConfig.Lookup(account.Config().Config.Code)
1550-
if acct == nil {
1551-
return errp.Newf("could not find account")
1537+
f := func() {
1538+
txs, err := account.Transactions()
1539+
if err != nil {
1540+
log.WithError(err).Error("discoverAccount")
1541+
return
15521542
}
1553-
acct.Used = true
1554-
acct.HiddenBecauseUnused = false
15551543

1556-
// We only really show the account to the user now, so this is the moment to set the
1557-
// watchonly flag on it if the user has the accont's keystore's watchonly setting enabled.
1558-
rootFingerprint, err := acct.SigningConfigurations.RootFingerprint()
1544+
if len(txs) == 0 {
1545+
// Invoke this here too because even if an account is unused, we scan up to 5 accounts.
1546+
backend.maybeAddHiddenUnusedAccounts()
1547+
return
1548+
}
1549+
log.Info("marking account as used")
1550+
err = backend.config.ModifyAccountsConfig(func(accountsConfig *config.AccountsConfig) error {
1551+
acct := accountsConfig.Lookup(account.Config().Config.Code)
1552+
if acct == nil {
1553+
return errp.Newf("could not find account")
1554+
}
1555+
acct.Used = true
1556+
acct.HiddenBecauseUnused = false
1557+
1558+
// We only really show the account to the user now, so this is the moment to set the
1559+
// watchonly flag on it if the user has the accont's keystore's watchonly setting enabled.
1560+
rootFingerprint, err := acct.SigningConfigurations.RootFingerprint()
1561+
if err != nil {
1562+
return err
1563+
}
1564+
if accountsConfig.IsKeystoreWatchonly(rootFingerprint) {
1565+
t := true
1566+
acct.Watch = &t
1567+
}
1568+
1569+
return nil
1570+
})
15591571
if err != nil {
1560-
return err
1572+
log.WithError(err).Error("checkAccountUsed")
1573+
return
15611574
}
1562-
if accountsConfig.IsKeystoreWatchonly(rootFingerprint) {
1563-
t := true
1564-
acct.Watch = &t
1575+
backend.emitAccountsStatusChanged()
1576+
backend.maybeAddHiddenUnusedAccounts()
1577+
}
1578+
account.Observe(func(event observable.Event) {
1579+
if event.Subject == string(accountsTypes.EventSyncDone) {
1580+
f()
15651581
}
1566-
1567-
return nil
15681582
})
1569-
if err != nil {
1570-
log.WithError(err).Error("checkAccountUsed")
1571-
return
1572-
}
1573-
backend.emitAccountsStatusChanged()
1574-
backend.maybeAddHiddenUnusedAccounts()
15751583
}
15761584

15771585
// LookupEthAccountCode takes an Ethereum address and returns the corresponding account code and account name

backend/backend.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,9 @@ func (backend *Backend) Testing() bool {
590590
// Accounts returns the current accounts of the backend.
591591
func (backend *Backend) Accounts() AccountsList {
592592
defer backend.accountsAndKeystoreLock.RLock()()
593-
return backend.accounts
593+
accounts := AccountsList{}
594+
accounts = append(accounts, backend.accounts...)
595+
return accounts
594596
}
595597

596598
// KeystoreTotalAmount represents the total balance amount of the accounts belonging to a keystore.

0 commit comments

Comments
 (0)