mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-19 21:04:41 +00:00
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:
@@ -6,7 +6,9 @@ use crate::{
|
||||
};
|
||||
use account_utils::{validator_definitions::ValidatorDefinition, ZeroizeString};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use slashing_protection::{NotSafe, Safe, SlashingDatabase};
|
||||
use slashing_protection::{
|
||||
interchange::Interchange, InterchangeError, NotSafe, Safe, SlashingDatabase,
|
||||
};
|
||||
use slog::{crit, error, info, warn, Logger};
|
||||
use slot_clock::SlotClock;
|
||||
use std::iter::FromIterator;
|
||||
@@ -183,7 +185,7 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
|
||||
self.validators
|
||||
.write()
|
||||
.add_definition(validator_def.clone())
|
||||
.add_definition_replace_disabled(validator_def.clone())
|
||||
.await
|
||||
.map_err(|e| format!("Unable to add definition: {:?}", e))?;
|
||||
|
||||
@@ -693,6 +695,48 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
|
||||
Ok(SignedContributionAndProof { message, signature })
|
||||
}
|
||||
|
||||
pub fn import_slashing_protection(
|
||||
&self,
|
||||
interchange: Interchange,
|
||||
) -> Result<(), InterchangeError> {
|
||||
self.slashing_protection
|
||||
.import_interchange_info(interchange, self.genesis_validators_root)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Export slashing protection data while also disabling the given keys in the database.
|
||||
///
|
||||
/// If any key is unknown to the slashing protection database it will be silently omitted
|
||||
/// from the result. It is the caller's responsibility to check whether all keys provided
|
||||
/// had data returned for them.
|
||||
pub fn export_slashing_protection_for_keys(
|
||||
&self,
|
||||
pubkeys: &[PublicKeyBytes],
|
||||
) -> Result<Interchange, InterchangeError> {
|
||||
self.slashing_protection.with_transaction(|txn| {
|
||||
let known_pubkeys = pubkeys
|
||||
.iter()
|
||||
.filter_map(|pubkey| {
|
||||
let validator_id = self
|
||||
.slashing_protection
|
||||
.get_validator_id_ignoring_status(txn, pubkey)
|
||||
.ok()?;
|
||||
|
||||
Some(
|
||||
self.slashing_protection
|
||||
.update_validator_status(txn, validator_id, false)
|
||||
.map(|()| *pubkey),
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<PublicKeyBytes>, _>>()?;
|
||||
self.slashing_protection.export_interchange_info_in_txn(
|
||||
self.genesis_validators_root,
|
||||
Some(&known_pubkeys),
|
||||
txn,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Prune the slashing protection database so that it remains performant.
|
||||
///
|
||||
/// This function will only do actual pruning periodically, so it should usually be
|
||||
|
||||
Reference in New Issue
Block a user