Skip to content

Commit febfa4d

Browse files
committed
maintenance: only check if an account is used if not already set.
When an account is set as used, there is no more need to check it again. By exiting early if an account is already used, we avoid a call to Transactions().
1 parent bdcfc0d commit febfa4d

File tree

2 files changed

+71
-10
lines changed

2 files changed

+71
-10
lines changed

backend/accounts.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,20 +1722,23 @@ func (backend *Backend) checkAccountUsed(account accounts.Interface) {
17221722
return
17231723
}
17241724
}
1725+
17251726
log := backend.log.WithField("accountCode", account.Config().Config.Code)
1726-
txs, err := account.Transactions()
1727-
if err != nil {
1728-
log.WithError(err).Error("discoverAccount")
1729-
return
1730-
}
1727+
if !account.Config().Config.Used {
1728+
txs, err := account.Transactions()
1729+
if err != nil {
1730+
log.WithError(err).Error("discoverAccount")
1731+
return
1732+
}
17311733

1732-
if len(txs) == 0 {
1733-
// Invoke this here too because even if an account is unused, we scan up to 5 accounts.
1734-
backend.maybeAddHiddenUnusedAccounts()
1735-
return
1734+
if len(txs) == 0 {
1735+
// Invoke this here too because even if an account is unused, we scan up to 5 accounts.
1736+
backend.maybeAddHiddenUnusedAccounts()
1737+
return
1738+
}
17361739
}
17371740
log.Info("marking account as used")
1738-
err = backend.config.ModifyAccountsConfig(func(accountsConfig *config.AccountsConfig) error {
1741+
err := backend.config.ModifyAccountsConfig(func(accountsConfig *config.AccountsConfig) error {
17391742
acct := accountsConfig.Lookup(account.Config().Config.Code)
17401743
if acct == nil {
17411744
return errp.Newf("could not find account")

backend/accounts_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"time"
2323

2424
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts"
25+
accountsMocks "github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/mocks"
2526
accountsTypes "github.com/BitBoxSwiss/bitbox-wallet-app/backend/accounts/types"
2627
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc"
2728
"github.com/BitBoxSwiss/bitbox-wallet-app/backend/coins/btc/addresses"
@@ -1676,3 +1677,60 @@ func TestAccountsFiatAndCoinBalance(t *testing.T) {
16761677
}
16771678

16781679
}
1680+
1681+
func TestCheckAccountUsed(t *testing.T) {
1682+
b := newBackend(t, testnetDisabled, regtestDisabled)
1683+
b.tstCheckAccountUsed = nil
1684+
defer b.Close()
1685+
accountMocks := map[accountsTypes.Code]*accountsMocks.InterfaceMock{}
1686+
// A Transactions function that always returns one transaction, so the account is always used.
1687+
txFunc := func() (accounts.OrderedTransactions, error) {
1688+
return accounts.OrderedTransactions{&accounts.TransactionData{}}, nil
1689+
}
1690+
1691+
b.makeBtcAccount = func(config *accounts.AccountConfig, coin *btc.Coin, gapLimits *types.GapLimits, getAddress func(coinpkg.Code, blockchain.ScriptHashHex) (*addresses.AccountAddress, error), log *logrus.Entry) accounts.Interface {
1692+
accountMock := MockBtcAccount(t, config, coin, gapLimits, log)
1693+
accountMock.TransactionsFunc = txFunc
1694+
accountMocks[config.Config.Code] = accountMock
1695+
return accountMock
1696+
}
1697+
1698+
b.makeEthAccount = func(config *accounts.AccountConfig, coin *eth.Coin, httpClient *http.Client, log *logrus.Entry) accounts.Interface {
1699+
accountMock := MockEthAccount(config, coin, httpClient, log)
1700+
accountMock.TransactionsFunc = txFunc
1701+
accountMocks[config.Config.Code] = accountMock
1702+
return accountMock
1703+
}
1704+
1705+
ks1 := makeBitBox02Multi()
1706+
1707+
ks1Fingerprint, err := ks1.RootFingerprint()
1708+
require.NoError(t, err)
1709+
1710+
b.registerKeystore(ks1)
1711+
require.NoError(t, b.SetWatchonly(ks1Fingerprint, true))
1712+
1713+
accountsByKestore, err := b.AccountsByKeystore()
1714+
require.NoError(t, err)
1715+
1716+
accountList, ok := accountsByKestore[hex.EncodeToString(ks1Fingerprint)]
1717+
require.True(t, ok, "Expected accounts for keystore with fingerprint %s", hex.EncodeToString(ks1Fingerprint))
1718+
1719+
// Check all accounts, make sure they are set as used.
1720+
for _, acct := range accountList {
1721+
mock, ok := accountMocks[acct.Config().Config.Code]
1722+
require.True(t, ok, "No mock for account %s", acct.Config().Config.Code)
1723+
1724+
b.checkAccountUsed(acct)
1725+
// Ensure that Transactions is called
1726+
require.Len(t, mock.TransactionsCalls(), 1)
1727+
require.True(t, acct.Config().Config.Used)
1728+
1729+
// Call checkAccountUsed again, Transactions should not be called again.
1730+
b.checkAccountUsed(acct)
1731+
require.Len(t, mock.TransactionsCalls(), 1)
1732+
// And Used should still be true.
1733+
require.True(t, acct.Config().Config.Used)
1734+
}
1735+
1736+
}

0 commit comments

Comments
 (0)