diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go index d3a98850c7..4a23de521e 100644 --- a/accounts/keystore/account_cache.go +++ b/accounts/keystore/account_cache.go @@ -283,9 +283,11 @@ func (ac *accountCache) scanAccounts() error { start := time.Now() for _, path := range creates.ToSlice() { + ac.fileC.mu.Lock() if a := readAccount(path); a != nil { ac.add(*a) } + ac.fileC.mu.Unlock() } for _, path := range deletes.ToSlice() { ac.deleteByFile(path) diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index 63eb850374..390551a1f1 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -39,6 +39,8 @@ type fileCache struct { func (fc *fileCache) scan(keyDir string) (mapset.Set[string], mapset.Set[string], mapset.Set[string], error) { t0 := time.Now() + fc.mu.Lock() + defer fc.mu.Unlock() // List all the files from the keystore folder files, err := os.ReadDir(keyDir) if err != nil { @@ -46,9 +48,6 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set[string], mapset.Set[string] } t1 := time.Now() - fc.mu.Lock() - defer fc.mu.Unlock() - // Iterate all the files and gather their metadata all := mapset.NewThreadUnsafeSet[string]() mods := mapset.NewThreadUnsafeSet[string]() diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 29c4bdf2ca..6ec81acfd2 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -232,6 +232,8 @@ func (ks *KeyStore) Accounts() []accounts.Account { // Delete deletes the key matched by account if the passphrase is correct. // If the account contains no filename, the address must match a unique key. func (ks *KeyStore) Delete(a accounts.Account, passphrase string) error { + ks.cache.fileC.mu.Lock() + defer ks.cache.fileC.mu.Unlock() // Decrypting the key isn't really necessary, but we do // it anyway to check the password and zero out the key // immediately afterwards. diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index f8922a3f3f..7f541ddfed 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -17,6 +17,7 @@ package keystore import ( + "fmt" "math/rand" "os" "runtime" @@ -339,8 +340,8 @@ func TestWalletNotifications(t *testing.T) { for ev := range updates { events = append(events, walletEvent{ev, ev.Wallet.Accounts()[0]}) } - checkAccounts(t, live, ks.Wallets()) checkEvents(t, wantEvents, events) + checkAccounts(t, live, ks.Wallets()) } // TestImportECDSA tests the import functionality of a keystore. @@ -443,15 +444,12 @@ func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, walle // checkEvents checks that all events in 'want' are present in 'have'. Events may be present multiple times. func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { + filter := make(map[string]struct{}) + for _, haveEv := range have { + filter[fmt.Sprintf("%s-%d", haveEv.a.Address.String(), haveEv.Kind)] = struct{}{} + } for _, wantEv := range want { - nmatch := 0 - for ; len(have) > 0; nmatch++ { - if have[0].Kind != wantEv.Kind || have[0].a != wantEv.a { - break - } - have = have[1:] - } - if nmatch == 0 { + if _, ok := filter[fmt.Sprintf("%s-%d", wantEv.a.Address.String(), wantEv.Kind)]; !ok { t.Fatalf("can't find event with Kind=%v for %x", wantEv.Kind, wantEv.a.Address) } }