Improve wait for activation (#13448)

* removing timeout on wait for activation, instead switched to an event driven approach

* fixing unit tests

* linting

* simplifying return

* adding sleep for the remaining slot to avoid cpu spikes

* removing ifstatement on log

* removing ifstatement on log

* improving switch statement

* removing the loop entirely

* fixing unit test

* fixing manu's reported issue with deletion of json file

* missed change around writefile at path

* gofmt

* fixing deepsource issue with reading file

* trying to clean file to avoid deepsource issue

* still getting error trying a different approach

* fixing stream loop

* fixing unit test

* Update validator/keymanager/local/keymanager.go

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>

* fixing linting

---------

Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
This commit is contained in:
james-prysm
2024-01-16 11:04:54 -06:00
committed by GitHub
parent 46387a903a
commit 790a09f9b1
11 changed files with 161 additions and 160 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"path/filepath"
"strings"
"sync"
@@ -282,18 +283,29 @@ func (km *Keymanager) SaveStoreAndReInitialize(ctx context.Context, store *accou
if err != nil {
return err
}
if err := km.wallet.WriteFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName, encodedAccounts); err != nil {
existedPreviously, err := km.wallet.WriteFileAtPath(ctx, AccountsPath, AccountsKeystoreFileName, encodedAccounts)
if err != nil {
return err
}
// Reinitialize account store and cache
// This will update the in-memory information instead of reading from the file itself for safety concerns
km.accountsStore = store
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
if existedPreviously {
// Reinitialize account store and cache
// This will update the in-memory information instead of reading from the file itself for safety concerns
km.accountsStore = store
err = km.initializeKeysCachesFromKeystore()
if err != nil {
return errors.Wrap(err, "failed to initialize keys caches")
}
return nil
}
return err
// manually reload the account from the keystore the first time
km.reloadAccountsFromKeystoreFile(filepath.Join(km.wallet.AccountsDir(), AccountsPath, AccountsKeystoreFileName))
// listen to account changes of the new file
go km.listenForAccountChanges(ctx)
return nil
}
// CreateAccountsKeystoreRepresentation is a pure function that takes an accountStore and wallet password and returns the encrypted formatted json version for local writing.

View File

@@ -26,6 +26,7 @@ func (km *Keymanager) listenForAccountChanges(ctx context.Context) {
debounceFileChangesInterval := features.Get().KeystoreImportDebounceInterval
accountsFilePath := filepath.Join(km.wallet.AccountsDir(), AccountsPath, AccountsKeystoreFileName)
if !file.Exists(accountsFilePath) {
log.Warnf("Starting without accounts located in wallet at %s", accountsFilePath)
return
}
watcher, err := fsnotify.NewWatcher()
@@ -56,27 +57,7 @@ func (km *Keymanager) listenForAccountChanges(ctx context.Context) {
log.Errorf("Type %T is not a valid file system event", event)
return
}
fileBytes, err := os.ReadFile(ev.Name)
if err != nil {
log.WithError(err).Errorf("Could not read file at path: %s", ev.Name)
return
}
if fileBytes == nil {
log.WithError(err).Errorf("Loaded in an empty file: %s", ev.Name)
return
}
accountsKeystore := &AccountsKeystoreRepresentation{}
if err := json.Unmarshal(fileBytes, accountsKeystore); err != nil {
log.WithError(
err,
).Errorf("Could not read valid, EIP-2335 keystore json file at path: %s", ev.Name)
return
}
if err := km.reloadAccountsFromKeystore(accountsKeystore); err != nil {
log.WithError(
err,
).Error("Could not replace the accounts store from keystore file")
}
km.reloadAccountsFromKeystoreFile(ev.Name)
})
for {
select {
@@ -92,6 +73,34 @@ func (km *Keymanager) listenForAccountChanges(ctx context.Context) {
}
}
func (km *Keymanager) reloadAccountsFromKeystoreFile(accountsFilePath string) {
if km.wallet == nil {
log.Error("Could not reload accounts because wallet was undefined")
return
}
fileBytes, err := os.ReadFile(filepath.Clean(accountsFilePath))
if err != nil {
log.WithError(err).Errorf("Could not read file at path: %s", accountsFilePath)
return
}
if fileBytes == nil {
log.WithError(err).Errorf("Loaded in an empty file: %s", accountsFilePath)
return
}
accountsKeystore := &AccountsKeystoreRepresentation{}
if err := json.Unmarshal(fileBytes, accountsKeystore); err != nil {
log.WithError(
err,
).Errorf("Could not read valid, EIP-2335 keystore json file at path: %s", accountsFilePath)
return
}
if err := km.reloadAccountsFromKeystore(accountsKeystore); err != nil {
log.WithError(
err,
).Error("Could not replace the accounts store from keystore file")
}
}
// Replaces the accounts store struct in the local keymanager with
// the contents of a keystore file by decrypting it with the accounts password.
func (km *Keymanager) reloadAccountsFromKeystore(keystore *AccountsKeystoreRepresentation) error {
@@ -107,6 +116,7 @@ func (km *Keymanager) reloadAccountsFromKeystore(keystore *AccountsKeystoreRepre
if len(newAccountsStore.PublicKeys) != len(newAccountsStore.PrivateKeys) {
return errors.New("number of public and private keys in keystore do not match")
}
pubKeys := make([][fieldparams.BLSPubkeyLength]byte, len(newAccountsStore.PublicKeys))
for i := 0; i < len(newAccountsStore.PrivateKeys); i++ {
privKey, err := bls.SecretKeyFromBytes(newAccountsStore.PrivateKeys[i])