Skip to content

Commit ab26beb

Browse files
committed
Merge branch 'accountslock'
2 parents cfa756c + aad518e commit ab26beb

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

backend/backend.go

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,11 @@ func NewBackend(arguments *arguments.Arguments, environment Environment) (*Backe
208208

209209
// configureHistoryExchangeRates changes backend.ratesUpdater settings.
210210
// It requires both backend.config to be up-to-date and all accounts initialized.
211+
//
212+
// The accountsLock must be held when calling this function.
211213
func (backend *Backend) configureHistoryExchangeRates() {
212214
var coins []string
213-
for _, acct := range backend.Accounts() {
215+
for _, acct := range backend.accounts {
214216
coins = append(coins, string(acct.Coin().Code()))
215217
}
216218
// No reason continue with ERC20 tokens if Ethereum is inactive.
@@ -227,8 +229,8 @@ func (backend *Backend) configureHistoryExchangeRates() {
227229
}
228230

229231
// addAccount adds the given account to the backend.
232+
// The accountsLock must be held when calling this function.
230233
func (backend *Backend) addAccount(account accounts.Interface) {
231-
defer backend.accountsLock.Lock()()
232234
backend.accounts = append(backend.accounts, account)
233235
account.Observe(backend.Notify)
234236
backend.onAccountInit(account)
@@ -264,9 +266,8 @@ func (backend *Backend) emitAccountsStatusChanged() {
264266
})
265267
}
266268

267-
// CreateAndAddAccount creates an account with the given parameters and adds it to the backend. If
268-
// persist is true, the configuration is fetched and saved in the accounts configuration.
269-
func (backend *Backend) CreateAndAddAccount(
269+
// The accountsLock must be held when calling this function.
270+
func (backend *Backend) createAndAddAccount(
270271
coin coin.Coin,
271272
code string,
272273
name string,
@@ -345,6 +346,20 @@ func (backend *Backend) CreateAndAddAccount(
345346
return nil
346347
}
347348

349+
// CreateAndAddAccount creates an account with the given parameters and adds it to the backend. If
350+
// persist is true, the configuration is fetched and saved in the accounts configuration.
351+
func (backend *Backend) CreateAndAddAccount(
352+
coin coin.Coin,
353+
code string,
354+
name string,
355+
getSigningConfigurations func() (signing.Configurations, error),
356+
persist bool,
357+
emitEvent bool,
358+
) error {
359+
defer backend.accountsLock.Lock()()
360+
return backend.createAndAddAccount(coin, code, name, getSigningConfigurations, persist, emitEvent)
361+
}
362+
348363
type scriptTypeWithKeypath struct {
349364
scriptType signing.ScriptType
350365
keypath signing.AbsoluteKeypath
@@ -364,6 +379,8 @@ func newScriptTypeWithKeypath(scriptType signing.ScriptType, keypath string) scr
364379
// adds a combined BTC account with the given script types. If the keystore requires split accounts
365380
// (bitbox01) or the user configure split accounts in the settings, one account per script type is
366381
// added instead of a combined account.
382+
//
383+
// The accountsLock must be held when calling this function.
367384
func (backend *Backend) createAndAddBTCAccount(
368385
keystore keystore.Keystore,
369386
coin coin.Coin,
@@ -420,7 +437,7 @@ func (backend *Backend) createAndAddBTCAccount(
420437
case signing.ScriptTypeP2WPKH:
421438
suffixedName += ": bech32"
422439
}
423-
err := backend.CreateAndAddAccount(
440+
err := backend.createAndAddAccount(
424441
coin,
425442
fmt.Sprintf("%s-%s", code, cfg.scriptType),
426443
suffixedName,
@@ -443,13 +460,14 @@ func (backend *Backend) createAndAddBTCAccount(
443460
}
444461
return result, nil
445462
}
446-
err := backend.CreateAndAddAccount(coin, code, name, getSigningConfigurations, false, false)
463+
err := backend.createAndAddAccount(coin, code, name, getSigningConfigurations, false, false)
447464
if err != nil {
448465
panic(err)
449466
}
450467
}
451468
}
452469

470+
// The accountsLock must be held when calling this function.
453471
func (backend *Backend) createAndAddETHAccount(
454472
keystore keystore.Keystore,
455473
coin coin.Coin,
@@ -493,7 +511,7 @@ func (backend *Backend) createAndAddETHAccount(
493511
),
494512
}, nil
495513
}
496-
err = backend.CreateAndAddAccount(coin, code, name, getSigningConfigurations, false, false)
514+
err = backend.createAndAddAccount(coin, code, name, getSigningConfigurations, false, false)
497515
if err != nil {
498516
panic(err)
499517
}
@@ -660,6 +678,7 @@ func (backend *Backend) Coin(code coinpkg.Code) (coin.Coin, error) {
660678
return coin, nil
661679
}
662680

681+
// The accountsLock must be held when calling this function.
663682
func (backend *Backend) initPersistedAccounts() {
664683
for _, account := range backend.config.AccountsConfig().Accounts {
665684
account := account
@@ -677,7 +696,7 @@ func (backend *Backend) initPersistedAccounts() {
677696
getSigningConfigurations := func() (signing.Configurations, error) {
678697
return signing.Configurations{account.Configuration}, nil
679698
}
680-
err = backend.CreateAndAddAccount(coin, account.Code, account.Name, getSigningConfigurations, false, false)
699+
err = backend.createAndAddAccount(coin, account.Code, account.Name, getSigningConfigurations, false, false)
681700
if err != nil {
682701
panic(err)
683702
}
@@ -686,6 +705,8 @@ func (backend *Backend) initPersistedAccounts() {
686705

687706
// initDefaultAccounts creates a bunch of default accounts for a set of keystores (not manually
688707
// user-added). Currently the first bip44 account for all supported and active account types.
708+
//
709+
// The accountsLock must be held when calling this function.
689710
func (backend *Backend) initDefaultAccounts() {
690711
if backend.keystores.Count() == 0 {
691712
return
@@ -765,6 +786,7 @@ func (backend *Backend) initDefaultAccounts() {
765786
}
766787
}
767788

789+
// The accountsLock must be held when calling this function.
768790
func (backend *Backend) initAccounts() {
769791
// Since initAccounts replaces all previous accounts, we need to properly close them first.
770792
backend.uninitAccounts()
@@ -785,6 +807,8 @@ func (backend *Backend) initAccounts() {
785807
// if the configuration changed (e.g. which accounts are active). This is a stopgap measure until
786808
// accounts can be added and removed individually.
787809
func (backend *Backend) ReinitializeAccounts() {
810+
defer backend.accountsLock.Lock()()
811+
788812
backend.log.Info("Reinitializing accounts")
789813
backend.initAccounts()
790814
}
@@ -796,6 +820,7 @@ func (backend *Backend) Testing() bool {
796820

797821
// Accounts returns the current accounts of the backend.
798822
func (backend *Backend) Accounts() []accounts.Interface {
823+
defer backend.accountsLock.RLock()()
799824
return backend.accounts
800825
}
801826

@@ -852,6 +877,8 @@ func (backend *Backend) Start() <-chan interface{} {
852877
if backend.arguments.DevMode() {
853878
backend.baseManager.Start()
854879
}
880+
881+
defer backend.accountsLock.Lock()()
855882
backend.initPersistedAccounts()
856883
backend.emitAccountsStatusChanged()
857884

@@ -932,8 +959,8 @@ func (backend *Backend) BitBoxBaseDeregister(bitboxBaseID string) {
932959
backend.events <- backendEvent{Type: "bitboxbases", Data: "registeredChanged"}
933960
}
934961

962+
// The accountsLock must be held when calling this function.
935963
func (backend *Backend) uninitAccounts() {
936-
defer backend.accountsLock.Lock()()
937964
for _, account := range backend.accounts {
938965
account := account
939966
backend.onAccountUninit(account)
@@ -960,6 +987,8 @@ func (backend *Backend) RegisterKeystore(keystore keystore.Keystore) {
960987
if backend.arguments.Multisig() && backend.keystores.Count() != 2 {
961988
return
962989
}
990+
991+
defer backend.accountsLock.Lock()()
963992
backend.initAccounts()
964993
}
965994

@@ -971,6 +1000,9 @@ func (backend *Backend) DeregisterKeystore() {
9711000
Subject: "keystores",
9721001
Action: action.Reload,
9731002
})
1003+
1004+
defer backend.accountsLock.Lock()()
1005+
9741006
backend.uninitAccounts()
9751007
// TODO: classify accounts by keystore, remove only the ones belonging to the deregistered
9761008
// keystore. For now we just remove all, then re-add the rest.
@@ -1152,9 +1184,12 @@ func (backend *Backend) Environment() Environment {
11521184

11531185
// Close shuts down the backend. After this, no other method should be called.
11541186
func (backend *Backend) Close() error {
1187+
defer backend.accountsLock.Lock()()
1188+
11551189
errors := []string{}
11561190

11571191
backend.ratesUpdater.Stop()
1192+
11581193
backend.uninitAccounts()
11591194

11601195
for _, coin := range backend.coins {

0 commit comments

Comments
 (0)