accounts/keystore: fix race in Import/ImportECDSA

This commit is contained in:
Marius van der Wijden 2020-04-14 13:13:41 +02:00
parent 5a20cc0de6
commit 10c214ffd5

View file

@ -68,6 +68,7 @@ type KeyStore struct {
updating bool // Whether the event notification loop is running updating bool // Whether the event notification loop is running
mu sync.RWMutex mu sync.RWMutex
impMu sync.RWMutex // Import Mutex locks the import to prevent two insertions from racing
} }
type unlocked struct { type unlocked struct {
@ -443,12 +444,19 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac
if err != nil { if err != nil {
return accounts.Account{}, err return accounts.Account{}, err
} }
ks.impMu.Lock()
defer ks.impMu.Unlock()
if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, fmt.Errorf("account already exists")
}
return ks.importKey(key, newPassphrase) return ks.importKey(key, newPassphrase)
} }
// ImportECDSA stores the given key into the key directory, encrypting it with the passphrase. // ImportECDSA stores the given key into the key directory, encrypting it with the passphrase.
func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) {
key := newKeyFromECDSA(priv) key := newKeyFromECDSA(priv)
ks.impMu.Lock()
defer ks.impMu.Unlock()
if ks.cache.hasAddress(key.Address) { if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, fmt.Errorf("account already exists") return accounts.Account{}, fmt.Errorf("account already exists")
} }