Implement standard keystore API (#2736)

## Issue Addressed

Implements the standard key manager API from https://ethereum.github.io/keymanager-APIs/, formerly https://github.com/ethereum/beacon-APIs/pull/151
Related to https://github.com/sigp/lighthouse/issues/2557

## Proposed Changes

- [x] Add all of the new endpoints from the standard API: GET, POST and DELETE.
- [x] Add a `validators.enabled` column to the slashing protection database to support atomic disable + export.
- [x] Add tests for all the common sequential accesses of the API
- [x] Add tests for interactions with remote signer validators
- [x] Add end-to-end tests for migration of validators from one VC to another
- [x] Implement the authentication scheme from the standard (token bearer auth)

## Additional Info

The `enabled` column in the validators SQL database is necessary to prevent a race condition when exporting slashing protection data. Without the slashing protection database having a way of knowing that a key has been disabled, a concurrent request to sign a message could insert a new record into the database. The `delete_concurrent_with_signing` test exercises this code path, and was indeed failing before the `enabled` column was added.

The validator client authentication has been modified from basic auth to bearer auth, with basic auth preserved for backwards compatibility.
This commit is contained in:
Michael Sproul
2022-01-30 23:22:04 +00:00
parent ee000d5219
commit e961ff60b4
32 changed files with 2284 additions and 127 deletions

View File

@@ -134,15 +134,18 @@ impl<'a> Builder<'a> {
self
}
/// Return the path to the validator dir to be built, i.e. `base_dir/pubkey`.
pub fn get_dir_path(base_validators_dir: &Path, voting_keystore: &Keystore) -> PathBuf {
base_validators_dir.join(format!("0x{}", voting_keystore.pubkey()))
}
/// Consumes `self`, returning a `ValidatorDir` if no error is encountered.
pub fn build(self) -> Result<ValidatorDir, Error> {
let (voting_keystore, voting_password) = self
.voting_keystore
.ok_or(Error::UninitializedVotingKeystore)?;
let dir = self
.base_validators_dir
.join(format!("0x{}", voting_keystore.pubkey()));
let dir = Self::get_dir_path(&self.base_validators_dir, &voting_keystore);
if dir.exists() {
return Err(Error::DirectoryAlreadyExists(dir));