Modularize validator store (#6705)

- Create trait `ValidatorStore` with all functions used by the `validator_services`
- Make `validator_services` generic on `S: ValidatorStore`
- Introduce `LighthouseValidatorStore`, which has identical functionality to the old `ValidatorStore`
- Remove dependencies (especially `environment`) from `validator_services` and `beacon_node_fallback` in order to be able to cleanly use them in Anchor
This commit is contained in:
Daniel Knopik
2025-05-07 05:43:33 +02:00
committed by GitHub
parent beb0ce68bd
commit 3d92e3663b
42 changed files with 2010 additions and 1622 deletions

View File

@@ -16,13 +16,14 @@ deposit_contract = { workspace = true }
directory = { workspace = true }
dirs = { workspace = true }
doppelganger_service = { workspace = true }
eth2 = { workspace = true }
eth2_keystore = { workspace = true }
eth2 = { workspace = true }
eth2_keystore = { workspace = true }
ethereum_serde_utils = { workspace = true }
filesystem = { workspace = true }
graffiti_file = { workspace = true }
health_metrics = { workspace = true }
initialized_validators = { workspace = true }
lighthouse_validator_store = { workspace = true }
lighthouse_version = { workspace = true }
logging = { workspace = true }
parking_lot = { workspace = true }
@@ -32,19 +33,19 @@ serde = { workspace = true }
serde_json = { workspace = true }
signing_method = { workspace = true }
slashing_protection = { workspace = true }
slot_clock = { workspace = true }
sysinfo = { workspace = true }
system_health = { workspace = true }
task_executor = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { workspace = true }
types = { workspace = true }
url = { workspace = true }
validator_dir = { workspace = true }
validator_services = { workspace = true }
validator_store = { workspace = true }
slot_clock = { workspace = true }
sysinfo = { workspace = true }
system_health = { workspace = true }
task_executor = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }
tokio-stream = { workspace = true }
tracing = { workspace = true }
types = { workspace = true }
url = { workspace = true }
validator_dir = { workspace = true }
validator_services = { workspace = true }
validator_store = { workspace = true }
warp = { workspace = true }
warp_utils = { workspace = true }
zeroize = { workspace = true }

View File

