@@ -208,9 +208,11 @@ func NewBackend(arguments *arguments.Arguments, environment Environment) (*Backe
208
208
209
209
// configureHistoryExchangeRates changes backend.ratesUpdater settings.
210
210
// 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.
211
213
func (backend * Backend ) configureHistoryExchangeRates () {
212
214
var coins []string
213
- for _ , acct := range backend .Accounts () {
215
+ for _ , acct := range backend .accounts {
214
216
coins = append (coins , string (acct .Coin ().Code ()))
215
217
}
216
218
// No reason continue with ERC20 tokens if Ethereum is inactive.
@@ -227,8 +229,8 @@ func (backend *Backend) configureHistoryExchangeRates() {
227
229
}
228
230
229
231
// addAccount adds the given account to the backend.
232
+ // The accountsLock must be held when calling this function.
230
233
func (backend * Backend ) addAccount (account accounts.Interface ) {
231
- defer backend .accountsLock .Lock ()()
232
234
backend .accounts = append (backend .accounts , account )
233
235
account .Observe (backend .Notify )
234
236
backend .onAccountInit (account )
@@ -264,9 +266,8 @@ func (backend *Backend) emitAccountsStatusChanged() {
264
266
})
265
267
}
266
268
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 (
270
271
coin coin.Coin ,
271
272
code string ,
272
273
name string ,
@@ -345,6 +346,20 @@ func (backend *Backend) CreateAndAddAccount(
345
346
return nil
346
347
}
347
348
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
+
348
363
type scriptTypeWithKeypath struct {
349
364
scriptType signing.ScriptType
350
365
keypath signing.AbsoluteKeypath
@@ -364,6 +379,8 @@ func newScriptTypeWithKeypath(scriptType signing.ScriptType, keypath string) scr
364
379
// adds a combined BTC account with the given script types. If the keystore requires split accounts
365
380
// (bitbox01) or the user configure split accounts in the settings, one account per script type is
366
381
// added instead of a combined account.
382
+ //
383
+ // The accountsLock must be held when calling this function.
367
384
func (backend * Backend ) createAndAddBTCAccount (
368
385
keystore keystore.Keystore ,
369
386
coin coin.Coin ,
@@ -420,7 +437,7 @@ func (backend *Backend) createAndAddBTCAccount(
420
437
case signing .ScriptTypeP2WPKH :
421
438
suffixedName += ": bech32"
422
439
}
423
- err := backend .CreateAndAddAccount (
440
+ err := backend .createAndAddAccount (
424
441
coin ,
425
442
fmt .Sprintf ("%s-%s" , code , cfg .scriptType ),
426
443
suffixedName ,
@@ -443,13 +460,14 @@ func (backend *Backend) createAndAddBTCAccount(
443
460
}
444
461
return result , nil
445
462
}
446
- err := backend .CreateAndAddAccount (coin , code , name , getSigningConfigurations , false , false )
463
+ err := backend .createAndAddAccount (coin , code , name , getSigningConfigurations , false , false )
447
464
if err != nil {
448
465
panic (err )
449
466
}
450
467
}
451
468
}
452
469
470
+ // The accountsLock must be held when calling this function.
453
471
func (backend * Backend ) createAndAddETHAccount (
454
472
keystore keystore.Keystore ,
455
473
coin coin.Coin ,
@@ -493,7 +511,7 @@ func (backend *Backend) createAndAddETHAccount(
493
511
),
494
512
}, nil
495
513
}
496
- err = backend .CreateAndAddAccount (coin , code , name , getSigningConfigurations , false , false )
514
+ err = backend .createAndAddAccount (coin , code , name , getSigningConfigurations , false , false )
497
515
if err != nil {
498
516
panic (err )
499
517
}
@@ -660,6 +678,7 @@ func (backend *Backend) Coin(code coinpkg.Code) (coin.Coin, error) {
660
678
return coin , nil
661
679
}
662
680
681
+ // The accountsLock must be held when calling this function.
663
682
func (backend * Backend ) initPersistedAccounts () {
664
683
for _ , account := range backend .config .AccountsConfig ().Accounts {
665
684
account := account
@@ -677,7 +696,7 @@ func (backend *Backend) initPersistedAccounts() {
677
696
getSigningConfigurations := func () (signing.Configurations , error ) {
678
697
return signing.Configurations {account .Configuration }, nil
679
698
}
680
- err = backend .CreateAndAddAccount (coin , account .Code , account .Name , getSigningConfigurations , false , false )
699
+ err = backend .createAndAddAccount (coin , account .Code , account .Name , getSigningConfigurations , false , false )
681
700
if err != nil {
682
701
panic (err )
683
702
}
@@ -686,6 +705,8 @@ func (backend *Backend) initPersistedAccounts() {
686
705
687
706
// initDefaultAccounts creates a bunch of default accounts for a set of keystores (not manually
688
707
// 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.
689
710
func (backend * Backend ) initDefaultAccounts () {
690
711
if backend .keystores .Count () == 0 {
691
712
return
@@ -765,6 +786,7 @@ func (backend *Backend) initDefaultAccounts() {
765
786
}
766
787
}
767
788
789
+ // The accountsLock must be held when calling this function.
768
790
func (backend * Backend ) initAccounts () {
769
791
// Since initAccounts replaces all previous accounts, we need to properly close them first.
770
792
backend .uninitAccounts ()
@@ -785,6 +807,8 @@ func (backend *Backend) initAccounts() {
785
807
// if the configuration changed (e.g. which accounts are active). This is a stopgap measure until
786
808
// accounts can be added and removed individually.
787
809
func (backend * Backend ) ReinitializeAccounts () {
810
+ defer backend .accountsLock .Lock ()()
811
+
788
812
backend .log .Info ("Reinitializing accounts" )
789
813
backend .initAccounts ()
790
814
}
@@ -796,6 +820,7 @@ func (backend *Backend) Testing() bool {
796
820
797
821
// Accounts returns the current accounts of the backend.
798
822
func (backend * Backend ) Accounts () []accounts.Interface {
823
+ defer backend .accountsLock .RLock ()()
799
824
return backend .accounts
800
825
}
801
826
@@ -852,6 +877,8 @@ func (backend *Backend) Start() <-chan interface{} {
852
877
if backend .arguments .DevMode () {
853
878
backend .baseManager .Start ()
854
879
}
880
+
881
+ defer backend .accountsLock .Lock ()()
855
882
backend .initPersistedAccounts ()
856
883
backend .emitAccountsStatusChanged ()
857
884
@@ -932,8 +959,8 @@ func (backend *Backend) BitBoxBaseDeregister(bitboxBaseID string) {
932
959
backend .events <- backendEvent {Type : "bitboxbases" , Data : "registeredChanged" }
933
960
}
934
961
962
+ // The accountsLock must be held when calling this function.
935
963
func (backend * Backend ) uninitAccounts () {
936
- defer backend .accountsLock .Lock ()()
937
964
for _ , account := range backend .accounts {
938
965
account := account
939
966
backend .onAccountUninit (account )
@@ -960,6 +987,8 @@ func (backend *Backend) RegisterKeystore(keystore keystore.Keystore) {
960
987
if backend .arguments .Multisig () && backend .keystores .Count () != 2 {
961
988
return
962
989
}
990
+
991
+ defer backend .accountsLock .Lock ()()
963
992
backend .initAccounts ()
964
993
}
965
994
@@ -971,6 +1000,9 @@ func (backend *Backend) DeregisterKeystore() {
971
1000
Subject : "keystores" ,
972
1001
Action : action .Reload ,
973
1002
})
1003
+
1004
+ defer backend .accountsLock .Lock ()()
1005
+
974
1006
backend .uninitAccounts ()
975
1007
// TODO: classify accounts by keystore, remove only the ones belonging to the deregistered
976
1008
// keystore. For now we just remove all, then re-add the rest.
@@ -1152,9 +1184,12 @@ func (backend *Backend) Environment() Environment {
1152
1184
1153
1185
// Close shuts down the backend. After this, no other method should be called.
1154
1186
func (backend * Backend ) Close () error {
1187
+ defer backend .accountsLock .Lock ()()
1188
+
1155
1189
errors := []string {}
1156
1190
1157
1191
backend .ratesUpdater .Stop ()
1192
+
1158
1193
backend .uninitAccounts ()
1159
1194
1160
1195
for _ , coin := range backend .coins {
0 commit comments