@@ -1,5 +1,6 @@
use bls::{PublicKey, PublicKeyBytes};
use eth2::types::GenericResponse;
use lighthouse_validator_store::LighthouseValidatorStore;
use slot_clock::SlotClock;
use std::sync::Arc;
use tracing::info;
@@ -9,7 +10,7 @@ use validator_store::ValidatorStore;
pub async fn create_signed_voluntary_exit<T: 'static + SlotClock + Clone, E: EthSpec>(
pubkey: PublicKey,
maybe_epoch: Option<Epoch>,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
slot_clock: T,
) -> Result<GenericResponse<SignedVoluntaryExit>, warp::Rejection> {
let epoch = match maybe_epoch {

View File

@@ -5,12 +5,11 @@ use account_utils::{
random_mnemonic, random_password,
};
use eth2::lighthouse_vc::types::{self as api_types};
use lighthouse_validator_store::LighthouseValidatorStore;
use slot_clock::SlotClock;
use std::path::{Path, PathBuf};
use types::ChainSpec;
use types::EthSpec;
use types::{ChainSpec, EthSpec};
use validator_dir::{keystore_password_path, Builder as ValidatorDirBuilder};
use validator_store::ValidatorStore;
use zeroize::Zeroizing;
/// Create some validator EIP-2335 keystores and store them on disk. Then, enroll the validators in
@@ -30,7 +29,7 @@ pub async fn create_validators_mnemonic<P: AsRef<Path>, T: 'static + SlotClock,
validator_requests: &[api_types::ValidatorRequest],
validator_dir: P,
secrets_dir: Option<PathBuf>,
validator_store: &ValidatorStore<T, E>,
validator_store: &LighthouseValidatorStore<T, E>,
spec: &ChainSpec,
) -> Result<(Vec<api_types::CreatedValidator>, Mnemonic), warp::Rejection> {
let mnemonic = mnemonic_opt.unwrap_or_else(random_mnemonic);
@@ -178,7 +177,7 @@ pub async fn create_validators_mnemonic<P: AsRef<Path>, T: 'static + SlotClock,
pub async fn create_validators_web3signer<T: 'static + SlotClock, E: EthSpec>(
validators: Vec<ValidatorDefinition>,
validator_store: &ValidatorStore<T, E>,
validator_store: &LighthouseValidatorStore<T, E>,
) -> Result<(), warp::Rejection> {
for validator in validators {
validator_store

View File

@@ -1,12 +1,12 @@
use bls::PublicKey;
use lighthouse_validator_store::LighthouseValidatorStore;
use slot_clock::SlotClock;
use std::sync::Arc;
use types::{graffiti::GraffitiString, EthSpec, Graffiti};
use validator_store::ValidatorStore;
pub fn get_graffiti<T: 'static + SlotClock + Clone, E: EthSpec>(
validator_pubkey: PublicKey,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_flag: Option<Graffiti>,
) -> Result<Graffiti, warp::Rejection> {
let initialized_validators_rw_lock = validator_store.initialized_validators();
@@ -29,7 +29,7 @@ pub fn get_graffiti<T: 'static + SlotClock + Clone, E: EthSpec>(
pub fn set_graffiti<T: 'static + SlotClock + Clone, E: EthSpec>(
validator_pubkey: PublicKey,
graffiti: GraffitiString,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
) -> Result<(), warp::Rejection> {
let initialized_validators_rw_lock = validator_store.initialized_validators();
let mut initialized_validators = initialized_validators_rw_lock.write();
@@ -55,7 +55,7 @@ pub fn set_graffiti<T: 'static + SlotClock + Clone, E: EthSpec>(
pub fn delete_graffiti<T: 'static + SlotClock + Clone, E: EthSpec>(
validator_pubkey: PublicKey,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
) -> Result<(), warp::Rejection> {
let initialized_validators_rw_lock = validator_store.initialized_validators();
let mut initialized_validators = initialized_validators_rw_lock.write();

View File

@@ -10,6 +10,7 @@ use eth2::lighthouse_vc::{
};
use eth2_keystore::Keystore;
use initialized_validators::{Error, InitializedValidators};
use lighthouse_validator_store::LighthouseValidatorStore;
use signing_method::SigningMethod;
use slot_clock::SlotClock;
use std::path::PathBuf;
@@ -19,13 +20,12 @@ use tokio::runtime::Handle;
use tracing::{info, warn};
use types::{EthSpec, PublicKeyBytes};
use validator_dir::{keystore_password_path, Builder as ValidatorDirBuilder};
use validator_store::ValidatorStore;
use warp::Rejection;
use warp_utils::reject::{custom_bad_request, custom_server_error};
use zeroize::Zeroizing;
pub fn list<T: SlotClock + 'static, E: EthSpec>(
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
) -> ListKeystoresResponse {
let initialized_validators_rwlock = validator_store.initialized_validators();
let initialized_validators = initialized_validators_rwlock.read();
@@ -62,7 +62,7 @@ pub fn import<T: SlotClock + 'static, E: EthSpec>(
request: ImportKeystoresRequest,
validator_dir: PathBuf,
secrets_dir: Option<PathBuf>,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor,
) -> Result<ImportKeystoresResponse, Rejection> {
// Check request validity. This is the only cases in which we should return a 4xx code.
@@ -117,7 +117,7 @@ pub fn import<T: SlotClock + 'static, E: EthSpec>(
)
} else if let Some(handle) = task_executor.handle() {
// Import the keystore.
match import_single_keystore(
match import_single_keystore::<_, E>(
keystore,
password,
validator_dir.clone(),
@@ -164,7 +164,7 @@ fn import_single_keystore<T: SlotClock + 'static, E: EthSpec>(
password: Zeroizing<String>,
validator_dir_path: PathBuf,
secrets_dir: Option<PathBuf>,
validator_store: &ValidatorStore<T, E>,
validator_store: &LighthouseValidatorStore<T, E>,
handle: Handle,
) -> Result<ImportKeystoreStatus, String> {
// Check if the validator key already exists, erroring if it is a remote signer validator.
@@ -234,7 +234,7 @@ fn import_single_keystore<T: SlotClock + 'static, E: EthSpec>(
pub fn delete<T: SlotClock + 'static, E: EthSpec>(
request: DeleteKeystoresRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor,
) -> Result<DeleteKeystoresResponse, Rejection> {
let export_response = export(request, validator_store, task_executor)?;
@@ -265,7 +265,7 @@ pub fn delete<T: SlotClock + 'static, E: EthSpec>(
pub fn export<T: SlotClock + 'static, E: EthSpec>(
request: DeleteKeystoresRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor,
) -> Result<ExportKeystoresResponse, Rejection> {
// Remove from initialized validators.

View File

@@ -13,6 +13,7 @@ use graffiti::{delete_graffiti, get_graffiti, set_graffiti};
use create_signed_voluntary_exit::create_signed_voluntary_exit;
use graffiti_file::{determine_graffiti, GraffitiFile};
use lighthouse_validator_store::LighthouseValidatorStore;
use validator_store::ValidatorStore;
use account_utils::{
@@ -41,7 +42,6 @@ use serde::{Deserialize, Serialize};
use slot_clock::SlotClock;
use std::collections::HashMap;
use std::future::Future;
use std::marker::PhantomData;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::PathBuf;
use std::sync::Arc;
@@ -77,11 +77,11 @@ impl From<String> for Error {
/// A wrapper around all the items required to spawn the HTTP server.
///
/// The server will gracefully handle the case where any fields are `None`.
pub struct Context<T: SlotClock, E: EthSpec> {
pub struct Context<T: SlotClock, E> {
pub task_executor: TaskExecutor,
pub api_secret: ApiSecret,
pub block_service: Option<BlockService<T, E>>,
pub validator_store: Option<Arc<ValidatorStore<T, E>>>,
pub block_service: Option<BlockService<LighthouseValidatorStore<T, E>, T>>,
pub validator_store: Option<Arc<LighthouseValidatorStore<T, E>>>,
pub validator_dir: Option<PathBuf>,
pub secrets_dir: Option<PathBuf>,
pub graffiti_file: Option<GraffitiFile>,
@@ -90,7 +90,6 @@ pub struct Context<T: SlotClock, E: EthSpec> {
pub config: Config,
pub sse_logging_components: Option<SSELoggingComponents>,
pub slot_clock: T,
pub _phantom: PhantomData<E>,
}
/// Configuration for the HTTP server.
@@ -320,7 +319,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path("validators"))
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(|validator_store: Arc<ValidatorStore<T, E>>| {
.then(|validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
let validators = validator_store
.initialized_validators()
@@ -345,7 +344,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(
|validator_pubkey: PublicKey, validator_store: Arc<ValidatorStore<T, E>>| {
|validator_pubkey: PublicKey, validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
let validator = validator_store
.initialized_validators()
@@ -395,7 +394,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(graffiti_file_filter.clone())
.and(graffiti_flag_filter)
.then(
|validator_store: Arc<ValidatorStore<T, E>>,
|validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_file: Option<GraffitiFile>,
graffiti_flag: Option<Graffiti>| {
blocking_json_task(move || {
@@ -424,33 +423,35 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path("health"))
.and(warp::path::end())
.and(block_service_filter.clone())
.then(|block_filter: BlockService<T, E>| async move {
let mut result: HashMap<String, Vec<CandidateInfo>> = HashMap::new();
.then(
|block_filter: BlockService<LighthouseValidatorStore<T, E>, T>| async move {
let mut result: HashMap<String, Vec<CandidateInfo>> = HashMap::new();
let mut beacon_nodes = Vec::new();
for node in &*block_filter.beacon_nodes.candidates.read().await {
beacon_nodes.push(CandidateInfo {
index: node.index,
endpoint: node.beacon_node.to_string(),
health: *node.health.read().await,
});
}
result.insert("beacon_nodes".to_string(), beacon_nodes);
if let Some(proposer_nodes_list) = &block_filter.proposer_nodes {
let mut proposer_nodes = Vec::new();
for node in &*proposer_nodes_list.candidates.read().await {
proposer_nodes.push(CandidateInfo {
let mut beacon_nodes = Vec::new();
for node in &*block_filter.beacon_nodes.candidates.read().await {
beacon_nodes.push(CandidateInfo {
index: node.index,
endpoint: node.beacon_node.to_string(),
health: *node.health.read().await,
});
}
result.insert("proposer_nodes".to_string(), proposer_nodes);
}
result.insert("beacon_nodes".to_string(), beacon_nodes);
blocking_json_task(move || Ok(api_types::GenericResponse::from(result))).await
});
if let Some(proposer_nodes_list) = &block_filter.proposer_nodes {
let mut proposer_nodes = Vec::new();
for node in &*proposer_nodes_list.candidates.read().await {
proposer_nodes.push(CandidateInfo {
index: node.index,
endpoint: node.beacon_node.to_string(),
health: *node.health.read().await,
});
}
result.insert("proposer_nodes".to_string(), proposer_nodes);
}
blocking_json_task(move || Ok(api_types::GenericResponse::from(result))).await
},
);
// POST lighthouse/validators/
let post_validators = warp::path("lighthouse")
@@ -466,14 +467,14 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
move |body: Vec<api_types::ValidatorRequest>,
validator_dir: PathBuf,
secrets_dir: PathBuf,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
spec: Arc<ChainSpec>,
task_executor: TaskExecutor| {
blocking_json_task(move || {
let secrets_dir = store_passwords_in_secrets_dir.then_some(secrets_dir);
if let Some(handle) = task_executor.handle() {
let (validators, mnemonic) =
handle.block_on(create_validators_mnemonic(
handle.block_on(create_validators_mnemonic::<_, _, E>(
None,
None,
&body,
@@ -511,7 +512,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
move |body: api_types::CreateValidatorsMnemonicRequest,
validator_dir: PathBuf,
secrets_dir: PathBuf,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
spec: Arc<ChainSpec>,
task_executor: TaskExecutor| {
blocking_json_task(move || {
@@ -525,7 +526,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
))
})?;
let (validators, _mnemonic) =
handle.block_on(create_validators_mnemonic(
handle.block_on(create_validators_mnemonic::<_, _, E>(
Some(mnemonic),
Some(body.key_derivation_path_offset),
&body.validators,
@@ -558,7 +559,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
move |body: api_types::KeystoreValidatorsPostRequest,
validator_dir: PathBuf,
secrets_dir: PathBuf,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor| {
blocking_json_task(move || {
// Check to ensure the password is correct.
@@ -644,7 +645,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(task_executor_filter.clone())
.then(
|body: Vec<api_types::Web3SignerValidatorRequest>,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor| {
blocking_json_task(move || {
if let Some(handle) = task_executor.handle() {
@@ -672,7 +673,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
),
})
.collect();
handle.block_on(create_validators_web3signer(
handle.block_on(create_validators_web3signer::<_, E>(
web3signers,
&validator_store,
))?;
@@ -698,7 +699,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.then(
|validator_pubkey: PublicKey,
body: api_types::ValidatorPatchRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_file: Option<GraffitiFile>,
task_executor: TaskExecutor| {
blocking_json_task(move || {
@@ -851,7 +852,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(
|validator_pubkey: PublicKey, validator_store: Arc<ValidatorStore<T, E>>| {
|validator_pubkey: PublicKey, validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -892,7 +893,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.then(
|validator_pubkey: PublicKey,
request: api_types::UpdateFeeRecipientRequest,
validator_store: Arc<ValidatorStore<T, E>>| {
validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -928,7 +929,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(
|validator_pubkey: PublicKey, validator_store: Arc<ValidatorStore<T, E>>| {
|validator_pubkey: PublicKey, validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -964,7 +965,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(
|validator_pubkey: PublicKey, validator_store: Arc<ValidatorStore<T, E>>| {
|validator_pubkey: PublicKey, validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -997,7 +998,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.then(
|validator_pubkey: PublicKey,
request: api_types::UpdateGasLimitRequest,
validator_store: Arc<ValidatorStore<T, E>>| {
validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -1033,7 +1034,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(warp::path::end())
.and(validator_store_filter.clone())
.then(
|validator_pubkey: PublicKey, validator_store: Arc<ValidatorStore<T, E>>| {
|validator_pubkey: PublicKey, validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || {
if validator_store
.initialized_validators()
@@ -1074,13 +1075,13 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.then(
|pubkey: PublicKey,
query: api_types::VoluntaryExitQuery,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
slot_clock: T,
task_executor: TaskExecutor| {
blocking_json_task(move || {
if let Some(handle) = task_executor.handle() {
let signed_voluntary_exit =
handle.block_on(create_signed_voluntary_exit(
handle.block_on(create_signed_voluntary_exit::<T, E>(
pubkey,
query.epoch,
validator_store,
@@ -1106,7 +1107,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(graffiti_flag_filter)
.then(
|pubkey: PublicKey,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_flag: Option<Graffiti>| {
blocking_json_task(move || {
let graffiti = get_graffiti(pubkey.clone(), validator_store, graffiti_flag)?;
@@ -1130,7 +1131,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.then(
|pubkey: PublicKey,
query: SetGraffitiRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_file: Option<GraffitiFile>| {
blocking_json_task(move || {
if graffiti_file.is_some() {
@@ -1155,7 +1156,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(graffiti_file_filter.clone())
.then(
|pubkey: PublicKey,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
graffiti_file: Option<GraffitiFile>| {
blocking_json_task(move || {
if graffiti_file.is_some() {
@@ -1172,7 +1173,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
// GET /eth/v1/keystores
let get_std_keystores = std_keystores.and(validator_store_filter.clone()).then(
|validator_store: Arc<ValidatorStore<T, E>>| {
|validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || Ok(keystores::list(validator_store)))
},
);
@@ -1188,7 +1189,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
move |request, validator_dir, secrets_dir, validator_store, task_executor| {
let secrets_dir = store_passwords_in_secrets_dir.then_some(secrets_dir);
blocking_json_task(move || {
keystores::import(
keystores::import::<_, E>(
request,
validator_dir,
secrets_dir,
@@ -1210,7 +1211,7 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
// GET /eth/v1/remotekeys
let get_std_remotekeys = std_remotekeys.and(validator_store_filter.clone()).then(
|validator_store: Arc<ValidatorStore<T, E>>| {
|validator_store: Arc<LighthouseValidatorStore<T, E>>| {
blocking_json_task(move || Ok(remotekeys::list(validator_store)))
},
);
@@ -1221,7 +1222,9 @@ pub fn serve<T: 'static + SlotClock + Clone, E: EthSpec>(
.and(validator_store_filter.clone())
.and(task_executor_filter.clone())
.then(|request, validator_store, task_executor| {
blocking_json_task(move || remotekeys::import(request, validator_store, task_executor))
blocking_json_task(move || {
remotekeys::import::<_, E>(request, validator_store, task_executor)
})
});
// DELETE /eth/v1/remotekeys

View File

@@ -8,6 +8,7 @@ use eth2::lighthouse_vc::std_types::{
ListRemotekeysResponse, SingleListRemotekeysResponse, Status,
};
use initialized_validators::{Error, InitializedValidators};
use lighthouse_validator_store::LighthouseValidatorStore;
use slot_clock::SlotClock;
use std::sync::Arc;
use task_executor::TaskExecutor;
@@ -15,12 +16,11 @@ use tokio::runtime::Handle;
use tracing::{info, warn};
use types::{EthSpec, PublicKeyBytes};
use url::Url;
use validator_store::ValidatorStore;
use warp::Rejection;
use warp_utils::reject::custom_server_error;
pub fn list<T: SlotClock + 'static, E: EthSpec>(
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
) -> ListRemotekeysResponse {
let initialized_validators_rwlock = validator_store.initialized_validators();
let initialized_validators = initialized_validators_rwlock.read();
@@ -50,7 +50,7 @@ pub fn list<T: SlotClock + 'static, E: EthSpec>(
pub fn import<T: SlotClock + 'static, E: EthSpec>(
request: ImportRemotekeysRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor,
) -> Result<ImportRemotekeysResponse, Rejection> {
info!(
@@ -63,8 +63,12 @@ pub fn import<T: SlotClock + 'static, E: EthSpec>(
for remotekey in request.remote_keys {
let status = if let Some(handle) = task_executor.handle() {
// Import the keystore.
match import_single_remotekey(remotekey.pubkey, remotekey.url, &validator_store, handle)
{
match import_single_remotekey::<_, E>(
remotekey.pubkey,
remotekey.url,
&validator_store,
handle,
) {
Ok(status) => Status::ok(status),
Err(e) => {
warn!(
@@ -89,7 +93,7 @@ pub fn import<T: SlotClock + 'static, E: EthSpec>(
fn import_single_remotekey<T: SlotClock + 'static, E: EthSpec>(
pubkey: PublicKeyBytes,
url: String,
validator_store: &ValidatorStore<T, E>,
validator_store: &LighthouseValidatorStore<T, E>,
handle: Handle,
) -> Result<ImportRemotekeyStatus, String> {
if let Err(url_err) = Url::parse(&url) {
@@ -143,7 +147,7 @@ fn import_single_remotekey<T: SlotClock + 'static, E: EthSpec>(
pub fn delete<T: SlotClock + 'static, E: EthSpec>(
request: DeleteRemotekeysRequest,
validator_store: Arc<ValidatorStore<T, E>>,
validator_store: Arc<LighthouseValidatorStore<T, E>>,
task_executor: TaskExecutor,
) -> Result<DeleteRemotekeysResponse, Rejection> {
info!(

View File

@@ -14,19 +14,19 @@ use eth2::{
use eth2_keystore::KeystoreBuilder;
use initialized_validators::key_cache::{KeyCache, CACHE_FILENAME};
use initialized_validators::{InitializedValidators, OnDecryptFailure};
use lighthouse_validator_store::{Config as ValidatorStoreConfig, LighthouseValidatorStore};
use parking_lot::RwLock;
use sensitive_url::SensitiveUrl;
use slashing_protection::{SlashingDatabase, SLASHING_PROTECTION_FILENAME};
use slot_clock::{SlotClock, TestingSlotClock};
use std::future::Future;
use std::marker::PhantomData;
use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;
use std::time::Duration;
use task_executor::test_utils::TestRuntime;
use tempfile::{tempdir, TempDir};
use tokio::sync::oneshot;
use validator_store::{Config as ValidatorStoreConfig, ValidatorStore};
use validator_services::block_service::BlockService;
use zeroize::Zeroizing;
pub const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
@@ -54,7 +54,7 @@ pub struct Web3SignerValidatorScenario {
pub struct ApiTester {
pub client: ValidatorClientHttpClient,
pub initialized_validators: Arc<RwLock<InitializedValidators>>,
pub validator_store: Arc<ValidatorStore<TestingSlotClock, E>>,
pub validator_store: Arc<LighthouseValidatorStore<TestingSlotClock, E>>,
pub url: SensitiveUrl,
pub api_token: String,
pub test_runtime: TestRuntime,
@@ -101,7 +101,7 @@ impl ApiTester {
let test_runtime = TestRuntime::default();
let validator_store = Arc::new(ValidatorStore::<_, E>::new(
let validator_store = Arc::new(LighthouseValidatorStore::new(
initialized_validators,
slashing_protection,
Hash256::repeat_byte(42),
@@ -121,7 +121,7 @@ impl ApiTester {
let context = Arc::new(Context {
task_executor: test_runtime.task_executor.clone(),
api_secret,
block_service: None,
block_service: None::<BlockService<LighthouseValidatorStore<_, _>, _>>,
validator_dir: Some(validator_dir.path().into()),
secrets_dir: Some(secrets_dir.path().into()),
validator_store: Some(validator_store.clone()),
@@ -131,7 +131,6 @@ impl ApiTester {
config: http_config,
sse_logging_components: None,
slot_clock,
_phantom: PhantomData,
});
let ctx = context;
let (shutdown_tx, shutdown_rx) = oneshot::channel();
@@ -139,7 +138,7 @@ impl ApiTester {
// It's not really interesting why this triggered, just that it happened.
let _ = shutdown_rx.await;
};
let (listening_socket, server) = super::serve(ctx, server_shutdown).unwrap();
let (listening_socket, server) = super::serve::<_, E>(ctx, server_shutdown).unwrap();
tokio::spawn(server);
@@ -638,7 +637,7 @@ impl ApiTester {
assert_eq!(
self.validator_store
.get_builder_proposals(&validator.voting_pubkey),
.get_builder_proposals_testing_only(&validator.voting_pubkey),
builder_proposals
);

View File

@@ -18,12 +18,12 @@ use eth2::{
Error as ApiError,
};
use eth2_keystore::KeystoreBuilder;
use lighthouse_validator_store::{Config as ValidatorStoreConfig, LighthouseValidatorStore};
use parking_lot::RwLock;
use sensitive_url::SensitiveUrl;
use slashing_protection::{SlashingDatabase, SLASHING_PROTECTION_FILENAME};
use slot_clock::{SlotClock, TestingSlotClock};
use std::future::Future;
use std::marker::PhantomData;
use std::net::{IpAddr, Ipv4Addr};
use std::str::FromStr;
use std::sync::Arc;
@@ -31,7 +31,7 @@ use std::time::Duration;
use task_executor::test_utils::TestRuntime;
use tempfile::{tempdir, TempDir};
use types::graffiti::GraffitiString;
use validator_store::{Config as ValidatorStoreConfig, ValidatorStore};
use validator_store::ValidatorStore;
use zeroize::Zeroizing;
const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
@@ -42,7 +42,7 @@ type E = MainnetEthSpec;
struct ApiTester {
client: ValidatorClientHttpClient,
initialized_validators: Arc<RwLock<InitializedValidators>>,
validator_store: Arc<ValidatorStore<TestingSlotClock, E>>,
validator_store: Arc<LighthouseValidatorStore<TestingSlotClock, E>>,
url: SensitiveUrl,
slot_clock: TestingSlotClock,
_validator_dir: TempDir,
@@ -91,7 +91,7 @@ impl ApiTester {
let test_runtime = TestRuntime::default();
let validator_store = Arc::new(ValidatorStore::<_, E>::new(
let validator_store = Arc::new(LighthouseValidatorStore::<_, E>::new(
initialized_validators,
slashing_protection,
Hash256::repeat_byte(42),
@@ -129,11 +129,10 @@ impl ApiTester {
},
sse_logging_components: None,
slot_clock: slot_clock.clone(),
_phantom: PhantomData,
});
let ctx = context.clone();
let (listening_socket, server) =
super::serve(ctx, test_runtime.task_executor.exit()).unwrap();
super::serve::<_, E>(ctx, test_runtime.task_executor.exit()).unwrap();
tokio::spawn(server);
@@ -670,7 +669,7 @@ impl ApiTester {
assert_eq!(
self.validator_store
.get_builder_proposals(&validator.voting_pubkey),
.get_builder_proposals_testing_only(&validator.voting_pubkey),
builder_proposals
);
@@ -686,7 +685,7 @@ impl ApiTester {
assert_eq!(
self.validator_store
.get_builder_boost_factor(&validator.voting_pubkey),
.get_builder_boost_factor_testing_only(&validator.voting_pubkey),
builder_boost_factor
);
@@ -702,7 +701,7 @@ impl ApiTester {
assert_eq!(
self.validator_store
.determine_validator_builder_boost_factor(&validator.voting_pubkey),
.determine_builder_boost_factor(&validator.voting_pubkey),
builder_boost_factor
);
@@ -712,7 +711,7 @@ impl ApiTester {
pub fn assert_default_builder_boost_factor(self, builder_boost_factor: Option<u64>) -> Self {
assert_eq!(
self.validator_store
.determine_default_builder_boost_factor(),
.determine_builder_boost_factor(&PublicKeyBytes::empty()),
builder_boost_factor
);
@@ -728,7 +727,7 @@ impl ApiTester {
assert_eq!(
self.validator_store
.get_prefer_builder_proposals(&validator.voting_pubkey),
.get_prefer_builder_proposals_testing_only(&validator.voting_pubkey),
prefer_builder_proposals
);
@@ -1159,7 +1158,7 @@ async fn validator_derived_builder_boost_factor_with_process_defaults() {
})
.await
.assert_default_builder_boost_factor(Some(80))
.assert_validator_derived_builder_boost_factor(0, None)
.assert_validator_derived_builder_boost_factor(0, Some(80))
.await
.set_builder_proposals(0, false)
.await

View File

@@ -8,12 +8,13 @@ use eth2::lighthouse_vc::{
types::Web3SignerValidatorRequest,
};
use itertools::Itertools;
use lighthouse_validator_store::DEFAULT_GAS_LIMIT;
use rand::{rngs::SmallRng, Rng, SeedableRng};
use slashing_protection::interchange::{Interchange, InterchangeMetadata};
use std::{collections::HashMap, path::Path};
use tokio::runtime::Handle;
use types::{attestation::AttestationBase, Address};
use validator_store::DEFAULT_GAS_LIMIT;
use validator_store::ValidatorStore;
use zeroize::Zeroizing;
fn new_keystore(password: Zeroizing<String>) -> Keystore {