From 85b240671009e9d8a7d0b2ee542cd7c2ef534829 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Wed, 18 Dec 2024 17:38:35 +0100 Subject: [PATCH 01/21] create signature collector and make processor stateless --- Cargo.lock | 27 ++- Cargo.toml | 3 + anchor/processor/Cargo.toml | 3 +- anchor/processor/src/lib.rs | 95 +++------- anchor/processor/tests/processor_tests.rs | 14 +- anchor/signature_collector/Cargo.toml | 13 ++ anchor/signature_collector/src/lib.rs | 216 ++++++++++++++++++++++ 7 files changed, 293 insertions(+), 78 deletions(-) create mode 100644 anchor/signature_collector/Cargo.toml create mode 100644 anchor/signature_collector/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0fa4f900a..a505c8491 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1636,6 +1636,20 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04d2cd9c18b9f454ed67da600630b021a8a80bf33f8c95896ab33aaf1c26b728" +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -5997,7 +6011,6 @@ dependencies = [ "futures", "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", "num_cpus", - "qbft", "serde", "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", "tokio", @@ -7224,6 +7237,18 @@ dependencies = [ "rand_core", ] +[[package]] +name = "signature_collector" +version = "0.1.0" +dependencies = [ + "dashmap", + "processor", + "ssv_types", + "tokio", + "tracing", + "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", +] + [[package]] name = "simple_asn1" version = "0.6.2" diff --git a/Cargo.toml b/Cargo.toml index aa1e61d69..e84cf0a90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "anchor/network", "anchor/processor", "anchor/qbft", + "anchor/signature_collector", ] resolver = "2" @@ -25,6 +26,7 @@ network = { path = "anchor/network" } version = { path = "anchor/common/version" } processor = { path = "anchor/processor" } ssv_types = { path = "anchor/common/ssv_types" } +signature_collector = { path = "anchor/signature_collector" } lighthouse_network = { git = "https://github.com/sigp/lighthouse", branch = "unstable" } task_executor = { git = "https://github.com/sigp/lighthouse", branch = "unstable", default-features = false, features = [ "tracing", ] } metrics = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } @@ -37,6 +39,7 @@ derive_more = { version = "1.0.0", features = ["full"] } async-channel = "1.9" axum = "0.7.7" clap = { version = "4.5.15", features = ["derive", "wrap_help"] } +dashmap = "6.1.0" discv5 = "0.8.0" dirs = "5.0.1" either = "1.13.0" diff --git a/anchor/processor/Cargo.toml b/anchor/processor/Cargo.toml index c81984c1b..50dd0ad03 100644 --- a/anchor/processor/Cargo.toml +++ b/anchor/processor/Cargo.toml @@ -7,10 +7,9 @@ edition = { workspace = true } [dependencies] metrics = { workspace = true } num_cpus = { workspace = true } -qbft = { workspace = true } serde = { workspace = true } task_executor = { workspace = true } -tokio = { workspace = true, features = ["sync", "rt", "rt-multi-thread", "macros"] } +tokio = { workspace = true, features = ["sync"] } tracing = { workspace = true } [dev-dependencies] diff --git a/anchor/processor/src/lib.rs b/anchor/processor/src/lib.rs index 4cb8ae969..8d63f743f 100644 --- a/anchor/processor/src/lib.rs +++ b/anchor/processor/src/lib.rs @@ -9,9 +9,7 @@ mod metrics; -use qbft::{InMessage, InstanceHeight}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; use std::fmt::{Debug, Formatter}; use std::future::Future; use std::pin::Pin; @@ -19,7 +17,6 @@ use std::sync::Arc; use task_executor::TaskExecutor; use tokio::select; use tokio::sync::mpsc::error::TrySendError; -use tokio::sync::mpsc::UnboundedSender; use tokio::sync::{mpsc, OwnedSemaphorePermit, Semaphore}; use tokio::time::Instant; use tracing::{error, warn}; @@ -49,49 +46,46 @@ pub struct Sender { impl Sender { /// Convenience method creating an async [`WorkItem`] and sending it. pub fn send_async + Send + 'static>( - &mut self, + &self, future: F, name: &'static str, ) -> Result<(), TrySendError> { self.send_work_item(WorkItem { func: WorkKind::Async(Box::pin(future)), expiry: None, - state_modifier: None, name, }) } /// Convenience method creating a blocking [`WorkItem`] and sending it. pub fn send_blocking( - &mut self, + &self, func: F, name: &'static str, ) -> Result<(), TrySendError> { self.send_work_item(WorkItem { func: WorkKind::Blocking(Box::new(func)), expiry: None, - state_modifier: None, name, }) } /// Convenience method creating an immediate [`WorkItem`] and sending it. - pub fn send_immediate( - &mut self, + pub fn send_immediate( + &self, func: F, name: &'static str, ) -> Result<(), TrySendError> { self.send_work_item(WorkItem { func: WorkKind::Immediate(Box::new(func)), expiry: None, - state_modifier: None, name, }) } /// Sends a [`WorkItem`] into the queue, non-blocking, returning an error if the queue is full. /// Handles metrics and logging for you. - pub fn send_work_item(&mut self, item: WorkItem) -> Result<(), TrySendError> { + pub fn send_work_item(&self, item: WorkItem) -> Result<(), TrySendError> { let name = item.name; let result = self.tx.try_send(item); if let Err(err) = &result { @@ -121,21 +115,20 @@ pub struct Senders { /// Catch-all queue for tasks that are either very quick to run or behave well as async task in /// the Tokio runtime. Is launched immediately and does not require capacity as defined by /// [`Config::max_workers`]. - pub permitless_tx: Sender, - pub example2_tx: Sender, + pub permitless: Sender, + pub urgent_consensus: Sender, // todo add all the needed queues here } struct Receivers { permitless_rx: mpsc::Receiver, - example2_rx: mpsc::Receiver, + urgent_consensus_rx: mpsc::Receiver, // todo add all the needed queues here } pub type AsyncFn = Pin + Send>>; pub type BlockingFn = Box; -pub type ImmediateFn = Box; -pub type StateModifierFn = Box; +pub type ImmediateFn = Box; enum WorkKind { Async(AsyncFn), @@ -153,42 +146,29 @@ impl Debug for WorkKind { } } +#[derive(Debug)] pub struct WorkItem { func: WorkKind, expiry: Option, - state_modifier: Option, name: &'static str, } -impl Debug for WorkItem { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("WorkItem") - .field("func", &self.func) - .field("expiry", &self.expiry) - .field("state_modifier", &self.state_modifier.is_some()) - .field("name", &self.name) - .finish() - } -} - impl WorkItem { /// Create an async work task. Will be spawned on the Tokio runtime. - pub fn new_async(name: &'static str, func: AsyncFn) -> Self { + pub fn new_async + Send + 'static>(name: &'static str, func: F) -> Self { Self { name, expiry: None, - state_modifier: None, - func: WorkKind::Async(func), + func: WorkKind::Async(Box::pin(func)), } } /// Create a blocking work task. Will be spawned on the Tokio runtime using `spawn_blocking`. - pub fn new_blocking(name: &'static str, func: BlockingFn) -> Self { + pub fn new_blocking(name: &'static str, func: F) -> Self { Self { name, expiry: None, - state_modifier: None, - func: WorkKind::Blocking(func), + func: WorkKind::Blocking(Box::new(func)), } } @@ -198,12 +178,14 @@ impl WorkItem { /// The [`DropOnFinish`] should be dropped when the work is done, for proper permit accounting /// and metrics. This includes any work triggered by the closure, so [`DropOnFinish`] should /// be sent along if any other process such as a QBFT instance is messaged. - pub fn new_immediate(name: &'static str, func: ImmediateFn) -> Self { + pub fn new_immediate( + name: &'static str, + func: F, + ) -> Self { Self { name, expiry: None, - state_modifier: None, - func: WorkKind::Immediate(func), + func: WorkKind::Immediate(Box::new(func)), } } @@ -217,17 +199,6 @@ impl WorkItem { self.expiry = Some(expiry); self } - - /// Before starting the work, modify the [`ProcessorState`]. Useful for storing stuff to be used - /// by [immediate](WorkItem::new_immediate) `WorkItem`s. - pub fn set_state_modifier(&mut self, state_modifier: Option) { - self.state_modifier = state_modifier; - } - - pub fn with_state_modifier(mut self, state_modifier: StateModifierFn) -> Self { - self.state_modifier = Some(state_modifier); - self - } } /// Refunds the permit and updates metrics on drop. @@ -245,27 +216,20 @@ impl Drop for DropOnFinish { } } -/// Contains several items necessary for processing immediate work items, such as queues for -/// triggering work in other parts of the client. -#[derive(Default, Debug)] -pub struct ProcessorState { - // placeholder, of course we also have to separate by validator and set data type - pub qbft_instances: HashMap>>, -} - /// Create a new processor and spawn it with the given executor. Returns the queue senders. pub fn spawn(config: Config, executor: TaskExecutor) -> Senders { - // todo macro? just specifying name and capacity? let (permitless_tx, permitless_rx) = mpsc::channel(1000); - let (example2_tx, example2_rx) = mpsc::channel(1000); + let (urgent_consensus_tx, urgent_consensus_rx) = mpsc::channel(1000); let senders = Senders { - permitless_tx: Sender { tx: permitless_tx }, - example2_tx: Sender { tx: example2_tx }, + permitless: Sender { tx: permitless_tx }, + urgent_consensus: Sender { + tx: urgent_consensus_tx, + }, }; let receivers = Receivers { permitless_rx, - example2_rx, + urgent_consensus_rx, }; executor.spawn(processor(config, receivers, executor.clone()), "processor"); @@ -274,7 +238,6 @@ pub fn spawn(config: Config, executor: TaskExecutor) -> Senders { async fn processor(config: Config, mut receivers: Receivers, executor: TaskExecutor) { let semaphore = Arc::new(Semaphore::new(config.max_workers)); - let mut state = ProcessorState::default(); loop { let _timer = metrics::start_timer(&metrics::ANCHOR_PROCESSOR_EVENT_HANDLING_SECONDS); @@ -287,7 +250,7 @@ async fn processor(config: Config, mut receivers: Receivers, executor: TaskExecu Ok(permit) = semaphore.clone().acquire_owned() => { select! { biased; - Some(w) = receivers.example2_rx.recv() => (Some(permit), Some(w)), + Some(w) = receivers.urgent_consensus_rx.recv() => (Some(permit), Some(w)), // we have a permit, so we prefer other queues at this point, // but it should still be possible to receive a permitless event @@ -329,10 +292,6 @@ async fn processor(config: Config, mut receivers: Receivers, executor: TaskExecu ), }; - if let Some(state_modifier) = work_item.state_modifier { - state_modifier(&mut state); - } - match work_item.func { WorkKind::Async(async_fn) => executor.spawn( async move { @@ -350,7 +309,7 @@ async fn processor(config: Config, mut receivers: Receivers, executor: TaskExecu work_item.name, ); } - WorkKind::Immediate(immediate_fn) => immediate_fn(&state, drop_on_finish), + WorkKind::Immediate(immediate_fn) => immediate_fn(drop_on_finish), } } } diff --git a/anchor/processor/tests/processor_tests.rs b/anchor/processor/tests/processor_tests.rs index 437678184..fdca8f96c 100644 --- a/anchor/processor/tests/processor_tests.rs +++ b/anchor/processor/tests/processor_tests.rs @@ -15,7 +15,7 @@ async fn test_max_workers() -> Result<(), Box> { let config = processor::Config { max_workers: 3 }; - let mut sender_queues = processor::spawn(config, executor); + let sender_queues = processor::spawn(config, executor); let start_sync = Arc::new(Barrier::new(4)); let continue_notify = Arc::new(Notify::new()); @@ -24,7 +24,7 @@ async fn test_max_workers() -> Result<(), Box> { for _ in 0..3 { let start_sync = start_sync.clone(); let continue_notify = continue_notify.clone(); - sender_queues.example2_tx.send_async( + sender_queues.urgent_consensus.send_async( async move { start_sync.wait().await; continue_notify.notified().await; @@ -34,11 +34,11 @@ async fn test_max_workers() -> Result<(), Box> { // throw in some permitless tasks sender_queues - .permitless_tx + .permitless .send_blocking(|| {}, "test_task2")?; sender_queues - .permitless_tx - .send_immediate(|_, _| {}, "test_task3")?; + .permitless + .send_immediate(|_| {}, "test_task3")?; } // wait until every task has been spawned @@ -50,7 +50,7 @@ async fn test_max_workers() -> Result<(), Box> { let permitless_sync = Arc::new(Barrier::new(2)); let passed_permitless_sync = permitless_sync.clone(); // now, we should be able to spawn only via the "permitless" queue - sender_queues.permitless_tx.send_async( + sender_queues.permitless.send_async( async move { passed_permitless_sync.wait().await; }, @@ -59,7 +59,7 @@ async fn test_max_workers() -> Result<(), Box> { let (did_run_tx, mut did_run_rx) = oneshot::channel(); // but other queues should only run after we freed up space: - sender_queues.example2_tx.send_async( + sender_queues.urgent_consensus.send_async( async move { let _ = did_run_tx.send(()); }, diff --git a/anchor/signature_collector/Cargo.toml b/anchor/signature_collector/Cargo.toml new file mode 100644 index 000000000..aba98d56a --- /dev/null +++ b/anchor/signature_collector/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "signature_collector" +version = "0.1.0" +edition = { workspace = true } +authors = ["Sigma Prime "] + +[dependencies] +dashmap = { workspace = true } +processor = { workspace = true } +ssv_types = { workspace = true } +tokio = { workspace = true, features = ["sync"] } +tracing = { workspace = true } +types = { workspace = true } diff --git a/anchor/signature_collector/src/lib.rs b/anchor/signature_collector/src/lib.rs new file mode 100644 index 000000000..41e1685f2 --- /dev/null +++ b/anchor/signature_collector/src/lib.rs @@ -0,0 +1,216 @@ +use dashmap::DashMap; +use processor::{DropOnFinish, Senders, WorkItem}; +use ssv_types::{ClusterId, OperatorId}; +use std::collections::{hash_map, HashMap}; +use std::mem; +use std::sync::Arc; +use tokio::sync::mpsc::error::TrySendError; +use tokio::sync::mpsc::UnboundedSender; +use tokio::sync::oneshot::error::RecvError; +use tokio::sync::{mpsc, oneshot}; +use tracing::error; +use types::{Hash256, SecretKey, Signature}; + +const COLLECTOR_NAME: &str = "signature_collector"; +const COLLECTOR_MESSAGE_NAME: &str = "signature_collector_message"; +const SIGNER_NAME: &str = "signer"; + +pub struct SignatureCollectorManager { + processor: Senders, + signature_collectors: DashMap>, +} + +impl SignatureCollectorManager { + pub fn new(processor: Senders) -> Self { + Self { + processor, + signature_collectors: DashMap::new(), + } + } + + pub async fn sign_and_collect( + self: &Arc, + request: SignatureRequest, + our_operator_id: OperatorId, + our_key: SecretKey, + ) -> Result, CollectionError> { + let (result_tx, result_rx) = oneshot::channel(); + + // first, register notifier + let cloned_request = request.clone(); + let manager = self.clone(); + self.processor.permitless.send_immediate( + move |drop_on_finish| { + let sender = manager.get_or_spawn(cloned_request); + let _ = sender.send(CollectorMessage { + kind: CollectorMessageKind::Notify { notify: result_tx }, + drop_on_finish, + }); + }, + COLLECTOR_MESSAGE_NAME, + )?; + + // then, trigger signing via blocking code + let manager = self.clone(); + self.processor.urgent_consensus.send_blocking( + move || { + let signature = Box::new(our_key.sign(request.signing_root)); + let _ = manager.receive_partial_signature(request, our_operator_id, signature); + // TODO send signature over network + }, + SIGNER_NAME, + )?; + + // finally, we resolve the collector future - if we are lucky, the signature is even already + // done (as we received enough shares before this fn is even called) + Ok(result_rx.await?) + } + + pub fn receive_partial_signature( + self: &Arc, + request: SignatureRequest, + operator_id: OperatorId, + signature: Box, + ) -> Result<(), CollectionError> { + let manager = self.clone(); + self.processor.permitless.send_immediate( + move |drop_on_finish| { + let sender = manager.get_or_spawn(request); + let _ = sender.send(CollectorMessage { + kind: CollectorMessageKind::PartialSignature { + operator_id, + signature, + }, + drop_on_finish, + }); + }, + COLLECTOR_MESSAGE_NAME, + )?; + Ok(()) + } + + pub fn remove(&self, signing_hash: Hash256) { + self.signature_collectors.remove(&signing_hash); + } + + fn get_or_spawn(&self, request: SignatureRequest) -> UnboundedSender { + match self.signature_collectors.entry(request.signing_root) { + dashmap::Entry::Occupied(entry) => entry.get().clone(), + dashmap::Entry::Vacant(entry) => { + let (tx, rx) = mpsc::unbounded_channel(); + let tx = entry.insert(tx); + let _ = self + .processor + .permitless + .send_async(Box::pin(signature_collector(rx, request)), COLLECTOR_NAME); + tx.clone() + } + } + } +} + +#[derive(Debug, Clone)] +pub struct SignatureRequest { + pub cluster_id: ClusterId, + pub signing_root: Hash256, + pub threshold: u64, +} + +pub struct CollectorMessage { + pub kind: CollectorMessageKind, + pub drop_on_finish: DropOnFinish, +} + +pub enum CollectorMessageKind { + Notify { + notify: oneshot::Sender>, + }, + PartialSignature { + operator_id: OperatorId, + signature: Box, + }, +} + +#[derive(Debug)] +pub enum CollectionError { + QueueClosedError, + QueueFullError, + CollectionTimeout, +} + +impl From> for CollectionError { + fn from(value: TrySendError) -> Self { + match value { + TrySendError::Full(_) => CollectionError::QueueFullError, + TrySendError::Closed(_) => CollectionError::QueueClosedError, + } + } +} + +impl From for CollectionError { + fn from(_: RecvError) -> Self { + CollectionError::QueueClosedError + } +} + +async fn signature_collector( + mut rx: mpsc::UnboundedReceiver, + request: SignatureRequest, +) { + let mut notifiers = vec![]; + let mut signature_share = HashMap::new(); + let mut full_signature: Option> = None; + + while let Some(message) = rx.recv().await { + match message.kind { + CollectorMessageKind::Notify { notify } => { + if let Some(full_signature) = &full_signature { + let _ = notify.send(full_signature.clone()); + } else { + notifiers.push(notify); + } + } + CollectorMessageKind::PartialSignature { + operator_id, + signature, + } => { + if full_signature.is_some() { + // already got the full signature :) + continue; + } + + // always insert to make sure we're not duplicated + match signature_share.entry(operator_id) { + hash_map::Entry::Vacant(entry) => { + entry.insert(signature); + } + hash_map::Entry::Occupied(entry) => { + if entry.get() != &signature { + error!( + ?operator_id, + "received conflicting signatures from operator" + ); + } + } + } + + if signature_share.len() as u64 >= request.threshold { + // TODO move to blocking threadpool? + + // TODO do magic crypto to actually restore signature, for now hackily take first one + let signature = mem::take(&mut signature_share) + .into_iter() + .next() + .unwrap() + .1 + .into(); + + for notifier in mem::take(&mut notifiers) { + let _ = notifier.send(Arc::clone(&signature)); + } + full_signature = Some(signature); + } + } + } + } +} From 35c4132cc1bb4d033374619914b5ece485e39ad4 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 13 Dec 2024 15:05:31 +0100 Subject: [PATCH 02/21] create validator store and basic wire up everything --- Cargo.lock | 2281 ++++++----------------------- Cargo.toml | 23 +- anchor/Cargo.toml | 1 + anchor/client/Cargo.toml | 8 + anchor/client/src/config.rs | 6 + anchor/client/src/lib.rs | 462 +++++- anchor/http_metrics/Cargo.toml | 2 +- anchor/http_metrics/src/lib.rs | 2 +- anchor/src/main.rs | 3 +- anchor/validator_store/Cargo.toml | 14 + anchor/validator_store/src/lib.rs | 215 +++ 11 files changed, 1131 insertions(+), 1886 deletions(-) create mode 100644 anchor/validator_store/Cargo.toml create mode 100644 anchor/validator_store/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a505c8491..32589978c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,26 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "account_utils" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "directory 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "eth2_keystore", - "eth2_wallet", - "filesystem", - "rand", - "regex", - "rpassword", - "serde", - "serde_yaml", - "slog", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "validator_dir", - "zeroize", -] - [[package]] name = "addr2line" version = "0.24.2" @@ -118,55 +98,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "alloy-consensus" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629b62e38d471cc15fea534eb7283d2f8a4e8bdb1811bcc5d66dda6cfce6fae1" -dependencies = [ - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "c-kzg", -] - -[[package]] -name = "alloy-eip2930" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" -dependencies = [ - "alloy-primitives", - "alloy-rlp", -] - -[[package]] -name = "alloy-eip7702" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea59dc42102bc9a1905dc57901edc6dd48b9f38115df86c7d252acba70d71d04" -dependencies = [ - "alloy-primitives", - "alloy-rlp", -] - -[[package]] -name = "alloy-eips" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f923dd5fca5f67a43d81ed3ebad0880bd41f6dd0ada930030353ac356c54cd0f" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives", - "alloy-rlp", - "c-kzg", - "derive_more 1.0.0", - "once_cell", - "serde", - "sha2 0.10.8", -] - [[package]] name = "alloy-primitives" version = "0.8.15" @@ -186,7 +117,7 @@ dependencies = [ "hex-literal", "indexmap", "itoa", - "k256 0.13.4", + "k256", "keccak-asm", "paste", "proptest", @@ -195,7 +126,7 @@ dependencies = [ "ruint", "rustc-hash 2.1.0", "serde", - "sha3 0.10.8", + "sha3", "tiny-keccak", ] @@ -231,12 +162,25 @@ dependencies = [ "dirs 5.0.1", "futures", "regex", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "sensitive_url", "serde", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tokio", "tracing", "tracing-subscriber", + "types", +] + +[[package]] +name = "anchor_validator_store" +version = "0.1.0" +dependencies = [ + "dashmap", + "processor", + "ssv_types", + "tracing", + "types", + "validator_store", ] [[package]] @@ -683,12 +627,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -720,72 +658,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] -name = "beacon_chain" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +name = "beacon_node_fallback" +version = "0.1.0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "alloy-primitives", - "bitvec 1.0.1", - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "derivative", - "eth1", "eth2", - "eth2_network_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "execution_layer", - "fork_choice", "futures", - "genesis", - "hex", - "int_to_bytes 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", "itertools 0.10.5", - "kzg 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "lighthouse_version 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "lru", - "merkle_proof 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "oneshot_broadcast", - "operation_pool", - "parking_lot 0.12.3", - "proto_array", - "rand", - "rayon", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", "serde", - "serde_json", - "slasher", - "slog", - "slog-async", - "slog-term", - "sloggers", "slot_clock", - "smallvec", - "ssz_types", - "state_processing", - "store", "strum", - "superstruct", - "task_executor 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tempfile", + "task_executor", "tokio", - "tokio-stream", - "tree_hash", - "tree_hash_derive", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "tracing", + "types", + "validator_metrics", ] [[package]] -name = "bincode" -version = "1.3.3" +name = "bindgen" +version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "serde", + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.10.5", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.90", + "which", ] [[package]] @@ -815,28 +725,16 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "bitvec" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" -dependencies = [ - "funty 1.1.0", - "radium 0.6.2", - "tap", - "wyz 0.2.0", -] - [[package]] name = "bitvec" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" dependencies = [ - "funty 2.0.0", - "radium 0.7.0", + "funty", + "radium", "tap", - "wyz 0.5.1", + "wyz", ] [[package]] @@ -854,7 +752,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -867,36 +764,10 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "bls" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "arbitrary", - "blst", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "fixed_bytes 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "hex", - "rand", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "tree_hash", - "zeroize", -] - [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "arbitrary", @@ -904,10 +775,10 @@ dependencies = [ "ethereum_hashing", "ethereum_serde_utils", "ethereum_ssz", - "fixed_bytes 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "fixed_bytes", "hex", "rand", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "safe_arith", "serde", "tree_hash", "zeroize", @@ -933,8 +804,8 @@ checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" dependencies = [ "blst", "byte-slice-cast", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "pairing", "rand_core", "serde", @@ -950,18 +821,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "builder_client" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "eth2", - "lighthouse_version 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", -] - [[package]] name = "bumpalo" version = "3.16.0" @@ -1021,8 +880,6 @@ dependencies = [ "glob", "hex", "libc", - "once_cell", - "serde", ] [[package]] @@ -1036,6 +893,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -1104,6 +970,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.23" @@ -1148,58 +1025,49 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "clap", - "dirs 3.0.2", - "eth2_network_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "ethereum_ssz", - "hex", - "serde", - "serde_json", - "serde_yaml", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "clap_utils" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "clap", "dirs 3.0.2", - "eth2_network_config 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "eth2_network_config", "ethereum_ssz", "hex", "serde", "serde_json", "serde_yaml", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", ] [[package]] name = "client" version = "0.1.0" dependencies = [ + "anchor_validator_store", + "beacon_node_fallback", "clap", "dirs 5.0.1", + "eth2", + "eth2_config", "ethereum_hashing", "fdlimit", "http_api", "http_metrics", "hyper 1.5.1", "network", - "parking_lot 0.12.3", + "parking_lot", "processor", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "sensitive_url", "serde", + "slot_clock", "strum", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tokio", "tracing", - "unused_port 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", + "unused_port", + "validator_metrics", + "validator_services", "version", ] @@ -1221,15 +1089,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "itertools 0.10.5", -] - -[[package]] -name = "compare_fields" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "itertools 0.10.5", ] @@ -1237,16 +1097,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "compare_fields_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "quote", "syn 1.0.109", @@ -1337,8 +1188,8 @@ checksum = "319cb241b1ad37f8c376b2ebcd7233f53e033a50de6f0a9cf38e6cc545554de4" dependencies = [ "blst", "blstrs", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "pairing", "subtle", ] @@ -1430,18 +1281,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core", - "subtle", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.5" @@ -1503,16 +1342,6 @@ dependencies = [ "cipher 0.4.4", ] -[[package]] -name = "ctrlc" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" -dependencies = [ - "nix 0.29.0", - "windows-sys 0.59.0", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1647,7 +1476,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.10", + "parking_lot_core", ] [[package]] @@ -1682,16 +1511,6 @@ version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b72465f46d518f6015d9cf07f7f3013a95dd6b9c2747c3d65ae0cce43929d14f" -[[package]] -name = "delay_map" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4355c25cbf99edcb6b4a0e906f6bdc6956eda149e84455bea49696429b2f8e8" -dependencies = [ - "futures", - "tokio-util", -] - [[package]] name = "delay_map" version = "0.4.0" @@ -1703,31 +1522,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "deposit_contract" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "ethabi 16.0.0", - "ethereum_ssz", - "hex", - "reqwest", - "serde_json", - "sha2 0.9.9", - "tree_hash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "der" version = "0.7.9" @@ -1841,21 +1635,11 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "clap", - "clap_utils 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "eth2_network_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "directory" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "clap", - "clap_utils 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "eth2_network_config 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "clap_utils", + "eth2_network_config", ] [[package]] @@ -1922,80 +1706,47 @@ dependencies = [ [[package]] name = "discv5" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f569b8c367554666c8652305621e8bae3634a2ff5c6378081d5bd8c399c99f23" +checksum = "23e6b70634e26c909d1edbb3142b3eaf3b89da0e52f284f00ca7c80d9901ad9e" dependencies = [ "aes 0.8.4", "aes-gcm", "alloy-rlp", "arrayvec", "ctr 0.9.2", - "delay_map 0.3.0", + "delay_map", "enr 0.12.1", "fnv", "futures", - "hashlink 0.8.4", + "hashlink 0.9.1", "hex", "hkdf", "lazy_static", - "libp2p-identity", "lru", "more-asserts", - "multiaddr", - "parking_lot 0.11.2", + "parking_lot", "rand", "smallvec", - "socket2 0.4.10", + "socket2", "tokio", "tracing", - "uint 0.9.5", + "uint 0.10.0", "zeroize", ] [[package]] name = "discv5" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e6b70634e26c909d1edbb3142b3eaf3b89da0e52f284f00ca7c80d9901ad9e" +checksum = "898d136ecb64116ec68aecf14d889bd30f8b1fe0c19e262953f7388dbe77052e" dependencies = [ "aes 0.8.4", "aes-gcm", "alloy-rlp", "arrayvec", "ctr 0.9.2", - "delay_map 0.4.0", - "enr 0.12.1", - "fnv", - "futures", - "hashlink 0.9.1", - "hex", - "hkdf", - "lazy_static", - "lru", - "more-asserts", - "parking_lot 0.12.3", - "rand", - "smallvec", - "socket2 0.5.8", - "tokio", - "tracing", - "uint 0.10.0", - "zeroize", -] - -[[package]] -name = "discv5" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "898d136ecb64116ec68aecf14d889bd30f8b1fe0c19e262953f7388dbe77052e" -dependencies = [ - "aes 0.8.4", - "aes-gcm", - "alloy-rlp", - "arrayvec", - "ctr 0.9.2", - "delay_map 0.4.0", + "delay_map", "enr 0.13.0", "fnv", "futures", @@ -2007,10 +1758,10 @@ dependencies = [ "lru", "more-asserts", "multiaddr", - "parking_lot 0.12.3", + "parking_lot", "rand", "smallvec", - "socket2 0.5.8", + "socket2", "tokio", "tracing", "uint 0.10.0", @@ -2034,30 +1785,18 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.9", + "der", "digest 0.10.7", - "elliptic-curve 0.13.8", - "rfc6979 0.4.0", - "signature 2.2.0", - "spki 0.7.3", + "elliptic-curve", + "rfc6979", + "signature", + "spki", ] [[package]] @@ -2066,8 +1805,8 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", + "pkcs8", + "signature", ] [[package]] @@ -2091,41 +1830,22 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "rand_core", - "sec1 0.3.0", - "subtle", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array", - "group 0.13.0", + "group", "pem-rfc7468", - "pkcs8 0.10.2", + "pkcs8", "rand_core", - "sec1 0.7.3", + "sec1", "subtle", "zeroize", ] @@ -2150,11 +1870,11 @@ dependencies = [ "bytes", "ed25519-dalek", "hex", - "k256 0.13.4", + "k256", "log", "rand", "serde", - "sha3 0.10.8", + "sha3", "zeroize", ] @@ -2169,11 +1889,11 @@ dependencies = [ "bytes", "ed25519-dalek", "hex", - "k256 0.13.4", + "k256", "log", "rand", "serde", - "sha3 0.10.8", + "sha3", "zeroize", ] @@ -2189,28 +1909,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "environment" -version = "0.1.2" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "async-channel", - "ctrlc", - "eth2_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "eth2_network_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "futures", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "slog", - "slog-async", - "slog-json", - "slog-term", - "sloggers", - "task_executor 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tokio", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -2236,48 +1934,11 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "error-chain" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" -dependencies = [ - "backtrace", - "version_check", -] - -[[package]] -name = "eth1" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "eth2", - "ethereum_ssz", - "ethereum_ssz_derive", - "execution_layer", - "futures", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "merkle_proof 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "slog", - "state_processing", - "superstruct", - "task_executor 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tokio", - "tree_hash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "account_utils", - "bytes", "derivative", "eth2_keystore", "ethereum_serde_utils", @@ -2285,61 +1946,38 @@ dependencies = [ "ethereum_ssz_derive", "futures", "futures-util", - "libsecp256k1", - "lighthouse_network 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "lighthouse_network", "mediatype", - "pretty_reqwest_error 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "pretty_reqwest_error", "procfs", "proto_array", "psutil", "reqwest", - "ring 0.16.20", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "sensitive_url", "serde", "serde_json", "slashing_protection", "ssz_types", "store", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "eth2_config" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "paste", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "types", + "zeroize", ] [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "paste", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", ] [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "ethereum_hashing", - "hex", - "num-bigint", - "serde", - "serde_yaml", -] - -[[package]] -name = "eth2_interop_keypairs" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" -dependencies = [ - "bls 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "bls", "ethereum_hashing", "hex", "num-bigint", @@ -2350,9 +1988,9 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "bls", "num-bigint-dig", "ring 0.16.20", "sha2 0.9.9", @@ -2362,10 +2000,10 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "aes 0.7.5", - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "bls", "eth2_key_derivation", "hex", "hmac 0.11.0", @@ -2384,150 +2022,24 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "bytes", - "discv5 0.7.0", - "eth2_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "kzg 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "pretty_reqwest_error 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde_yaml", - "sha2 0.9.9", - "slog", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "url", - "zip", -] - -[[package]] -name = "eth2_network_config" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "bytes", "discv5 0.9.0", - "eth2_config 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "kzg 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "logging 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "pretty_reqwest_error 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "eth2_config", + "kzg", + "logging", + "pretty_reqwest_error", "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "sensitive_url", "serde_yaml", "sha2 0.9.9", "slog", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", "url", "zip", ] -[[package]] -name = "eth2_wallet" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "eth2_key_derivation", - "eth2_keystore", - "rand", - "serde", - "serde_json", - "serde_repr", - "tiny-bip39", - "uuid", -] - -[[package]] -name = "ethabi" -version = "16.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c98847055d934070b90e806e12d3936b787d0a115068981c1d8dfd5dfef5a5" -dependencies = [ - "ethereum-types 0.12.1", - "hex", - "serde", - "serde_json", - "sha3 0.9.1", - "thiserror 1.0.69", - "uint 0.9.5", -] - -[[package]] -name = "ethabi" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" -dependencies = [ - "ethereum-types 0.14.1", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror 1.0.69", - "uint 0.9.5", -] - -[[package]] -name = "ethbloom" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" -dependencies = [ - "crunchy", - "fixed-hash 0.7.0", - "impl-rlp", - "impl-serde 0.3.2", - "tiny-keccak", -] - -[[package]] -name = "ethbloom" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" -dependencies = [ - "crunchy", - "fixed-hash 0.8.0", - "impl-codec 0.6.0", - "impl-rlp", - "impl-serde 0.4.0", - "scale-info", - "tiny-keccak", -] - -[[package]] -name = "ethereum-types" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" -dependencies = [ - "ethbloom 0.11.1", - "fixed-hash 0.7.0", - "impl-rlp", - "impl-serde 0.3.2", - "primitive-types 0.10.1", - "uint 0.9.5", -] - -[[package]] -name = "ethereum-types" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" -dependencies = [ - "ethbloom 0.13.0", - "fixed-hash 0.8.0", - "impl-codec 0.6.0", - "impl-rlp", - "impl-serde 0.4.0", - "primitive-types 0.12.2", - "scale-info", - "uint 0.9.5", -] - [[package]] name = "ethereum_hashing" version = "0.7.0" @@ -2575,32 +2087,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "ethers-core" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" -dependencies = [ - "arrayvec", - "bytes", - "chrono", - "elliptic-curve 0.12.3", - "ethabi 18.0.0", - "generic-array", - "hex", - "k256 0.11.6", - "open-fastrlp", - "rand", - "rlp", - "rlp-derive", - "serde", - "serde_json", - "strum", - "thiserror 1.0.69", - "tiny-keccak", - "unicode-xid", -] - [[package]] name = "event-listener" version = "2.5.3" @@ -2628,60 +2114,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "execution_layer" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-consensus", - "alloy-primitives", - "alloy-rlp", - "arc-swap", - "builder_client", - "bytes", - "eth2", - "eth2_network_config 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "ethereum_serde_utils", - "ethereum_ssz", - "ethers-core", - "fixed_bytes 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "fork_choice", - "hash-db", - "hash256-std-hasher", - "hex", - "jsonwebtoken", - "keccak-hash", - "kzg 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "lighthouse_version 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "lru", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "pretty_reqwest_error 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "rand", - "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "serde_json", - "sha2 0.9.9", - "slog", - "slot_clock", - "ssz_types", - "state_processing", - "strum", - "superstruct", - "task_executor 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tempfile", - "tokio", - "tokio-stream", - "tree_hash", - "tree_hash_derive", - "triehash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "warp", - "zeroize", -] - [[package]] name = "fallible-iterator" version = "0.2.0" @@ -2721,23 +2153,13 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core", - "subtle", -] - [[package]] name = "ff" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec 1.0.1", + "bitvec", "rand_core", "subtle", ] @@ -2767,24 +2189,12 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "winapi", "windows-acl", ] -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand", - "rustc-hex", - "static_assertions", -] - [[package]] name = "fixed-hash" version = "0.8.0" @@ -2800,19 +2210,10 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "fixed_bytes" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" -dependencies = [ - "alloy-primitives", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "safe_arith", ] [[package]] @@ -2822,7 +2223,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", - "libz-sys", "miniz_oxide", ] @@ -2853,20 +2253,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "fork_choice" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "ethereum_ssz", - "ethereum_ssz_derive", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "proto_array", - "slog", - "state_processing", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2876,22 +2262,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "funty" version = "2.0.0" @@ -3047,26 +2417,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "genesis" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "environment", - "eth1", - "ethereum_hashing", - "ethereum_ssz", - "futures", - "int_to_bytes 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "merkle_proof 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "rayon", - "slog", - "state_processing", - "tokio", - "tree_hash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -3117,45 +2467,15 @@ dependencies = [ ] [[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "gossipsub" -version = "0.5.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "async-channel", - "asynchronous-codec", - "base64 0.21.7", - "byteorder", - "bytes", - "either", - "fnv", - "futures", - "futures-ticker", - "futures-timer", - "getrandom", - "hashlink 0.9.1", - "hex_fmt", - "libp2p", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand", - "regex", - "sha2 0.10.8", - "tracing", - "void", - "web-time", -] - -[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "async-channel", "asynchronous-codec", @@ -3182,14 +2502,14 @@ dependencies = [ ] [[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +name = "graffiti_file" +version = "0.1.0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "ff 0.12.1", - "rand_core", - "subtle", + "bls", + "serde", + "slog", + "types", ] [[package]] @@ -3198,7 +2518,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand", "rand_core", "rand_xorshift", @@ -3224,21 +2544,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hash-db" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" - -[[package]] -name = "hash256-std-hasher" -version = "0.15.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" -dependencies = [ - "crunchy", -] - [[package]] name = "hashbrown" version = "0.14.5" @@ -3279,30 +2584,6 @@ dependencies = [ "hashbrown 0.14.5", ] -[[package]] -name = "headers" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" -dependencies = [ - "base64 0.21.7", - "bytes", - "headers-core", - "http 0.2.12", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http 0.2.12", -] - [[package]] name = "heck" version = "0.4.1" @@ -3365,7 +2646,7 @@ dependencies = [ "ipnet", "once_cell", "rand", - "socket2 0.5.8", + "socket2", "thiserror 1.0.69", "tinyvec", "tokio", @@ -3385,7 +2666,7 @@ dependencies = [ "ipconfig", "lru-cache", "once_cell", - "parking_lot 0.12.3", + "parking_lot", "rand", "resolv-conf", "smallvec", @@ -3443,6 +2724,15 @@ dependencies = [ "hmac 0.8.1", ] +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "hostname" version = "0.3.1" @@ -3517,7 +2807,7 @@ dependencies = [ "axum", "serde", "slot_clock", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tokio", "tracing", ] @@ -3527,14 +2817,13 @@ name = "http_metrics" version = "0.1.0" dependencies = [ "axum", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", + "metrics", + "parking_lot", "serde", "tokio", "tower-http", "tracing", "validator_metrics", - "warp_utils", ] [[package]] @@ -3566,7 +2855,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.8", + "socket2", "tokio", "tower-service", "tracing", @@ -3603,7 +2892,7 @@ dependencies = [ "hyper 0.14.31", "rustls 0.21.12", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", ] [[package]] @@ -3855,49 +3144,13 @@ dependencies = [ "xmltree", ] -[[package]] -name = "impl-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "161ebdfec3c8e3b52bf61c4f3550a1eea4f9579d10dc1b936f3171ebdcd6c443" -dependencies = [ - "parity-scale-codec 2.3.1", -] - [[package]] name = "impl-codec" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.12", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-serde" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" -dependencies = [ - "serde", + "parity-scale-codec", ] [[package]] @@ -3944,15 +3197,7 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "bytes", -] - -[[package]] -name = "int_to_bytes" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "bytes", ] @@ -3983,7 +3228,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.8", + "socket2", "widestring 1.1.0", "windows-sys 0.48.0", "winreg", @@ -4055,34 +3300,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "9.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" -dependencies = [ - "base64 0.21.7", - "js-sys", - "pem", - "ring 0.17.8", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", - "sha3 0.10.8", -] - [[package]] name = "k256" version = "0.13.4" @@ -4090,11 +3307,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "once_cell", "sha2 0.10.8", - "signature 2.2.0", + "signature", ] [[package]] @@ -4116,39 +3333,10 @@ dependencies = [ "sha3-asm", ] -[[package]] -name = "keccak-hash" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b286e6b663fb926e1eeb68528e69cb70ed46c6d65871a21b2215ae8154c6d3c" -dependencies = [ - "primitive-types 0.12.2", - "tiny-keccak", -] - -[[package]] -name = "kzg" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "arbitrary", - "c-kzg", - "derivative", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "hex", - "rust_eth_kzg", - "serde", - "serde_json", - "tree_hash", -] - [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "arbitrary", "c-kzg", @@ -4173,6 +3361,12 @@ dependencies = [ "spin 0.9.8", ] +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "leveldb" version = "0.8.6" @@ -4226,6 +3420,16 @@ dependencies = [ "rle-decode-fast", ] +[[package]] +name = "libloading" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.48.5", +] + [[package]] name = "libm" version = "0.2.11" @@ -4305,7 +3509,7 @@ dependencies = [ "multihash", "multistream-select", "once_cell", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "quick-protobuf", "rand", @@ -4329,7 +3533,7 @@ dependencies = [ "hickory-resolver", "libp2p-core", "libp2p-identity", - "parking_lot 0.12.3", + "parking_lot", "smallvec", "tracing", ] @@ -4403,7 +3607,7 @@ dependencies = [ "p256", "quick-protobuf", "rand", - "sec1 0.7.3", + "sec1", "sha2 0.10.8", "thiserror 1.0.69", "tracing", @@ -4425,7 +3629,7 @@ dependencies = [ "libp2p-swarm", "rand", "smallvec", - "socket2 0.5.8", + "socket2", "tokio", "tracing", "void", @@ -4461,7 +3665,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "nohash-hasher", - "parking_lot 0.12.3", + "parking_lot", "rand", "smallvec", "tracing", @@ -4541,12 +3745,12 @@ dependencies = [ "libp2p-core", "libp2p-identity", "libp2p-tls", - "parking_lot 0.12.3", + "parking_lot", "quinn", "rand", "ring 0.17.8", "rustls 0.23.19", - "socket2 0.5.8", + "socket2", "thiserror 1.0.69", "tokio", "tracing", @@ -4600,7 +3804,7 @@ dependencies = [ "libc", "libp2p-core", "libp2p-identity", - "socket2 0.5.8", + "socket2", "tokio", "tracing", ] @@ -4724,77 +3928,16 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libz-sys" -version = "1.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lighthouse_network" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "bytes", - "delay_map 0.3.0", - "directory 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "dirs 3.0.2", - "discv5 0.7.0", - "either", - "error-chain", - "ethereum_ssz", - "ethereum_ssz_derive", - "fnv", - "futures", - "gossipsub 0.5.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "hex", - "itertools 0.10.5", - "libp2p", - "libp2p-mplex", - "lighthouse_version 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "lru", - "lru_cache 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "prometheus-client", - "rand", - "regex", - "serde", - "sha2 0.9.9", - "slog", - "smallvec", - "snap", - "ssz_types", - "strum", - "superstruct", - "task_executor 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tiny-keccak", - "tokio", - "tokio-io-timeout", - "tokio-util", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "unsigned-varint 0.8.0", - "unused_port 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "void", -] - [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "alloy-rlp", "bytes", - "delay_map 0.4.0", - "directory 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "delay_map", + "directory", "dirs 3.0.2", "discv5 0.9.0", "either", @@ -4802,16 +3945,16 @@ dependencies = [ "ethereum_ssz_derive", "fnv", "futures", - "gossipsub 0.5.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "gossipsub", "hex", "itertools 0.10.5", "libp2p", "libp2p-mplex", - "lighthouse_version 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "lighthouse_version", "lru", - "lru_cache 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "metrics 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "parking_lot 0.12.3", + "lru_cache", + "metrics", + "parking_lot", "prometheus-client", "rand", "regex", @@ -4823,30 +3966,21 @@ dependencies = [ "ssz_types", "strum", "superstruct", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tiny-keccak", "tokio", "tokio-io-timeout", "tokio-util", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", "unsigned-varint 0.8.0", - "unused_port 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "unused_port", "void", ] [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "git-version", - "target_info", -] - -[[package]] -name = "lighthouse_version" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "git-version", "target_info", @@ -4886,14 +4020,6 @@ dependencies = [ "scopeguard", ] -[[package]] -name = "lockfile" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "fs2", -] - [[package]] name = "log" version = "0.4.22" @@ -4903,33 +4029,11 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "chrono", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "serde", - "serde_json", - "slog", - "slog-term", - "sloggers", - "take_mut", - "tokio", - "tracing", - "tracing-appender", - "tracing-core", - "tracing-log", - "tracing-subscriber", -] - -[[package]] -name = "logging" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "chrono", - "metrics 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "parking_lot 0.12.3", + "metrics", + "parking_lot", "serde", "serde_json", "slog", @@ -4965,15 +4069,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "fnv", -] - -[[package]] -name = "lru_cache" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "fnv", ] @@ -5038,23 +4134,12 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "ethereum_hashing", - "fixed_bytes 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "merkle_proof" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "ethereum_hashing", - "fixed_bytes 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "fixed_bytes", + "safe_arith", ] [[package]] @@ -5083,15 +4168,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "prometheus", -] - -[[package]] -name = "metrics" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "prometheus", ] @@ -5109,7 +4186,7 @@ dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", "itertools 0.13.0", - "parking_lot 0.12.3", + "parking_lot", "rayon", "serde", "smallvec", @@ -5125,16 +4202,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -5312,9 +4379,9 @@ dependencies = [ "discv5 0.8.0", "futures", "libp2p", - "lighthouse_network 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "lighthouse_network", "serde", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tokio", "tracing", "version", @@ -5337,20 +4404,8 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", -] - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.6.0", + "bitflags 1.3.2", "cfg-if", - "cfg_aliases", "libc", ] @@ -5478,45 +4533,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" -[[package]] -name = "oneshot_broadcast" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "parking_lot 0.12.3", -] - [[package]] name = "opaque-debug" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "ethereum-types 0.14.1", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "openssl" version = "0.10.68" @@ -5571,26 +4593,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "operation_pool" -version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "bitvec 1.0.1", - "derivative", - "ethereum_ssz", - "ethereum_ssz_derive", - "itertools 0.10.5", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "rand", - "rayon", - "serde", - "state_processing", - "store", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -5609,8 +4611,8 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ - "ecdsa 0.16.9", - "elliptic-curve 0.13.8", + "ecdsa", + "elliptic-curve", "primeorder", "sha2 0.10.8", ] @@ -5621,21 +4623,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group 0.13.0", -] - -[[package]] -name = "parity-scale-codec" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373b1a4c1338d9cd3d1fa53b3a11bdab5ab6bd80a20f7f7becd76953ae2be909" -dependencies = [ - "arrayvec", - "bitvec 0.20.4", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive 2.3.1", - "serde", + "group", ] [[package]] @@ -5645,32 +4633,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec", - "bitvec 1.0.1", + "bitvec", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.12", + "parity-scale-codec-derive", "serde", ] -[[package]] -name = "parity-scale-codec-derive" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "parity-scale-codec-derive" version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 1.0.109", @@ -5682,17 +4658,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.3" @@ -5700,21 +4665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -5725,7 +4676,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.7", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -5836,24 +4787,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.9", - "spki 0.7.3", + "der", + "spki", ] [[package]] @@ -5924,19 +4865,20 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "sensitive_url", ] [[package]] -name = "pretty_reqwest_error" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ - "reqwest", - "sensitive_url 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "proc-macro2", + "syn 2.0.90", ] [[package]] @@ -5945,20 +4887,7 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "elliptic-curve 0.13.8", -] - -[[package]] -name = "primitive-types" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" -dependencies = [ - "fixed-hash 0.7.0", - "impl-codec 0.5.1", - "impl-rlp", - "impl-serde 0.3.2", - "uint 0.9.5", + "elliptic-curve", ] [[package]] @@ -5967,31 +4896,18 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ - "fixed-hash 0.8.0", - "impl-codec 0.6.0", - "impl-rlp", - "impl-serde 0.4.0", - "scale-info", + "fixed-hash", + "impl-codec", "uint 0.9.5", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -6009,10 +4925,10 @@ version = "0.1.0" dependencies = [ "async-channel", "futures", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "metrics", "num_cpus", "serde", - "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "task_executor", "tokio", "tracing", ] @@ -6042,7 +4958,7 @@ dependencies = [ "fnv", "lazy_static", "memchr", - "parking_lot 0.12.3", + "parking_lot", "protobuf", "thiserror 1.0.69", ] @@ -6055,7 +4971,7 @@ checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.3", + "parking_lot", "prometheus-client-derive-encode", ] @@ -6104,15 +5020,15 @@ dependencies = [ [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "safe_arith", "serde", "serde_yaml", "superstruct", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "types", ] [[package]] @@ -6192,7 +5108,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.0", "rustls 0.23.19", - "socket2 0.5.8", + "socket2", "thiserror 2.0.6", "tokio", "tracing", @@ -6227,7 +5143,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.8", + "socket2", "tracing", "windows-sys 0.59.0", ] @@ -6248,7 +5164,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" dependencies = [ "log", - "parking_lot 0.12.3", + "parking_lot", "scheduled-thread-pool", ] @@ -6262,12 +5178,6 @@ dependencies = [ "rusqlite", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "radium" version = "0.7.0" @@ -6346,15 +5256,6 @@ dependencies = [ "yasna", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.7" @@ -6445,7 +5346,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-pemfile 1.0.4", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", @@ -6453,7 +5354,7 @@ dependencies = [ "system-configuration 0.5.1", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.1", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -6475,17 +5376,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac 0.12.1", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -6542,27 +5432,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rlp-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "rpassword" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "rpds" version = "0.11.0" @@ -6604,8 +5473,8 @@ dependencies = [ "fastrlp", "num-bigint", "num-traits", - "parity-scale-codec 3.6.12", - "primitive-types 0.12.2", + "parity-scale-codec", + "primitive-types", "proptest", "rand", "rlp", @@ -6739,20 +5608,6 @@ dependencies = [ "sct", ] -[[package]] -name = "rustls" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-pki-types", - "rustls-webpki 0.102.8", - "subtle", - "zeroize", -] - [[package]] name = "rustls" version = "0.23.19" @@ -6776,15 +5631,6 @@ dependencies = [ "base64 0.21.7", ] -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.10.0" @@ -6853,12 +5699,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" - -[[package]] -name = "safe_arith" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" [[package]] name = "salsa20" @@ -6869,30 +5710,6 @@ dependencies = [ "cipher 0.3.0", ] -[[package]] -name = "scale-info" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" -dependencies = [ - "cfg-if", - "derive_more 1.0.0", - "parity-scale-codec 3.6.12", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" -dependencies = [ - "proc-macro-crate 3.2.0", - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "schannel" version = "0.1.27" @@ -6908,15 +5725,9 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.12.3", + "parking_lot", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -6945,30 +5756,16 @@ dependencies = [ "untrusted 0.9.0", ] -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.9", + "base16ct", + "der", "generic-array", - "pkcs8 0.10.2", + "pkcs8", "subtle", "zeroize", ] @@ -7023,16 +5820,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "serde", - "url", -] - -[[package]] -name = "sensitive_url" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "serde", "url", @@ -7047,16 +5835,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde_array_query" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89c6e82b1005b33d5b2bbc47096800e5ad6b67ef5636f9c13ad29a6935734a7" -dependencies = [ - "serde", - "serde_urlencoded", -] - [[package]] name = "serde_derive" version = "1.0.216" @@ -7161,18 +5939,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - [[package]] name = "sha3" version = "0.10.8" @@ -7217,16 +5983,6 @@ dependencies = [ "libc", ] -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core", -] - [[package]] name = "signature" version = "2.2.0" @@ -7246,60 +6002,22 @@ dependencies = [ "ssv_types", "tokio", "tracing", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror 1.0.69", - "time", + "types", ] [[package]] name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "slasher" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "bincode", - "byteorder", - "derivative", - "ethereum_ssz", - "ethereum_ssz_derive", - "filesystem", - "flate2", - "lru", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "rand", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "slog", - "ssz_types", - "strum", - "tree_hash", - "tree_hash_derive", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "autocfg", ] [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -7310,7 +6028,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "types", ] [[package]] @@ -7418,11 +6136,11 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "metrics", + "parking_lot", + "types", ] [[package]] @@ -7457,16 +6175,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.8" @@ -7489,16 +6197,6 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.3" @@ -7506,7 +6204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.9", + "der", ] [[package]] @@ -7516,7 +6214,7 @@ dependencies = [ "base64 0.22.1", "derive_more 1.0.0", "openssl", - "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "types", ] [[package]] @@ -7546,27 +6244,27 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "state_processing" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "arbitrary", - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "bls", "derivative", "ethereum_hashing", "ethereum_ssz", "ethereum_ssz_derive", - "int_to_bytes 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "int_to_bytes", "integer-sqrt", "itertools 0.10.5", - "merkle_proof 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "merkle_proof", + "metrics", "rand", "rayon", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "safe_arith", "smallvec", "ssz_types", - "test_random_derive 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "test_random_derive", "tree_hash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "types", ] [[package]] @@ -7578,24 +6276,30 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ + "bls", "db-key", - "directory 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "directory", "ethereum_ssz", "ethereum_ssz_derive", "itertools 0.10.5", "leveldb", + "logging", "lru", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "metrics", + "parking_lot", + "safe_arith", "serde", "slog", "sloggers", + "smallvec", "state_processing", "strum", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "superstruct", + "types", + "xdelta3", + "zstd 0.13.2", ] [[package]] @@ -7655,21 +6359,11 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "ethereum_hashing", - "fixed_bytes 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", -] - -[[package]] -name = "swap_or_not_shuffle" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "ethereum_hashing", - "fixed_bytes 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "fixed_bytes", ] [[package]] @@ -7780,26 +6474,12 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "async-channel", - "futures", - "logging 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "slog", - "sloggers", - "tokio", -] - -[[package]] -name = "task_executor" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "async-channel", "futures", - "logging 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "metrics 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "logging", + "metrics", "slog", "sloggers", "tokio", @@ -7843,16 +6523,7 @@ dependencies = [ [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "test_random_derive" -version = "0.2.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "quote", "syn 1.0.109", @@ -7948,25 +6619,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny-bip39" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" -dependencies = [ - "anyhow", - "hmac 0.12.1", - "once_cell", - "pbkdf2 0.11.0", - "rand", - "rustc-hash 1.1.0", - "sha2 0.10.8", - "thiserror 1.0.69", - "unicode-normalization", - "wasm-bindgen", - "zeroize", -] - [[package]] name = "tiny-keccak" version = "2.0.2" @@ -8013,7 +6665,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.8", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -8059,29 +6711,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" -dependencies = [ - "rustls 0.22.4", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - [[package]] name = "tokio-util" version = "0.7.13" @@ -8103,17 +6732,6 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" @@ -8122,7 +6740,7 @@ checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "toml_datetime", - "winnow 0.6.20", + "winnow", ] [[package]] @@ -8283,16 +6901,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "triehash" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1631b201eb031b563d2e85ca18ec8092508e262a3196ce9bd10a67ec87b9f5c" -dependencies = [ - "hash-db", - "rlp", -] - [[package]] name = "triomphe" version = "0.1.14" @@ -8318,87 +6926,38 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "arbitrary", - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "compare_fields 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "compare_fields_derive 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "derivative", - "eth2_interop_keypairs 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "ethereum_hashing", - "ethereum_serde_utils", - "ethereum_ssz", - "ethereum_ssz_derive", - "fixed_bytes 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "hex", - "int_to_bytes 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "itertools 0.10.5", - "kzg 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "log", - "maplit", - "merkle_proof 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "metastruct", - "milhouse", - "parking_lot 0.12.3", - "rand", - "rand_xorshift", - "rayon", - "regex", - "rpds", - "rusqlite", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "serde_json", - "serde_yaml", - "slog", - "smallvec", - "ssz_types", - "superstruct", - "swap_or_not_shuffle 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tempfile", - "test_random_derive 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "tree_hash", - "tree_hash_derive", -] - -[[package]] -name = "types" -version = "0.2.1" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", - "bls 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "compare_fields 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "compare_fields_derive 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "bls", + "compare_fields", + "compare_fields_derive", "derivative", - "eth2_interop_keypairs 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "eth2_interop_keypairs", "ethereum_hashing", "ethereum_serde_utils", "ethereum_ssz", "ethereum_ssz_derive", - "fixed_bytes 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "fixed_bytes", "hex", - "int_to_bytes 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "int_to_bytes", "itertools 0.10.5", - "kzg 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "kzg", "log", "maplit", - "merkle_proof 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "merkle_proof", "metastruct", "milhouse", - "parking_lot 0.12.3", + "parking_lot", "rand", "rand_xorshift", "rayon", "regex", "rpds", "rusqlite", - "safe_arith 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "safe_arith", "serde", "serde_json", "serde_yaml", @@ -8406,9 +6965,9 @@ dependencies = [ "smallvec", "ssz_types", "superstruct", - "swap_or_not_shuffle 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "swap_or_not_shuffle", "tempfile", - "test_random_derive 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", + "test_random_derive", "tree_hash", "tree_hash_derive", ] @@ -8455,12 +7014,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" -[[package]] -name = "unicase" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" - [[package]] name = "unicode-ident" version = "1.0.14" @@ -8536,19 +7089,10 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "lru_cache 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "parking_lot 0.12.3", -] - -[[package]] -name = "unused_port" -version = "0.1.0" -source = "git+https://github.com/sigp/lighthouse?branch=unstable#c5a48a9dffc82e5e18d24ca7f2ab3671c9ad8469" -dependencies = [ - "lru_cache 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", - "parking_lot 0.12.3", + "lru_cache", + "parking_lot", ] [[package]] @@ -8591,29 +7135,43 @@ dependencies = [ ] [[package]] -name = "validator_dir" +name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "bls 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "deposit_contract", - "derivative", - "directory 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "eth2_keystore", - "filesystem", - "hex", - "lockfile", - "rand", + "metrics", +] + +[[package]] +name = "validator_services" +version = "0.1.0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +dependencies = [ + "beacon_node_fallback", + "bls", + "eth2", + "futures", + "graffiti_file", + "logging", + "parking_lot", + "safe_arith", + "slot_clock", + "task_executor", + "tokio", + "tracing", "tree_hash", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "types", + "validator_metrics", + "validator_store", ] [[package]] -name = "validator_metrics" +name = "validator_store" version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" dependencies = [ - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", + "slashing_protection", + "types", ] [[package]] @@ -8673,55 +7231,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "warp" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "headers", - "http 0.2.12", - "hyper 0.14.31", - "log", - "mime", - "mime_guess", - "percent-encoding", - "pin-project", - "rustls-pemfile 2.2.0", - "scoped-tls", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls 0.25.0", - "tokio-util", - "tower-service", - "tracing", -] - -[[package]] -name = "warp_utils" -version = "0.1.0" -source = "git+https://github.com/agemanning/lighthouse?branch=modularize-vc#75a58586623f84f0fd4b0a5c1de43edfc8010a78" -dependencies = [ - "beacon_chain", - "bytes", - "eth2", - "headers", - "metrics 0.2.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "safe_arith 0.1.0 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "serde", - "serde_array_query", - "serde_json", - "state_processing", - "tokio", - "types 0.2.1 (git+https://github.com/agemanning/lighthouse?branch=modularize-vc)", - "warp", -] - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -8834,6 +7343,18 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.42", +] + [[package]] name = "widestring" version = "0.4.3" @@ -9132,15 +7653,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.20" @@ -9172,12 +7684,6 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - [[package]] name = "wyz" version = "0.5.1" @@ -9216,6 +7722,20 @@ dependencies = [ "time", ] +[[package]] +name = "xdelta3" +version = "0.1.5" +source = "git+http://github.com/sigp/xdelta3-rs?rev=50d63cdf1878e5cf3538e9aae5eed34a22c64e4a#50d63cdf1878e5cf3538e9aae5eed34a22c64e4a" +dependencies = [ + "bindgen", + "cc", + "futures-io", + "futures-util", + "libc", + "log", + "rand", +] + [[package]] name = "xml-rs" version = "0.8.24" @@ -9240,7 +7760,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "rand", "static_assertions", @@ -9255,7 +7775,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.3", + "parking_lot", "pin-project", "rand", "static_assertions", @@ -9343,6 +7863,7 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ + "serde", "zeroize_derive", ] @@ -9396,7 +7917,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd", + "zstd 0.11.2+zstd.1.5.2", ] [[package]] @@ -9405,7 +7926,16 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe", + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe 7.2.1", ] [[package]] @@ -9418,6 +7948,15 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + [[package]] name = "zstd-sys" version = "2.0.13+zstd.1.5.6" diff --git a/Cargo.toml b/Cargo.toml index e84cf0a90..15ebc11f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "anchor/processor", "anchor/qbft", "anchor/signature_collector", + "anchor/validator_store", ] resolver = "2" @@ -25,16 +26,22 @@ http_metrics = { path = "anchor/http_metrics" } network = { path = "anchor/network" } version = { path = "anchor/common/version" } processor = { path = "anchor/processor" } +anchor_validator_store = { path = "anchor/validator_store" } ssv_types = { path = "anchor/common/ssv_types" } signature_collector = { path = "anchor/signature_collector" } -lighthouse_network = { git = "https://github.com/sigp/lighthouse", branch = "unstable" } -task_executor = { git = "https://github.com/sigp/lighthouse", branch = "unstable", default-features = false, features = [ "tracing", ] } -metrics = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } -validator_metrics = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } -sensitive_url = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } -slot_clock = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } -unused_port = { git = "https://github.com/sigp/lighthouse", branch = "unstable" } -types = { git = "https://github.com/sigp/lighthouse", branch = "unstable" } +lighthouse_network = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +task_executor = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store", default-features = false, features = [ "tracing", ] } +metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +sensitive_url = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +slot_clock = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +unused_port = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +types = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_services = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +eth2_config = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +eth2 = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_store = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +beacon_node_fallback = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } derive_more = { version = "1.0.0", features = ["full"] } async-channel = "1.9" axum = "0.7.7" diff --git a/anchor/Cargo.toml b/anchor/Cargo.toml index 7cbea8899..4189887ee 100644 --- a/anchor/Cargo.toml +++ b/anchor/Cargo.toml @@ -17,6 +17,7 @@ task_executor = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } +types = { workspace = true } [dev-dependencies] regex = "1.10.6" diff --git a/anchor/client/Cargo.toml b/anchor/client/Cargo.toml index dfb3c40d0..2e35697be 100644 --- a/anchor/client/Cargo.toml +++ b/anchor/client/Cargo.toml @@ -9,8 +9,12 @@ name = "client" path = "src/lib.rs" [dependencies] +anchor_validator_store = { workspace = true } +beacon_node_fallback = { workspace = true } clap = { workspace = true } dirs = { workspace = true } +eth2 = { workspace = true } +eth2_config = { workspace = true } ethereum_hashing = "0.7.0" fdlimit = "0.3" http_api = { workspace = true } @@ -21,9 +25,13 @@ parking_lot = { workspace = true } processor = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } +slot_clock = { workspace = true } strum = { workspace = true } task_executor = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } +types = { workspace = true } unused_port = { workspace = true } +validator_metrics = { workspace = true } +validator_services = { workspace = true } version = { workspace = true } diff --git a/anchor/client/src/config.rs b/anchor/client/src/config.rs index 9cb8e1ead..2fd8666c5 100644 --- a/anchor/client/src/config.rs +++ b/anchor/client/src/config.rs @@ -30,10 +30,14 @@ pub struct Config { /// /// Should be similar to `["http://localhost:8080"]` pub beacon_nodes: Vec, + /// An optional beacon node used for block proposals only. + pub proposer_nodes: Vec, /// The http endpoints of the execution node APIs. pub execution_nodes: Vec, /// beacon node is not synced at startup. pub allow_unsynced_beacon_node: bool, + /// If true, use longer timeouts for requests made to the beacon node. + pub use_long_timeouts: bool, /// Configuration for the HTTP REST API. pub http_api: http_api::Config, /// Configuration for the network stack. @@ -69,8 +73,10 @@ impl Default for Config { data_dir, secrets_dir, beacon_nodes, + proposer_nodes: vec![], execution_nodes, allow_unsynced_beacon_node: false, + use_long_timeouts: false, http_api: <_>::default(), http_metrics: <_>::default(), network: <_>::default(), diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index c4b67402b..5d687af21 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -3,21 +3,62 @@ mod cli; pub mod config; +use anchor_validator_store::AnchorValidatorStore; +use beacon_node_fallback::{ + start_fallback_updater_service, ApiTopic, BeaconNodeFallback, CandidateBeaconNode, +}; pub use cli::Anchor; use config::Config; +use eth2::reqwest::{Certificate, ClientBuilder}; +use eth2::{BeaconNodeHttpClient, Timeouts}; +use eth2_config::Eth2Config; use network::Network; use parking_lot::RwLock; +use sensitive_url::SensitiveUrl; +use slot_clock::{SlotClock, SystemTimeSlotClock}; +use std::fs::File; +use std::io::Read; use std::net::SocketAddr; +use std::path::Path; use std::sync::Arc; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; use task_executor::TaskExecutor; use tokio::net::TcpListener; -use tracing::{debug, error, info}; +use tokio::sync::mpsc; +use tokio::time::sleep; +use tracing::{debug, error, info, warn}; +use types::{EthSpec, Hash256}; +use validator_metrics::set_gauge; +use validator_services::attestation_service::AttestationServiceBuilder; +use validator_services::block_service::BlockServiceBuilder; +use validator_services::duties_service; +use validator_services::duties_service::DutiesServiceBuilder; +use validator_services::preparation_service::PreparationServiceBuilder; +use validator_services::sync_committee_service::SyncCommitteeService; + +/// The time between polls when waiting for genesis. +const WAITING_FOR_GENESIS_POLL_TIME: Duration = Duration::from_secs(12); + +/// Specific timeout constants for HTTP requests involved in different validator duties. +/// This can help ensure that proper endpoint fallback occurs. +const HTTP_ATTESTATION_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_ATTESTER_DUTIES_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_ATTESTATION_SUBSCRIPTIONS_TIMEOUT_QUOTIENT: u32 = 24; +const HTTP_LIVENESS_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_PROPOSAL_TIMEOUT_QUOTIENT: u32 = 2; +const HTTP_PROPOSER_DUTIES_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_SYNC_COMMITTEE_CONTRIBUTION_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_SYNC_DUTIES_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_GET_BEACON_BLOCK_SSZ_TIMEOUT_QUOTIENT: u32 = 4; +const HTTP_GET_DEBUG_BEACON_STATE_QUOTIENT: u32 = 4; +const HTTP_GET_DEPOSIT_SNAPSHOT_QUOTIENT: u32 = 4; +const HTTP_GET_VALIDATOR_BLOCK_TIMEOUT_QUOTIENT: u32 = 4; pub struct Client {} impl Client { /// Runs the Anchor Client - pub async fn run(executor: TaskExecutor, config: Config) -> Result<(), String> { + pub async fn run(executor: TaskExecutor, config: Config) -> Result<(), String> { // Attempt to raise soft fd limit. The behavior is OS specific: // `linux` - raise soft fd limit to hard // `macos` - raise soft fd limit to `min(kernel limit, hard fd limit)` @@ -42,11 +83,13 @@ impl Client { "Starting the Anchor client" ); + let spec = Eth2Config::mainnet().spec; + // Start the processor - let _processor_senders = processor::spawn(config.processor, executor.clone()); + let processor_senders = processor::spawn(config.processor, executor.clone()); // Optionally start the metrics server. - let _http_metrics_shared_state = if config.http_metrics.enabled { + let http_metrics_shared_state = if config.http_metrics.enabled { let shared_state = Arc::new(RwLock::new(http_metrics::Shared { genesis_time: None })); let exit = executor.exit(); @@ -77,6 +120,417 @@ impl Client { // Spawn the network listening task executor.spawn(network.run(), "network"); + let last_beacon_node_index = config + .beacon_nodes + .len() + .checked_sub(1) + .ok_or_else(|| "No beacon nodes defined.".to_string())?; + + let beacon_node_setup = |x: (usize, &SensitiveUrl)| { + let i = x.0; + let url = x.1; + let slot_duration = Duration::from_secs(spec.seconds_per_slot); + + let mut beacon_node_http_client_builder = ClientBuilder::new(); + + // Add new custom root certificates if specified. + if let Some(certificates) = &config.beacon_nodes_tls_certs { + for cert in certificates { + beacon_node_http_client_builder = beacon_node_http_client_builder + .add_root_certificate(load_pem_certificate(cert)?); + } + } + + let beacon_node_http_client = beacon_node_http_client_builder + // Set default timeout to be the full slot duration. + .timeout(slot_duration) + .build() + .map_err(|e| format!("Unable to build HTTP client: {:?}", e))?; + + // Use quicker timeouts if a fallback beacon node exists. + let timeouts = if i < last_beacon_node_index && !config.use_long_timeouts { + info!("Fallback endpoints are available, using optimized timeouts."); + Timeouts { + attestation: slot_duration / HTTP_ATTESTATION_TIMEOUT_QUOTIENT, + attester_duties: slot_duration / HTTP_ATTESTER_DUTIES_TIMEOUT_QUOTIENT, + attestation_subscriptions: slot_duration + / HTTP_ATTESTATION_SUBSCRIPTIONS_TIMEOUT_QUOTIENT, + liveness: slot_duration / HTTP_LIVENESS_TIMEOUT_QUOTIENT, + proposal: slot_duration / HTTP_PROPOSAL_TIMEOUT_QUOTIENT, + proposer_duties: slot_duration / HTTP_PROPOSER_DUTIES_TIMEOUT_QUOTIENT, + sync_committee_contribution: slot_duration + / HTTP_SYNC_COMMITTEE_CONTRIBUTION_TIMEOUT_QUOTIENT, + sync_duties: slot_duration / HTTP_SYNC_DUTIES_TIMEOUT_QUOTIENT, + get_beacon_blocks_ssz: slot_duration + / HTTP_GET_BEACON_BLOCK_SSZ_TIMEOUT_QUOTIENT, + get_debug_beacon_states: slot_duration / HTTP_GET_DEBUG_BEACON_STATE_QUOTIENT, + get_deposit_snapshot: slot_duration / HTTP_GET_DEPOSIT_SNAPSHOT_QUOTIENT, + get_validator_block: slot_duration / HTTP_GET_VALIDATOR_BLOCK_TIMEOUT_QUOTIENT, + } + } else { + Timeouts::set_all(slot_duration) + }; + + Ok(BeaconNodeHttpClient::from_components( + url.clone(), + beacon_node_http_client, + timeouts, + )) + }; + + let beacon_nodes: Vec = config + .beacon_nodes + .iter() + .enumerate() + .map(beacon_node_setup) + .collect::, String>>()?; + + let proposer_nodes: Vec = config + .proposer_nodes + .iter() + .enumerate() + .map(beacon_node_setup) + .collect::, String>>()?; + + let num_nodes = beacon_nodes.len(); + // User order of `beacon_nodes` is preserved, so `index` corresponds to the position of + // the node in `--beacon_nodes`. + let candidates = beacon_nodes + .into_iter() + .enumerate() + .map(|(index, node)| CandidateBeaconNode::new(node, index)) + .collect(); + + // User order of `proposer_nodes` is preserved, so `index` corresponds to the position of + // the node in `--proposer_nodes`. + let proposer_candidates = proposer_nodes + .into_iter() + .enumerate() + .map(|(index, node)| CandidateBeaconNode::new(node, index)) + .collect(); + + // Set the count for beacon node fallbacks excluding the primary beacon node. + set_gauge( + &validator_metrics::ETH2_FALLBACK_CONFIGURED, + num_nodes.saturating_sub(1) as i64, + ); + // Set the total beacon node count. + set_gauge( + &validator_metrics::TOTAL_BEACON_NODES_COUNT, + num_nodes as i64, + ); + + // Initialize the number of connected, synced beacon nodes to 0. + set_gauge(&validator_metrics::ETH2_FALLBACK_CONNECTED, 0); + set_gauge(&validator_metrics::SYNCED_BEACON_NODES_COUNT, 0); + // Initialize the number of connected, avaliable beacon nodes to 0. + set_gauge(&validator_metrics::AVAILABLE_BEACON_NODES_COUNT, 0); + + let mut beacon_nodes: BeaconNodeFallback<_, E> = BeaconNodeFallback::new( + candidates, + beacon_node_fallback::Config::default(), // TODO make configurable + vec![ApiTopic::Subscriptions], // TODO make configurable + spec.clone(), + ); + + let mut proposer_nodes: BeaconNodeFallback<_, E> = BeaconNodeFallback::new( + proposer_candidates, + beacon_node_fallback::Config::default(), // TODO make configurable + vec![ApiTopic::Subscriptions], // TODO make configurable + spec.clone(), + ); + + // Perform some potentially long-running initialization tasks. + let (genesis_time, _genesis_validators_root) = tokio::select! { + tuple = init_from_beacon_node(&beacon_nodes, &proposer_nodes) => tuple?, + () = executor.exit() => return Err("Shutting down".to_string()) + }; + + let slot_clock = SystemTimeSlotClock::new( + spec.genesis_slot, + Duration::from_secs(genesis_time), + Duration::from_secs(spec.seconds_per_slot), + ); + + beacon_nodes.set_slot_clock(slot_clock.clone()); + proposer_nodes.set_slot_clock(slot_clock.clone()); + + let beacon_nodes = Arc::new(beacon_nodes); + start_fallback_updater_service(executor.clone(), beacon_nodes.clone())?; + + let proposer_nodes = Arc::new(proposer_nodes); + start_fallback_updater_service(executor.clone(), proposer_nodes.clone())?; + + let validator_store = Arc::new(AnchorValidatorStore::new(processor_senders)); + + let duties_service = Arc::new( + DutiesServiceBuilder::new() + .slot_clock(slot_clock.clone()) + .beacon_nodes(beacon_nodes.clone()) + .validator_store(validator_store.clone()) + .spec(spec.clone()) + .executor(executor.clone()) + //.enable_high_validator_count_metrics(config.enable_high_validator_count_metrics) + .distributed(true) + .build()?, + ); + + // Update the metrics server. + if let Some(ctx) = &http_metrics_shared_state { + ctx.write().genesis_time = Some(genesis_time); + //ctx.write().validator_store = Some(validator_store.clone()); + //ctx.write().duties_service = Some(duties_service.clone()); + } + + let block_service_builder = BlockServiceBuilder::new() + .slot_clock(slot_clock.clone()) + .validator_store(validator_store.clone()) + .beacon_nodes(beacon_nodes.clone()) + .executor(executor.clone()); + //.graffiti(config.graffiti) + //.graffiti_file(config.graffiti_file.clone()); + + // If we have proposer nodes, add them to the block service builder. + //if proposer_nodes_num > 0 { + // block_service_builder = block_service_builder.proposer_nodes(proposer_nodes.clone()); + //} + + let block_service = block_service_builder.build()?; + + let attestation_service = AttestationServiceBuilder::new() + .duties_service(duties_service.clone()) + .slot_clock(slot_clock.clone()) + .validator_store(validator_store.clone()) + .beacon_nodes(beacon_nodes.clone()) + .executor(executor.clone()) + .chain_spec(spec.clone()) + .build()?; + + let preparation_service = PreparationServiceBuilder::new() + .slot_clock(slot_clock.clone()) + .validator_store(validator_store.clone()) + .beacon_nodes(beacon_nodes.clone()) + .executor(executor.clone()) + //.builder_registration_timestamp_override(config.builder_registration_timestamp_override) + .validator_registration_batch_size(500) + .build()?; + + let sync_committee_service = SyncCommitteeService::new( + duties_service.clone(), + validator_store.clone(), + slot_clock.clone(), + beacon_nodes.clone(), + executor.clone(), + ); + + // We use `SLOTS_PER_EPOCH` as the capacity of the block notification channel, because + // we don't expect notifications to be delayed by more than a single slot, let alone a + // whole epoch! + let channel_capacity = E::slots_per_epoch() as usize; + let (block_service_tx, block_service_rx) = mpsc::channel(channel_capacity); + + // Wait until genesis has occurred. + wait_for_genesis(&beacon_nodes, genesis_time).await?; + + duties_service::start_update_service(duties_service.clone(), block_service_tx); + + block_service + .start_update_service(block_service_rx) + .map_err(|e| format!("Unable to start block service: {}", e))?; + + attestation_service + .start_update_service(&spec) + .map_err(|e| format!("Unable to start attestation service: {}", e))?; + + sync_committee_service + .start_update_service(&spec) + .map_err(|e| format!("Unable to start sync committee service: {}", e))?; + + preparation_service + .start_update_service(&spec) + .map_err(|e| format!("Unable to start preparation service: {}", e))?; + Ok(()) } } + +async fn init_from_beacon_node( + beacon_nodes: &BeaconNodeFallback, + proposer_nodes: &BeaconNodeFallback, +) -> Result<(u64, Hash256), String> { + const RETRY_DELAY: Duration = Duration::from_secs(2); + + loop { + beacon_nodes.update_all_candidates().await; + proposer_nodes.update_all_candidates().await; + + let num_available = beacon_nodes.num_available().await; + let num_total = beacon_nodes.num_total().await; + + let proposer_available = proposer_nodes.num_available().await; + let proposer_total = proposer_nodes.num_total().await; + + if proposer_total > 0 && proposer_available == 0 { + warn!( + "retry in" = format!("{} seconds", RETRY_DELAY.as_secs()), + "total_proposers" = proposer_total, + "available_proposers" = proposer_available, + "total_beacon_nodes" = num_total, + "available_beacon_nodes" = num_available, + "Unable to connect to a proposer node" + ); + } + + if num_available > 0 && proposer_available == 0 { + info!( + "total" = num_total, + "available" = num_available, + "Initialized beacon node connections" + ); + break; + } else if num_available > 0 { + info!( + "total" = num_total, + "available" = num_available, + "proposers_available" = proposer_available, + "proposers_total" = proposer_total, + "Initialized beacon node connections" + ); + break; + } else { + warn!( + "retry in" = format!("{} seconds", RETRY_DELAY.as_secs()), + "total" = num_total, + "available" = num_available, + "Unable to connect to a beacon node" + ); + sleep(RETRY_DELAY).await; + } + } + + let genesis = loop { + match beacon_nodes + .first_success(|node| async move { node.get_beacon_genesis().await }) + .await + { + Ok(genesis) => break genesis.data, + Err(errors) => { + // Search for a 404 error which indicates that genesis has not yet + // occurred. + if errors + .0 + .iter() + .filter_map(|(_, e)| e.request_failure()) + .any(|e| e.status() == Some(eth2::StatusCode::NOT_FOUND)) + { + info!("Waiting for genesis",); + } else { + error!( + "error" = ?errors.0, + "Errors polling beacon node", + ); + } + } + } + + sleep(RETRY_DELAY).await; + }; + + Ok((genesis.genesis_time, genesis.genesis_validators_root)) +} + +async fn wait_for_genesis( + beacon_nodes: &BeaconNodeFallback, + genesis_time: u64, +) -> Result<(), String> { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|e| format!("Unable to read system time: {:?}", e))?; + let genesis_time = Duration::from_secs(genesis_time); + + // If the time now is less than (prior to) genesis, then delay until the + // genesis instant. + // + // If the validator client starts before genesis, it will get errors from + // the slot clock. + if now < genesis_time { + info!( + "seconds_to_wait" = (genesis_time - now).as_secs(), + "Starting node prior to genesis", + ); + + // Start polling the node for pre-genesis information, cancelling the polling as soon as the + // timer runs out. + tokio::select! { + result = poll_whilst_waiting_for_genesis(beacon_nodes, genesis_time) => result?, + () = sleep(genesis_time - now) => () + }; + + info!( + "ms_since_genesis" = (genesis_time - now).as_millis(), + "Genesis has occurred", + ); + } else { + info!( + "seconds_ago" = (now - genesis_time).as_secs(), + "Genesis has already occurred", + ); + } + + Ok(()) +} + +/// Request the version from the node, looping back and trying again on failure. Exit once the node +/// has been contacted. +async fn poll_whilst_waiting_for_genesis( + beacon_nodes: &BeaconNodeFallback, + genesis_time: Duration, +) -> Result<(), String> { + loop { + match beacon_nodes + .first_success(|beacon_node| async move { beacon_node.get_lighthouse_staking().await }) + .await + { + Ok(is_staking) => { + let now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .map_err(|e| format!("Unable to read system time: {:?}", e))?; + + if !is_staking { + error!( + "msg" = "this will caused missed duties", + "info" = "see the --staking CLI flag on the beacon node", + "Staking is disabled for beacon node" + ); + } + + if now < genesis_time { + info!( + "bn_staking_enabled" = is_staking, + "seconds_to_wait" = (genesis_time - now).as_secs(), + "Waiting for genesis" + ); + } else { + break Ok(()); + } + } + Err(e) => { + error!( + "error" = ?e.0, + "Error polling beacon node", + ); + } + } + + sleep(WAITING_FOR_GENESIS_POLL_TIME).await; + } +} + +pub fn load_pem_certificate>(pem_path: P) -> Result { + let mut buf = Vec::new(); + File::open(&pem_path) + .map_err(|e| format!("Unable to open certificate path: {}", e))? + .read_to_end(&mut buf) + .map_err(|e| format!("Unable to read certificate file: {}", e))?; + Certificate::from_pem(&buf).map_err(|e| format!("Unable to parse certificate: {}", e)) +} diff --git a/anchor/http_metrics/Cargo.toml b/anchor/http_metrics/Cargo.toml index fbf931ce9..bf5f7fa33 100644 --- a/anchor/http_metrics/Cargo.toml +++ b/anchor/http_metrics/Cargo.toml @@ -13,4 +13,4 @@ tower-http = { workspace = true } tracing = { workspace = true } validator_metrics = { workspace = true } # Group dependencies -warp_utils = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } +#warp_utils = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } diff --git a/anchor/http_metrics/src/lib.rs b/anchor/http_metrics/src/lib.rs index 2a2cde847..2a857e12b 100644 --- a/anchor/http_metrics/src/lib.rs +++ b/anchor/http_metrics/src/lib.rs @@ -106,7 +106,7 @@ async fn metrics_handler(State(state): State>>) -> Response(anchor_executor, config).await { error!(reason = e, "Failed to start Anchor"); // Ignore the error since it always occurs during normal operation when // shutting down. diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml new file mode 100644 index 000000000..ee14ed878 --- /dev/null +++ b/anchor/validator_store/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "anchor_validator_store" +version = "0.1.0" +edition = { workspace = true } +authors = ["Sigma Prime "] +rust-version = "1.81.0" + +[dependencies] +dashmap = "6.1.0" +processor = { workspace = true } +ssv_types = { workspace = true } +tracing = { workspace = true } +types = { workspace = true } +validator_store = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs new file mode 100644 index 000000000..9cd70b27a --- /dev/null +++ b/anchor/validator_store/src/lib.rs @@ -0,0 +1,215 @@ +use dashmap::DashMap; +use std::marker::PhantomData; +use tracing::{error, warn}; +use types::attestation::Attestation; +use types::beacon_block::BeaconBlock; +use types::graffiti::Graffiti; +use types::payload::AbstractExecPayload; +use types::selection_proof::SelectionProof; +use types::signed_aggregate_and_proof::SignedAggregateAndProof; +use types::signed_beacon_block::SignedBeaconBlock; +use types::signed_contribution_and_proof::SignedContributionAndProof; +use types::signed_voluntary_exit::SignedVoluntaryExit; +use types::slot_epoch::{Epoch, Slot}; +use types::sync_committee_contribution::SyncCommitteeContribution; +use types::sync_committee_message::SyncCommitteeMessage; +use types::sync_selection_proof::SyncSelectionProof; +use types::sync_subnet_id::SyncSubnetId; +use types::validator_registration_data::{ + SignedValidatorRegistrationData, ValidatorRegistrationData, +}; +use types::voluntary_exit::VoluntaryExit; +use types::{Address, EthSpec, PublicKeyBytes, Signature}; +use validator_store::{ + DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, ValidatorStore, +}; + +pub struct AnchorValidatorStore { + validators: DashMap, + _processor: processor::Senders, + _phantom: PhantomData, +} + +impl AnchorValidatorStore { + pub fn new(processor: processor::Senders) -> AnchorValidatorStore { + Self { + validators: DashMap::new(), + _processor: processor, + _phantom: PhantomData, + } + } +} + +#[derive(Debug)] +pub enum SpecificError { + ExitsUnsupported, + SigningTimeout, +} + +pub type Error = ValidatorStoreError; + +impl ValidatorStore for AnchorValidatorStore { + type Error = SpecificError; + + fn validator_index(&self, pubkey: &PublicKeyBytes) -> Option { + self.validators + .get(pubkey) + .map(|v| v.validator_metadata.validator_index.0 as u64) + } + + fn voting_pubkeys(&self, _filter_func: F) -> I + where + I: FromIterator, + F: Fn(DoppelgangerStatus) -> Option, + { + // we don't care about doppelgangers + self.validators.iter().map(|v| *v.key()).collect() + } + + fn doppelganger_protection_allows_signing(&self, _validator_pubkey: PublicKeyBytes) -> bool { + true + } + + fn num_voting_validators(&self) -> usize { + self.validators.len() + } + + fn graffiti(&self, validator_pubkey: &PublicKeyBytes) -> Option { + self.validators + .get(validator_pubkey) + .map(|v| v.validator_metadata.graffiti) + } + + fn get_fee_recipient(&self, validator_pubkey: &PublicKeyBytes) -> Option
{ + self.validators + .get(validator_pubkey) + .map(|v| v.validator_metadata.fee_recipient) + } + + fn determine_builder_boost_factor(&self, _validator_pubkey: &PublicKeyBytes) -> Option { + Some(1) + } + + async fn randao_reveal( + &self, + _validator_pubkey: PublicKeyBytes, + _signing_epoch: Epoch, + ) -> Result { + todo!() + } + + fn set_validator_index(&self, validator_pubkey: &PublicKeyBytes, index: u64) { + // we actually have the index already. we use the opportunity to do a sanity check + match self.validators.get(validator_pubkey) { + None => warn!( + validator = validator_pubkey.as_hex_string(), + "Trying to set index for unknown validator" + ), + Some(v) => { + if v.validator_metadata.validator_index.0 as u64 != index { + error!( + validator = validator_pubkey.as_hex_string(), + expected = v.validator_metadata.validator_index.0, + actual = index, + "Mismatched validator index", + ) + } + } + } + } + + async fn sign_block>( + &self, + _validator_pubkey: PublicKeyBytes, + _block: BeaconBlock, + _current_slot: Slot, + ) -> Result, Error> { + todo!() + } + + async fn sign_attestation( + &self, + _validator_pubkey: PublicKeyBytes, + _validator_committee_position: usize, + _attestation: &mut Attestation, + _current_epoch: Epoch, + ) -> Result<(), Error> { + todo!() + } + + async fn sign_voluntary_exit( + &self, + _validator_pubkey: PublicKeyBytes, + _voluntary_exit: VoluntaryExit, + ) -> Result { + // there should be no situation ever where we want to sign an exit + Err(Error::SpecificError(SpecificError::ExitsUnsupported)) + } + + async fn sign_validator_registration_data( + &self, + _validator_registration_data: ValidatorRegistrationData, + ) -> Result { + todo!() + } + + async fn produce_signed_aggregate_and_proof( + &self, + _validator_pubkey: PublicKeyBytes, + _aggregator_index: u64, + _aggregate: Attestation, + _selection_proof: SelectionProof, + ) -> Result, Error> { + todo!() + } + + async fn produce_selection_proof( + &self, + _validator_pubkey: PublicKeyBytes, + _slot: Slot, + ) -> Result { + todo!() + } + + async fn produce_sync_selection_proof( + &self, + _validator_pubkey: &PublicKeyBytes, + _slot: Slot, + _subnet_id: SyncSubnetId, + ) -> Result { + todo!() + } + + async fn produce_sync_committee_signature( + &self, + _slot: Slot, + _beacon_block_root: types::Hash256, + _validator_index: u64, + _validator_pubkey: &PublicKeyBytes, + ) -> Result { + todo!() + } + + async fn produce_signed_contribution_and_proof( + &self, + _aggregator_index: u64, + _aggregator_pubkey: PublicKeyBytes, + _contribution: SyncCommitteeContribution, + _selection_proof: SyncSelectionProof, + ) -> Result, Error> { + todo!() + } + + fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { + // TODO slashing protection + } + + fn proposal_data(&self, pubkey: &PublicKeyBytes) -> Option { + self.validators.get(pubkey).map(|v| ProposalData { + validator_index: Some(v.validator_metadata.validator_index.0 as u64), + fee_recipient: Some(v.validator_metadata.fee_recipient), + gas_limit: 30_000_000, // TODO support scalooors + builder_proposals: false, // TODO support MEVooors + }) + } +} From 9bd0d6a285a44f161b08438a49c79c0d9817aa2a Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 13 Dec 2024 17:30:14 +0100 Subject: [PATCH 03/21] add hack to connect to kurtosis BN --- anchor/client/src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 5d687af21..8cdf5b492 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -83,7 +83,9 @@ impl Client { "Starting the Anchor client" ); - let spec = Eth2Config::mainnet().spec; + let mut spec = Eth2Config::mainnet().spec; + // dirty hack to be able to connect to local kurtosis devnet + Arc::get_mut(&mut spec).unwrap().genesis_fork_version = [16, 0, 0, 56]; // Start the processor let processor_senders = processor::spawn(config.processor, executor.clone()); @@ -286,7 +288,8 @@ impl Client { .slot_clock(slot_clock.clone()) .validator_store(validator_store.clone()) .beacon_nodes(beacon_nodes.clone()) - .executor(executor.clone()); + .executor(executor.clone()) + .chain_spec(spec.clone()); //.graffiti(config.graffiti) //.graffiti_file(config.graffiti_file.clone()); From 748d22d8db4ab5628910c7720755f4001e03aaa5 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Tue, 17 Dec 2024 19:43:10 +0100 Subject: [PATCH 04/21] use `signature_collector` for the randao reveal --- Cargo.lock | 133 ++++++++++++++++++------------ anchor/client/Cargo.toml | 2 + anchor/client/src/lib.rs | 16 +++- anchor/validator_store/Cargo.toml | 1 + anchor/validator_store/src/lib.rs | 108 ++++++++++++++++++------ 5 files changed, 180 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32589978c..9a546c27b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,6 +177,7 @@ version = "0.1.0" dependencies = [ "dashmap", "processor", + "signature_collector", "ssv_types", "tracing", "types", @@ -564,7 +565,7 @@ dependencies = [ "http 1.2.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.1", + "hyper 1.5.2", "hyper-util", "itoa", "matchit", @@ -684,7 +685,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.12.1", "lazy_static", "lazycell", "log", @@ -884,9 +885,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" +checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" dependencies = [ "jobserver", "libc", @@ -1053,13 +1054,15 @@ dependencies = [ "fdlimit", "http_api", "http_metrics", - "hyper 1.5.1", + "hyper 1.5.2", "network", "parking_lot", "processor", "sensitive_url", "serde", + "signature_collector", "slot_clock", + "ssv_types", "strum", "task_executor", "tokio", @@ -1243,18 +1246,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -1271,9 +1274,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" @@ -2143,6 +2146,17 @@ dependencies = [ "bytes", ] +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "fdlimit" version = "0.3.0" @@ -2355,7 +2369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" dependencies = [ "futures-io", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", ] @@ -2840,9 +2854,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.31" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", @@ -2864,9 +2878,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" dependencies = [ "bytes", "futures-channel", @@ -2889,7 +2903,7 @@ checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "rustls 0.21.12", "tokio", "tokio-rustls", @@ -2902,7 +2916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.31", + "hyper 0.14.32", "native-tls", "tokio", "tokio-native-tls", @@ -2918,7 +2932,7 @@ dependencies = [ "futures-util", "http 1.2.0", "http-body 1.0.1", - "hyper 1.5.1", + "hyper 1.5.2", "pin-project-lite", "tokio", "tower-service", @@ -3136,7 +3150,7 @@ dependencies = [ "bytes", "futures", "http 0.2.12", - "hyper 0.14.31", + "hyper 0.14.32", "log", "rand", "tokio", @@ -3266,6 +3280,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -3427,7 +3450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3749,7 +3772,7 @@ dependencies = [ "quinn", "rand", "ring 0.17.8", - "rustls 0.23.19", + "rustls 0.23.20", "socket2", "thiserror 1.0.69", "tokio", @@ -3821,7 +3844,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring 0.17.8", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-webpki 0.101.7", "thiserror 1.0.69", "x509-parser", @@ -4210,9 +4233,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ "adler2", ] @@ -4751,7 +4774,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.6", + "thiserror 2.0.8", "ucd-trie", ] @@ -5008,9 +5031,9 @@ dependencies = [ [[package]] name = "proptest-derive" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff7ff745a347b87471d859a377a9a404361e7efc2a971d73424a6d183c0fc77" +checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", @@ -5107,9 +5130,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.0", - "rustls 0.23.19", + "rustls 0.23.20", "socket2", - "thiserror 2.0.6", + "thiserror 2.0.8", "tokio", "tracing", ] @@ -5125,10 +5148,10 @@ dependencies = [ "rand", "ring 0.17.8", "rustc-hash 2.1.0", - "rustls 0.23.19", + "rustls 0.23.20", "rustls-pki-types", "slab", - "thiserror 2.0.6", + "thiserror 2.0.8", "tinyvec", "tracing", "web-time", @@ -5136,9 +5159,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" dependencies = [ "cfg_aliases", "libc", @@ -5258,9 +5281,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -5334,7 +5357,7 @@ dependencies = [ "h2", "http 0.2.12", "http-body 0.4.6", - "hyper 0.14.31", + "hyper 0.14.32", "hyper-rustls", "hyper-tls", "ipnet", @@ -5461,17 +5484,19 @@ dependencies = [ [[package]] name = "ruint" -version = "1.12.3" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +checksum = "f5ef8fb1dd8de3870cb8400d51b4c2023854bbafd5431a3ac7e7317243e22d2f" dependencies = [ "alloy-rlp", "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", "bytes", - "fastrlp", + "fastrlp 0.3.1", + "fastrlp 0.4.0", "num-bigint", + "num-integer", "num-traits", "parity-scale-codec", "primitive-types", @@ -5557,7 +5582,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver 1.0.24", ] [[package]] @@ -5610,9 +5635,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "once_cell", "ring 0.17.8", @@ -5633,9 +5658,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" dependencies = [ "web-time", ] @@ -5785,9 +5810,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" dependencies = [ "core-foundation-sys", "libc", @@ -5804,9 +5829,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "semver-parser" @@ -6540,11 +6565,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.6" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a" dependencies = [ - "thiserror-impl 2.0.6", + "thiserror-impl 2.0.8", ] [[package]] @@ -6560,9 +6585,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.6" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943" dependencies = [ "proc-macro2", "quote", diff --git a/anchor/client/Cargo.toml b/anchor/client/Cargo.toml index 2e35697be..d0da3917d 100644 --- a/anchor/client/Cargo.toml +++ b/anchor/client/Cargo.toml @@ -25,7 +25,9 @@ parking_lot = { workspace = true } processor = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } +signature_collector = { workspace = true } slot_clock = { workspace = true } +ssv_types = { workspace = true } strum = { workspace = true } task_executor = { workspace = true } tokio = { workspace = true } diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 8cdf5b492..ac65d71e9 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -15,7 +15,9 @@ use eth2_config::Eth2Config; use network::Network; use parking_lot::RwLock; use sensitive_url::SensitiveUrl; +use signature_collector::SignatureCollectorManager; use slot_clock::{SlotClock, SystemTimeSlotClock}; +use ssv_types::OperatorId; use std::fs::File; use std::io::Read; use std::net::SocketAddr; @@ -90,6 +92,10 @@ impl Client { // Start the processor let processor_senders = processor::spawn(config.processor, executor.clone()); + // Create the processor-adjacent managers + let signature_collector = + Arc::new(SignatureCollectorManager::new(processor_senders.clone())); + // Optionally start the metrics server. let http_metrics_shared_state = if config.http_metrics.enabled { let shared_state = Arc::new(RwLock::new(http_metrics::Shared { genesis_time: None })); @@ -243,7 +249,7 @@ impl Client { ); // Perform some potentially long-running initialization tasks. - let (genesis_time, _genesis_validators_root) = tokio::select! { + let (genesis_time, genesis_validators_root) = tokio::select! { tuple = init_from_beacon_node(&beacon_nodes, &proposer_nodes) => tuple?, () = executor.exit() => return Err("Shutting down".to_string()) }; @@ -263,7 +269,13 @@ impl Client { let proposer_nodes = Arc::new(proposer_nodes); start_fallback_updater_service(executor.clone(), proposer_nodes.clone())?; - let validator_store = Arc::new(AnchorValidatorStore::new(processor_senders)); + let validator_store = Arc::new(AnchorValidatorStore::new( + processor_senders, + signature_collector, + spec.clone(), + genesis_validators_root, + OperatorId(123), + )); let duties_service = Arc::new( DutiesServiceBuilder::new() diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml index ee14ed878..b9c929ddb 100644 --- a/anchor/validator_store/Cargo.toml +++ b/anchor/validator_store/Cargo.toml @@ -8,6 +8,7 @@ rust-version = "1.81.0" [dependencies] dashmap = "6.1.0" processor = { workspace = true } +signature_collector = { workspace = true } ssv_types = { workspace = true } tracing = { workspace = true } types = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 9cd70b27a..e1c4a4545 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -1,5 +1,8 @@ use dashmap::DashMap; +use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; +use ssv_types::{Cluster, OperatorId}; use std::marker::PhantomData; +use std::sync::Arc; use tracing::{error, warn}; use types::attestation::Attestation; use types::beacon_block::BeaconBlock; @@ -19,31 +22,80 @@ use types::validator_registration_data::{ SignedValidatorRegistrationData, ValidatorRegistrationData, }; use types::voluntary_exit::VoluntaryExit; -use types::{Address, EthSpec, PublicKeyBytes, Signature}; +use types::{ + Address, ChainSpec, Domain, EthSpec, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, +}; use validator_store::{ DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, ValidatorStore, }; +struct InitializedCluster { + cluster: Cluster, + decrypted_key_share: SecretKey, +} + pub struct AnchorValidatorStore { - validators: DashMap, - _processor: processor::Senders, + clusters: DashMap, + signature_collector: Arc, + spec: Arc, + genesis_validators_root: Hash256, + operator_id: OperatorId, _phantom: PhantomData, } impl AnchorValidatorStore { - pub fn new(processor: processor::Senders) -> AnchorValidatorStore { + pub fn new( + _processor: processor::Senders, + signature_collector: Arc, + spec: Arc, + genesis_validators_root: Hash256, + operator_id: OperatorId, + ) -> AnchorValidatorStore { Self { - validators: DashMap::new(), - _processor: processor, + clusters: DashMap::new(), + signature_collector, + spec, + genesis_validators_root, + operator_id, _phantom: PhantomData, } } + + async fn collect_signature( + &self, + validator_pubkey: PublicKeyBytes, + signing_root: Hash256, + ) -> Result { + let Some(cluster) = self.clusters.get(&validator_pubkey) else { + return Err(Error::UnknownPubkey(validator_pubkey)); + }; + + let collector = self.signature_collector.sign_and_collect( + SignatureRequest { + cluster_id: cluster.cluster.cluster_id, + signing_root, + threshold: cluster.cluster.cluster_members.len() as u64 - cluster.cluster.faulty, + }, + self.operator_id, + cluster.decrypted_key_share.clone(), + ); + + // free lock before invoking future + drop(cluster); + Ok((*collector.await.map_err(SpecificError::from)?).clone()) + } } #[derive(Debug)] pub enum SpecificError { ExitsUnsupported, - SigningTimeout, + SignatureCollectionFailed(CollectionError), +} + +impl From for SpecificError { + fn from(err: CollectionError) -> SpecificError { + SpecificError::SignatureCollectionFailed(err) + } } pub type Error = ValidatorStoreError; @@ -52,9 +104,9 @@ impl ValidatorStore for AnchorValidatorStore { type Error = SpecificError; fn validator_index(&self, pubkey: &PublicKeyBytes) -> Option { - self.validators + self.clusters .get(pubkey) - .map(|v| v.validator_metadata.validator_index.0 as u64) + .map(|v| v.cluster.validator_metadata.validator_index.0 as u64) } fn voting_pubkeys(&self, _filter_func: F) -> I @@ -63,27 +115,28 @@ impl ValidatorStore for AnchorValidatorStore { F: Fn(DoppelgangerStatus) -> Option, { // we don't care about doppelgangers - self.validators.iter().map(|v| *v.key()).collect() + self.clusters.iter().map(|v| *v.key()).collect() } fn doppelganger_protection_allows_signing(&self, _validator_pubkey: PublicKeyBytes) -> bool { + // we don't care about doppelgangers true } fn num_voting_validators(&self) -> usize { - self.validators.len() + self.clusters.len() } fn graffiti(&self, validator_pubkey: &PublicKeyBytes) -> Option { - self.validators + self.clusters .get(validator_pubkey) - .map(|v| v.validator_metadata.graffiti) + .map(|v| v.cluster.validator_metadata.graffiti) } fn get_fee_recipient(&self, validator_pubkey: &PublicKeyBytes) -> Option
{ - self.validators + self.clusters .get(validator_pubkey) - .map(|v| v.validator_metadata.fee_recipient) + .map(|v| v.cluster.validator_metadata.fee_recipient) } fn determine_builder_boost_factor(&self, _validator_pubkey: &PublicKeyBytes) -> Option { @@ -92,24 +145,31 @@ impl ValidatorStore for AnchorValidatorStore { async fn randao_reveal( &self, - _validator_pubkey: PublicKeyBytes, - _signing_epoch: Epoch, + validator_pubkey: PublicKeyBytes, + signing_epoch: Epoch, ) -> Result { - todo!() + let domain = self.spec.get_domain( + signing_epoch, + Domain::Randao, + &self.spec.fork_at_epoch(signing_epoch), + self.genesis_validators_root, + ); + let signing_root = signing_epoch.signing_root(domain); + self.collect_signature(validator_pubkey, signing_root).await } fn set_validator_index(&self, validator_pubkey: &PublicKeyBytes, index: u64) { // we actually have the index already. we use the opportunity to do a sanity check - match self.validators.get(validator_pubkey) { + match self.clusters.get(validator_pubkey) { None => warn!( validator = validator_pubkey.as_hex_string(), "Trying to set index for unknown validator" ), Some(v) => { - if v.validator_metadata.validator_index.0 as u64 != index { + if v.cluster.validator_metadata.validator_index.0 as u64 != index { error!( validator = validator_pubkey.as_hex_string(), - expected = v.validator_metadata.validator_index.0, + expected = v.cluster.validator_metadata.validator_index.0, actual = index, "Mismatched validator index", ) @@ -205,9 +265,9 @@ impl ValidatorStore for AnchorValidatorStore { } fn proposal_data(&self, pubkey: &PublicKeyBytes) -> Option { - self.validators.get(pubkey).map(|v| ProposalData { - validator_index: Some(v.validator_metadata.validator_index.0 as u64), - fee_recipient: Some(v.validator_metadata.fee_recipient), + self.clusters.get(pubkey).map(|v| ProposalData { + validator_index: Some(v.cluster.validator_metadata.validator_index.0 as u64), + fee_recipient: Some(v.cluster.validator_metadata.fee_recipient), gas_limit: 30_000_000, // TODO support scalooors builder_proposals: false, // TODO support MEVooors }) From 7431490144214c7fe70c2667f20e7eeb8da8e457 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Wed, 18 Dec 2024 18:49:32 +0100 Subject: [PATCH 05/21] more progress on validator store --- Cargo.lock | 1 + Cargo.toml | 1 + anchor/common/ssv_types/src/lib.rs | 2 + anchor/common/ssv_types/src/qbft_msgid.rs | 47 ++++++++++ anchor/validator_store/Cargo.toml | 1 + anchor/validator_store/src/lib.rs | 100 +++++++++++++++++----- 6 files changed, 132 insertions(+), 20 deletions(-) create mode 100644 anchor/common/ssv_types/src/qbft_msgid.rs diff --git a/Cargo.lock b/Cargo.lock index 9a546c27b..787c747a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,6 +177,7 @@ version = "0.1.0" dependencies = [ "dashmap", "processor", + "safe_arith", "signature_collector", "ssv_types", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 15ebc11f8..5032cf9d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ eth2_config = { git = "https://github.com/dknopik/lighthouse", branch = "modular eth2 = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } validator_store = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } beacon_node_fallback = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +safe_arith = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } derive_more = { version = "1.0.0", features = ["full"] } async-channel = "1.9" axum = "0.7.7" diff --git a/anchor/common/ssv_types/src/lib.rs b/anchor/common/ssv_types/src/lib.rs index 6d25f44d2..d78e28df0 100644 --- a/anchor/common/ssv_types/src/lib.rs +++ b/anchor/common/ssv_types/src/lib.rs @@ -1,7 +1,9 @@ pub use cluster::{Cluster, ClusterId, ClusterMember, ValidatorIndex, ValidatorMetadata}; pub use operator::{Operator, OperatorId}; +pub use qbft_msgid::{Domain, Executor, MessageId, Role, HOLESKY_DOMAIN, MAINNET_DOMAIN}; pub use share::Share; mod cluster; mod operator; +mod qbft_msgid; mod share; mod util; diff --git a/anchor/common/ssv_types/src/qbft_msgid.rs b/anchor/common/ssv_types/src/qbft_msgid.rs new file mode 100644 index 000000000..9210a8fb4 --- /dev/null +++ b/anchor/common/ssv_types/src/qbft_msgid.rs @@ -0,0 +1,47 @@ +// todo probably move that to its own thing +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub struct Domain([u8; 4]); +pub const MAINNET_DOMAIN: Domain = Domain([0, 0, 0, 1]); +pub const HOLESKY_DOMAIN: Domain = Domain([0, 0, 5, 2]); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub enum Role { + Committee, + Aggregator, + Proposer, + SyncCommittee, +} + +impl Role { + fn into_message_id_bytes(self) -> [u8; 4] { + match self { + Role::Committee => [0, 0, 0, 0], + Role::Aggregator => [1, 0, 0, 0], + Role::Proposer => [2, 0, 0, 0], + Role::SyncCommittee => [3, 0, 0, 0], + } + } +} + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub enum Executor { + Committee([u8; 32]), + Validator([u8; 48]), +} + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct MessageId([u8; 56]); + +impl MessageId { + pub fn new(domain: &Domain, role: Role, duty_executor: &Executor) -> Self { + let mut id = [0; 56]; + id[0..4].copy_from_slice(&domain.0); + id[4..8].copy_from_slice(&role.into_message_id_bytes()); + match duty_executor { + Executor::Committee(slice) => id[24..].copy_from_slice(slice), + Executor::Validator(slice) => id[8..].copy_from_slice(slice), + } + + MessageId(id) + } +} diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml index b9c929ddb..be97837a3 100644 --- a/anchor/validator_store/Cargo.toml +++ b/anchor/validator_store/Cargo.toml @@ -8,6 +8,7 @@ rust-version = "1.81.0" [dependencies] dashmap = "6.1.0" processor = { workspace = true } +safe_arith = { workspace = true } signature_collector = { workspace = true } ssv_types = { workspace = true } tracing = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index e1c4a4545..f40c1c1b2 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -1,4 +1,5 @@ use dashmap::DashMap; +use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; use ssv_types::{Cluster, OperatorId}; use std::marker::PhantomData; @@ -24,6 +25,7 @@ use types::validator_registration_data::{ use types::voluntary_exit::VoluntaryExit; use types::{ Address, ChainSpec, Domain, EthSpec, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, + SyncAggregatorSelectionData, }; use validator_store::{ DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, ValidatorStore, @@ -61,6 +63,15 @@ impl AnchorValidatorStore { } } + fn get_domain(&self, epoch: Epoch, domain: Domain) -> Hash256 { + self.spec.get_domain( + epoch, + domain, + &self.spec.fork_at_epoch(epoch), + self.genesis_validators_root, + ) + } + async fn collect_signature( &self, validator_pubkey: PublicKeyBytes, @@ -74,7 +85,12 @@ impl AnchorValidatorStore { SignatureRequest { cluster_id: cluster.cluster.cluster_id, signing_root, - threshold: cluster.cluster.cluster_members.len() as u64 - cluster.cluster.faulty, + threshold: cluster + .cluster + .faulty + .safe_mul(2) + .and_then(|x| x.safe_add(1)) + .map_err(SpecificError::from)?, }, self.operator_id, cluster.decrypted_key_share.clone(), @@ -90,6 +106,7 @@ impl AnchorValidatorStore { pub enum SpecificError { ExitsUnsupported, SignatureCollectionFailed(CollectionError), + ArithError(ArithError), } impl From for SpecificError { @@ -98,6 +115,12 @@ impl From for SpecificError { } } +impl From for SpecificError { + fn from(err: ArithError) -> SpecificError { + SpecificError::ArithError(err) + } +} + pub type Error = ValidatorStoreError; impl ValidatorStore for AnchorValidatorStore { @@ -148,13 +171,8 @@ impl ValidatorStore for AnchorValidatorStore { validator_pubkey: PublicKeyBytes, signing_epoch: Epoch, ) -> Result { - let domain = self.spec.get_domain( - signing_epoch, - Domain::Randao, - &self.spec.fork_at_epoch(signing_epoch), - self.genesis_validators_root, - ); - let signing_root = signing_epoch.signing_root(domain); + let domain_hash = self.get_domain(signing_epoch, Domain::Randao); + let signing_root = signing_epoch.signing_root(domain_hash); self.collect_signature(validator_pubkey, signing_root).await } @@ -181,9 +199,25 @@ impl ValidatorStore for AnchorValidatorStore { async fn sign_block>( &self, _validator_pubkey: PublicKeyBytes, - _block: BeaconBlock, - _current_slot: Slot, + block: BeaconBlock, + current_slot: Slot, ) -> Result, Error> { + // Make sure the block slot is not higher than the current slot to avoid potential attacks. + if block.slot() > current_slot { + warn!( + "block_slot" = block.slot().as_u64(), + "current_slot" = current_slot.as_u64(), + "Not signing block with slot greater than current slot", + ); + return Err(Error::GreaterThanCurrentSlot { + slot: block.slot(), + current_slot, + }); + } + + // todo slashing protection + + // first, we have to get to consensus todo!() } @@ -208,9 +242,19 @@ impl ValidatorStore for AnchorValidatorStore { async fn sign_validator_registration_data( &self, - _validator_registration_data: ValidatorRegistrationData, + validator_registration_data: ValidatorRegistrationData, ) -> Result { - todo!() + let domain_hash = self.spec.get_builder_domain(); + let signing_root = validator_registration_data.signing_root(domain_hash); + + let signature = self + .collect_signature(validator_registration_data.pubkey, signing_root) + .await?; + + Ok(SignedValidatorRegistrationData { + message: validator_registration_data, + signature, + }) } async fn produce_signed_aggregate_and_proof( @@ -225,25 +269,41 @@ impl ValidatorStore for AnchorValidatorStore { async fn produce_selection_proof( &self, - _validator_pubkey: PublicKeyBytes, - _slot: Slot, + validator_pubkey: PublicKeyBytes, + slot: Slot, ) -> Result { - todo!() + let epoch = slot.epoch(E::slots_per_epoch()); + let domain_hash = self.get_domain(epoch, Domain::SelectionProof); + let signing_root = slot.signing_root(domain_hash); + + self.collect_signature(validator_pubkey, signing_root) + .await + .map(SelectionProof::from) } async fn produce_sync_selection_proof( &self, - _validator_pubkey: &PublicKeyBytes, - _slot: Slot, - _subnet_id: SyncSubnetId, + validator_pubkey: &PublicKeyBytes, + slot: Slot, + subnet_id: SyncSubnetId, ) -> Result { - todo!() + let epoch = slot.epoch(E::slots_per_epoch()); + let domain_hash = self.get_domain(epoch, Domain::SyncCommitteeSelectionProof); + let signing_root = SyncAggregatorSelectionData { + slot, + subcommittee_index: subnet_id.into(), + } + .signing_root(domain_hash); + + self.collect_signature(*validator_pubkey, signing_root) + .await + .map(SyncSelectionProof::from) } async fn produce_sync_committee_signature( &self, _slot: Slot, - _beacon_block_root: types::Hash256, + _beacon_block_root: Hash256, _validator_index: u64, _validator_pubkey: &PublicKeyBytes, ) -> Result { From 6bc94719ebb53c6cd30e95191feb007b23d730bc Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 19 Dec 2024 12:13:37 +0100 Subject: [PATCH 06/21] move `qbft` crate to common directory --- Cargo.toml | 4 ++-- anchor/{ => common}/qbft/Cargo.toml | 0 anchor/{ => common}/qbft/src/config.rs | 0 anchor/{ => common}/qbft/src/error.rs | 0 anchor/{ => common}/qbft/src/lib.rs | 0 anchor/{ => common}/qbft/src/tests.rs | 0 anchor/{ => common}/qbft/src/types.rs | 0 anchor/{ => common}/qbft/src/validation.rs | 0 8 files changed, 2 insertions(+), 2 deletions(-) rename anchor/{ => common}/qbft/Cargo.toml (100%) rename anchor/{ => common}/qbft/src/config.rs (100%) rename anchor/{ => common}/qbft/src/error.rs (100%) rename anchor/{ => common}/qbft/src/lib.rs (100%) rename anchor/{ => common}/qbft/src/tests.rs (100%) rename anchor/{ => common}/qbft/src/types.rs (100%) rename anchor/{ => common}/qbft/src/validation.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index e84cf0a90..e6d8b415e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,13 +3,13 @@ members = [ "anchor", "anchor/client", + "anchor/common/qbft", "anchor/common/ssv_types", "anchor/common/version", "anchor/http_api", "anchor/http_metrics", "anchor/network", "anchor/processor", - "anchor/qbft", "anchor/signature_collector", ] resolver = "2" @@ -19,7 +19,7 @@ edition = "2021" [workspace.dependencies] client = { path = "anchor/client" } -qbft = { path = "anchor/qbft" } +qbft = { path = "anchor/common/qbft" } http_api = { path = "anchor/http_api" } http_metrics = { path = "anchor/http_metrics" } network = { path = "anchor/network" } diff --git a/anchor/qbft/Cargo.toml b/anchor/common/qbft/Cargo.toml similarity index 100% rename from anchor/qbft/Cargo.toml rename to anchor/common/qbft/Cargo.toml diff --git a/anchor/qbft/src/config.rs b/anchor/common/qbft/src/config.rs similarity index 100% rename from anchor/qbft/src/config.rs rename to anchor/common/qbft/src/config.rs diff --git a/anchor/qbft/src/error.rs b/anchor/common/qbft/src/error.rs similarity index 100% rename from anchor/qbft/src/error.rs rename to anchor/common/qbft/src/error.rs diff --git a/anchor/qbft/src/lib.rs b/anchor/common/qbft/src/lib.rs similarity index 100% rename from anchor/qbft/src/lib.rs rename to anchor/common/qbft/src/lib.rs diff --git a/anchor/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs similarity index 100% rename from anchor/qbft/src/tests.rs rename to anchor/common/qbft/src/tests.rs diff --git a/anchor/qbft/src/types.rs b/anchor/common/qbft/src/types.rs similarity index 100% rename from anchor/qbft/src/types.rs rename to anchor/common/qbft/src/types.rs diff --git a/anchor/qbft/src/validation.rs b/anchor/common/qbft/src/validation.rs similarity index 100% rename from anchor/qbft/src/validation.rs rename to anchor/common/qbft/src/validation.rs From fd5e5c8df0bd626c8cbc86d77a3013c595279c53 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 19 Dec 2024 18:01:41 +0100 Subject: [PATCH 07/21] update to reflect lighthouse changes --- Cargo.lock | 116 ++++++++++++++++++------------ anchor/client/src/lib.rs | 32 ++++----- anchor/validator_store/src/lib.rs | 31 ++++---- 3 files changed, 102 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 787c747a9..8e75f8689 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -662,7 +662,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon_node_fallback" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "eth2", "futures", @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "arbitrary", @@ -886,9 +886,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.4" +version = "1.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" dependencies = [ "jobserver", "libc", @@ -1027,7 +1027,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "clap", @@ -1093,7 +1093,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "itertools 0.10.5", ] @@ -1101,7 +1101,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "quote", "syn 1.0.109", @@ -1639,7 +1639,7 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "clap", "clap_utils", @@ -1941,7 +1941,7 @@ dependencies = [ [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "derivative", "eth2_keystore", @@ -1957,6 +1957,7 @@ dependencies = [ "proto_array", "psutil", "reqwest", + "reqwest-eventsource", "sensitive_url", "serde", "serde_json", @@ -1970,7 +1971,7 @@ dependencies = [ [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "paste", "types", @@ -1979,7 +1980,7 @@ dependencies = [ [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bls", "ethereum_hashing", @@ -1992,7 +1993,7 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bls", "num-bigint-dig", @@ -2004,7 +2005,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "aes 0.7.5", "bls", @@ -2026,7 +2027,7 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bytes", "discv5 0.9.0", @@ -2118,6 +2119,17 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "eventsource-stream" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fef4569247a5f429d9156b9d0a2599914385dd189c539334c625d8099d90ab" +dependencies = [ + "futures-core", + "nom", + "pin-project-lite", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -2204,7 +2216,7 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "winapi", "windows-acl", @@ -2225,7 +2237,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "safe_arith", @@ -2490,7 +2502,7 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "async-channel", "asynchronous-codec", @@ -2519,7 +2531,7 @@ dependencies = [ [[package]] name = "graffiti_file" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bls", "serde", @@ -3212,7 +3224,7 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bytes", ] @@ -3360,7 +3372,7 @@ dependencies = [ [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "arbitrary", "c-kzg", @@ -3416,9 +3428,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.168" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libflate" @@ -3955,7 +3967,7 @@ dependencies = [ [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -4004,7 +4016,7 @@ dependencies = [ [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "git-version", "target_info", @@ -4053,7 +4065,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "chrono", "metrics", @@ -4093,7 +4105,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "fnv", ] @@ -4158,7 +4170,7 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -4192,7 +4204,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "prometheus", ] @@ -4889,7 +4901,7 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "reqwest", "sensitive_url", @@ -5044,7 +5056,7 @@ dependencies = [ [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", @@ -5390,6 +5402,22 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest-eventsource" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f529a5ff327743addc322af460761dff5b50e0c826b9e6ac44c3195c50bb2026" +dependencies = [ + "eventsource-stream", + "futures-core", + "futures-timer", + "mime", + "nom", + "pin-project-lite", + "reqwest", + "thiserror 1.0.69", +] + [[package]] name = "resolv-conf" version = "0.7.0" @@ -5725,7 +5753,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" [[package]] name = "salsa20" @@ -5846,7 +5874,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "serde", "url", @@ -6043,7 +6071,7 @@ dependencies = [ [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -6162,7 +6190,7 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "metrics", "parking_lot", @@ -6270,7 +6298,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "state_processing" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "arbitrary", "bls", @@ -6302,7 +6330,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "bls", "db-key", @@ -6385,7 +6413,7 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -6500,7 +6528,7 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "async-channel", "futures", @@ -6549,7 +6577,7 @@ dependencies = [ [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "quote", "syn 1.0.109", @@ -6952,7 +6980,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7115,7 +7143,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "lru_cache", "parking_lot", @@ -7163,7 +7191,7 @@ dependencies = [ [[package]] name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "metrics", ] @@ -7171,7 +7199,7 @@ dependencies = [ [[package]] name = "validator_services" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "beacon_node_fallback", "bls", @@ -7194,7 +7222,7 @@ dependencies = [ [[package]] name = "validator_store" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#8d8476fd38a8ea9992baf7ca94000125bebe7281" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" dependencies = [ "slashing_protection", "types", diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index ac65d71e9..5311cd91b 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -234,14 +234,14 @@ impl Client { // Initialize the number of connected, avaliable beacon nodes to 0. set_gauge(&validator_metrics::AVAILABLE_BEACON_NODES_COUNT, 0); - let mut beacon_nodes: BeaconNodeFallback<_, E> = BeaconNodeFallback::new( + let mut beacon_nodes: BeaconNodeFallback<_> = BeaconNodeFallback::new( candidates, beacon_node_fallback::Config::default(), // TODO make configurable vec![ApiTopic::Subscriptions], // TODO make configurable spec.clone(), ); - let mut proposer_nodes: BeaconNodeFallback<_, E> = BeaconNodeFallback::new( + let mut proposer_nodes: BeaconNodeFallback<_> = BeaconNodeFallback::new( proposer_candidates, beacon_node_fallback::Config::default(), // TODO make configurable vec![ApiTopic::Subscriptions], // TODO make configurable @@ -250,7 +250,7 @@ impl Client { // Perform some potentially long-running initialization tasks. let (genesis_time, genesis_validators_root) = tokio::select! { - tuple = init_from_beacon_node(&beacon_nodes, &proposer_nodes) => tuple?, + tuple = init_from_beacon_node::(&beacon_nodes, &proposer_nodes) => tuple?, () = executor.exit() => return Err("Shutting down".to_string()) }; @@ -264,10 +264,10 @@ impl Client { proposer_nodes.set_slot_clock(slot_clock.clone()); let beacon_nodes = Arc::new(beacon_nodes); - start_fallback_updater_service(executor.clone(), beacon_nodes.clone())?; + start_fallback_updater_service::<_, E>(executor.clone(), beacon_nodes.clone())?; let proposer_nodes = Arc::new(proposer_nodes); - start_fallback_updater_service(executor.clone(), proposer_nodes.clone())?; + start_fallback_updater_service::<_, E>(executor.clone(), proposer_nodes.clone())?; let validator_store = Arc::new(AnchorValidatorStore::new( processor_senders, @@ -286,7 +286,7 @@ impl Client { .executor(executor.clone()) //.enable_high_validator_count_metrics(config.enable_high_validator_count_metrics) .distributed(true) - .build()?, + .build::()?, ); // Update the metrics server. @@ -350,7 +350,7 @@ impl Client { duties_service::start_update_service(duties_service.clone(), block_service_tx); block_service - .start_update_service(block_service_rx) + .start_update_service::(block_service_rx) .map_err(|e| format!("Unable to start block service: {}", e))?; attestation_service @@ -362,7 +362,7 @@ impl Client { .map_err(|e| format!("Unable to start sync committee service: {}", e))?; preparation_service - .start_update_service(&spec) + .start_update_service::(&spec) .map_err(|e| format!("Unable to start preparation service: {}", e))?; Ok(()) @@ -370,14 +370,14 @@ impl Client { } async fn init_from_beacon_node( - beacon_nodes: &BeaconNodeFallback, - proposer_nodes: &BeaconNodeFallback, + beacon_nodes: &BeaconNodeFallback, + proposer_nodes: &BeaconNodeFallback, ) -> Result<(u64, Hash256), String> { const RETRY_DELAY: Duration = Duration::from_secs(2); loop { - beacon_nodes.update_all_candidates().await; - proposer_nodes.update_all_candidates().await; + beacon_nodes.update_all_candidates::().await; + proposer_nodes.update_all_candidates::().await; let num_available = beacon_nodes.num_available().await; let num_total = beacon_nodes.num_total().await; @@ -454,8 +454,8 @@ async fn init_from_beacon_node( Ok((genesis.genesis_time, genesis.genesis_validators_root)) } -async fn wait_for_genesis( - beacon_nodes: &BeaconNodeFallback, +async fn wait_for_genesis( + beacon_nodes: &BeaconNodeFallback, genesis_time: u64, ) -> Result<(), String> { let now = SystemTime::now() @@ -497,8 +497,8 @@ async fn wait_for_genesis( /// Request the version from the node, looping back and trying again on failure. Exit once the node /// has been contacted. -async fn poll_whilst_waiting_for_genesis( - beacon_nodes: &BeaconNodeFallback, +async fn poll_whilst_waiting_for_genesis( + beacon_nodes: &BeaconNodeFallback, genesis_time: Duration, ) -> Result<(), String> { loop { diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index f40c1c1b2..d0f0385c8 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -2,7 +2,6 @@ use dashmap::DashMap; use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; use ssv_types::{Cluster, OperatorId}; -use std::marker::PhantomData; use std::sync::Arc; use tracing::{error, warn}; use types::attestation::Attestation; @@ -36,30 +35,28 @@ struct InitializedCluster { decrypted_key_share: SecretKey, } -pub struct AnchorValidatorStore { +pub struct AnchorValidatorStore { clusters: DashMap, signature_collector: Arc, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, - _phantom: PhantomData, } -impl AnchorValidatorStore { +impl AnchorValidatorStore { pub fn new( _processor: processor::Senders, signature_collector: Arc, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, - ) -> AnchorValidatorStore { + ) -> AnchorValidatorStore { Self { clusters: DashMap::new(), signature_collector, spec, genesis_validators_root, operator_id, - _phantom: PhantomData, } } @@ -123,7 +120,7 @@ impl From for SpecificError { pub type Error = ValidatorStoreError; -impl ValidatorStore for AnchorValidatorStore { +impl ValidatorStore for AnchorValidatorStore { type Error = SpecificError; fn validator_index(&self, pubkey: &PublicKeyBytes) -> Option { @@ -166,7 +163,7 @@ impl ValidatorStore for AnchorValidatorStore { Some(1) } - async fn randao_reveal( + async fn randao_reveal( &self, validator_pubkey: PublicKeyBytes, signing_epoch: Epoch, @@ -196,7 +193,7 @@ impl ValidatorStore for AnchorValidatorStore { } } - async fn sign_block>( + async fn sign_block>( &self, _validator_pubkey: PublicKeyBytes, block: BeaconBlock, @@ -221,7 +218,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - async fn sign_attestation( + async fn sign_attestation( &self, _validator_pubkey: PublicKeyBytes, _validator_committee_position: usize, @@ -231,7 +228,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - async fn sign_voluntary_exit( + async fn sign_voluntary_exit( &self, _validator_pubkey: PublicKeyBytes, _voluntary_exit: VoluntaryExit, @@ -240,7 +237,7 @@ impl ValidatorStore for AnchorValidatorStore { Err(Error::SpecificError(SpecificError::ExitsUnsupported)) } - async fn sign_validator_registration_data( + async fn sign_validator_registration_data( &self, validator_registration_data: ValidatorRegistrationData, ) -> Result { @@ -257,7 +254,7 @@ impl ValidatorStore for AnchorValidatorStore { }) } - async fn produce_signed_aggregate_and_proof( + async fn produce_signed_aggregate_and_proof( &self, _validator_pubkey: PublicKeyBytes, _aggregator_index: u64, @@ -267,7 +264,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - async fn produce_selection_proof( + async fn produce_selection_proof( &self, validator_pubkey: PublicKeyBytes, slot: Slot, @@ -281,7 +278,7 @@ impl ValidatorStore for AnchorValidatorStore { .map(SelectionProof::from) } - async fn produce_sync_selection_proof( + async fn produce_sync_selection_proof( &self, validator_pubkey: &PublicKeyBytes, slot: Slot, @@ -300,7 +297,7 @@ impl ValidatorStore for AnchorValidatorStore { .map(SyncSelectionProof::from) } - async fn produce_sync_committee_signature( + async fn produce_sync_committee_signature( &self, _slot: Slot, _beacon_block_root: Hash256, @@ -310,7 +307,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - async fn produce_signed_contribution_and_proof( + async fn produce_signed_contribution_and_proof( &self, _aggregator_index: u64, _aggregator_pubkey: PublicKeyBytes, From 51b74f25b2070d50333fd48892131457c4dfbeab Mon Sep 17 00:00:00 2001 From: ThreeHrSleep <151536303+ThreeHrSleep@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:30:48 +0530 Subject: [PATCH 08/21] Align tracing related changes with lighthouse --- anchor/client/src/lib.rs | 46 +++++++++++++++---------------- anchor/validator_store/src/lib.rs | 4 +-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 5311cd91b..2486f02d0 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -387,36 +387,36 @@ async fn init_from_beacon_node( if proposer_total > 0 && proposer_available == 0 { warn!( - "retry in" = format!("{} seconds", RETRY_DELAY.as_secs()), - "total_proposers" = proposer_total, - "available_proposers" = proposer_available, - "total_beacon_nodes" = num_total, - "available_beacon_nodes" = num_available, + retry_in = format!("{} seconds", RETRY_DELAY.as_secs()), + total_proposers = proposer_total, + available_proposers = proposer_available, + total_beacon_nodes = num_total, + available_beacon_nodes = num_available, "Unable to connect to a proposer node" ); } if num_available > 0 && proposer_available == 0 { info!( - "total" = num_total, - "available" = num_available, + total = num_total, + available = num_available, "Initialized beacon node connections" ); break; } else if num_available > 0 { info!( - "total" = num_total, - "available" = num_available, - "proposers_available" = proposer_available, - "proposers_total" = proposer_total, + total = num_total, + available = num_available, + proposers_available = proposer_available, + proposers_total = proposer_total, "Initialized beacon node connections" ); break; } else { warn!( - "retry in" = format!("{} seconds", RETRY_DELAY.as_secs()), - "total" = num_total, - "available" = num_available, + retry_in = format!("{} seconds", RETRY_DELAY.as_secs()), + total = num_total, + available = num_available, "Unable to connect to a beacon node" ); sleep(RETRY_DELAY).await; @@ -441,7 +441,7 @@ async fn init_from_beacon_node( info!("Waiting for genesis",); } else { error!( - "error" = ?errors.0, + error = ?errors.0, "Errors polling beacon node", ); } @@ -470,7 +470,7 @@ async fn wait_for_genesis( // the slot clock. if now < genesis_time { info!( - "seconds_to_wait" = (genesis_time - now).as_secs(), + seconds_to_wait = (genesis_time - now).as_secs(), "Starting node prior to genesis", ); @@ -482,12 +482,12 @@ async fn wait_for_genesis( }; info!( - "ms_since_genesis" = (genesis_time - now).as_millis(), + ms_since_genesis = (genesis_time - now).as_millis(), "Genesis has occurred", ); } else { info!( - "seconds_ago" = (now - genesis_time).as_secs(), + seconds_ago = (now - genesis_time).as_secs(), "Genesis has already occurred", ); } @@ -513,16 +513,16 @@ async fn poll_whilst_waiting_for_genesis( if !is_staking { error!( - "msg" = "this will caused missed duties", - "info" = "see the --staking CLI flag on the beacon node", + msg = "this will caused missed duties", + info = "see the --staking CLI flag on the beacon node", "Staking is disabled for beacon node" ); } if now < genesis_time { info!( - "bn_staking_enabled" = is_staking, - "seconds_to_wait" = (genesis_time - now).as_secs(), + bn_staking_enabled = is_staking, + seconds_to_wait = (genesis_time - now).as_secs(), "Waiting for genesis" ); } else { @@ -531,7 +531,7 @@ async fn poll_whilst_waiting_for_genesis( } Err(e) => { error!( - "error" = ?e.0, + error = ?e.0, "Error polling beacon node", ); } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index d0f0385c8..571e8997b 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -202,8 +202,8 @@ impl ValidatorStore for AnchorValidatorStore { // Make sure the block slot is not higher than the current slot to avoid potential attacks. if block.slot() > current_slot { warn!( - "block_slot" = block.slot().as_u64(), - "current_slot" = current_slot.as_u64(), + block_slot = block.slot().as_u64(), + current_slot = current_slot.as_u64(), "Not signing block with slot greater than current slot", ); return Err(Error::GreaterThanCurrentSlot { From 6c586a66f09a5801a09cf2a17265bd11f7c3780c Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 2 Jan 2025 10:15:20 +0100 Subject: [PATCH 09/21] update deps --- Cargo.lock | 234 +++++++++++++++--------------- anchor/client/src/lib.rs | 8 +- anchor/validator_store/src/lib.rs | 2 +- 3 files changed, 122 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e75f8689..a887813cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,9 +100,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-primitives" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6259a506ab13e1d658796c31e6e39d2e2ee89243bcc505ddc613b35732e0a430" +checksum = "0540fd0355d400b59633c27bd4b42173e59943f28e9d3376b77a24771d432d04" dependencies = [ "alloy-rlp", "arbitrary", @@ -149,7 +149,7 @@ checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "arbitrary" @@ -439,7 +439,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "synstructure", ] @@ -451,7 +451,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -509,7 +509,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -544,7 +544,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -662,7 +662,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon_node_fallback" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "eth2", "futures", @@ -696,7 +696,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.90", + "syn 2.0.94", "which", ] @@ -769,7 +769,7 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "arbitrary", @@ -886,9 +886,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "jobserver", "libc", @@ -1015,7 +1015,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1027,7 +1027,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "clap", @@ -1093,7 +1093,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "itertools 0.10.5", ] @@ -1101,7 +1101,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "quote", "syn 1.0.109", @@ -1370,7 +1370,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1418,7 +1418,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1440,7 +1440,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1579,7 +1579,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1590,7 +1590,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1611,7 +1611,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "unicode-xid", ] @@ -1639,7 +1639,7 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "clap", "clap_utils", @@ -1780,7 +1780,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1910,7 +1910,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -1941,7 +1941,7 @@ dependencies = [ [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "derivative", "eth2_keystore", @@ -1971,7 +1971,7 @@ dependencies = [ [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "paste", "types", @@ -1980,7 +1980,7 @@ dependencies = [ [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bls", "ethereum_hashing", @@ -1993,7 +1993,7 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bls", "num-bigint-dig", @@ -2005,7 +2005,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "aes 0.7.5", "bls", @@ -2027,7 +2027,7 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bytes", "discv5 0.9.0", @@ -2089,7 +2089,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -2216,7 +2216,7 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "winapi", "windows-acl", @@ -2237,7 +2237,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "safe_arith", @@ -2261,9 +2261,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "foreign-types" @@ -2372,7 +2372,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -2490,19 +2490,19 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "async-channel", "asynchronous-codec", @@ -2531,7 +2531,7 @@ dependencies = [ [[package]] name = "graffiti_file" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bls", "serde", @@ -3089,7 +3089,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -3188,7 +3188,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -3224,7 +3224,7 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bytes", ] @@ -3372,7 +3372,7 @@ dependencies = [ [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "arbitrary", "c-kzg", @@ -3825,7 +3825,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -3967,7 +3967,7 @@ dependencies = [ [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -4016,7 +4016,7 @@ dependencies = [ [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "git-version", "target_info", @@ -4065,7 +4065,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "chrono", "metrics", @@ -4105,7 +4105,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "fnv", ] @@ -4170,7 +4170,7 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -4204,7 +4204,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "prometheus", ] @@ -4547,9 +4547,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -4598,7 +4598,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -4787,7 +4787,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.8", + "thiserror 2.0.9", "ucd-trie", ] @@ -4808,7 +4808,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -4901,7 +4901,7 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "reqwest", "sensitive_url", @@ -4914,7 +4914,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -5019,7 +5019,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -5050,13 +5050,13 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", @@ -5145,7 +5145,7 @@ dependencies = [ "rustc-hash 2.1.0", "rustls 0.23.20", "socket2", - "thiserror 2.0.8", + "thiserror 2.0.9", "tokio", "tracing", ] @@ -5164,7 +5164,7 @@ dependencies = [ "rustls 0.23.20", "rustls-pki-types", "slab", - "thiserror 2.0.8", + "thiserror 2.0.9", "tinyvec", "tracing", "web-time", @@ -5186,9 +5186,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -5717,9 +5717,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "rusty-fork" @@ -5753,7 +5753,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" [[package]] name = "salsa20" @@ -5874,7 +5874,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "serde", "url", @@ -5882,29 +5882,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", "memchr", @@ -5930,7 +5930,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6071,7 +6071,7 @@ dependencies = [ [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -6190,7 +6190,7 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "metrics", "parking_lot", @@ -6298,7 +6298,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "state_processing" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "arbitrary", "bls", @@ -6330,7 +6330,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "bls", "db-key", @@ -6413,7 +6413,7 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -6433,9 +6433,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" dependencies = [ "proc-macro2", "quote", @@ -6462,7 +6462,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6528,7 +6528,7 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "async-channel", "futures", @@ -6577,7 +6577,7 @@ dependencies = [ [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "quote", "syn 1.0.109", @@ -6594,11 +6594,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.8" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f5383f3e0071702bf93ab5ee99b52d26936be9dedd9413067cbdcddcb6141a" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" dependencies = [ - "thiserror-impl 2.0.8", + "thiserror-impl 2.0.9", ] [[package]] @@ -6609,18 +6609,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] name = "thiserror-impl" -version = "2.0.8" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f357fcec90b3caef6623a099691be676d033b40a058ac95d2a6ade6fa0c943" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6694,9 +6694,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -6742,7 +6742,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6871,7 +6871,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6952,7 +6952,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -6980,7 +6980,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7143,7 +7143,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "lru_cache", "parking_lot", @@ -7191,7 +7191,7 @@ dependencies = [ [[package]] name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "metrics", ] @@ -7199,7 +7199,7 @@ dependencies = [ [[package]] name = "validator_services" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "beacon_node_fallback", "bls", @@ -7222,7 +7222,7 @@ dependencies = [ [[package]] name = "validator_store" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#838eed6e3aad71f48eb80212a11d36103da020cc" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" dependencies = [ "slashing_protection", "types", @@ -7312,7 +7312,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "wasm-bindgen-shared", ] @@ -7347,7 +7347,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7709,9 +7709,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "e6f5bb5257f2407a5425c6e749bfd9692192a73e70a6060516ac04f889087d68" dependencies = [ "memchr", ] @@ -7865,7 +7865,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "synstructure", ] @@ -7887,7 +7887,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -7907,7 +7907,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", "synstructure", ] @@ -7929,7 +7929,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] @@ -7951,7 +7951,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.94", ] [[package]] diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 2486f02d0..63e9428bc 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -286,7 +286,7 @@ impl Client { .executor(executor.clone()) //.enable_high_validator_count_metrics(config.enable_high_validator_count_metrics) .distributed(true) - .build::()?, + .build()?, ); // Update the metrics server. @@ -347,18 +347,18 @@ impl Client { // Wait until genesis has occurred. wait_for_genesis(&beacon_nodes, genesis_time).await?; - duties_service::start_update_service(duties_service.clone(), block_service_tx); + duties_service::start_update_service::<_, _, E>(duties_service.clone(), block_service_tx); block_service .start_update_service::(block_service_rx) .map_err(|e| format!("Unable to start block service: {}", e))?; attestation_service - .start_update_service(&spec) + .start_update_service::(&spec) .map_err(|e| format!("Unable to start attestation service: {}", e))?; sync_committee_service - .start_update_service(&spec) + .start_update_service::(&spec) .map_err(|e| format!("Unable to start sync committee service: {}", e))?; preparation_service diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 571e8997b..e20ea28ca 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -317,7 +317,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { + fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { // TODO slashing protection } From 8e7634233c159de2b8de3fe2d82609dd7968eb0d Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 19 Dec 2024 16:03:26 +0100 Subject: [PATCH 10/21] implement initial qbft manager --- Cargo.lock | 21 +- Cargo.toml | 4 + anchor/common/qbft/Cargo.toml | 4 +- anchor/common/qbft/src/error.rs | 1 - anchor/common/qbft/src/lib.rs | 304 +++++++++++------------- anchor/common/qbft/src/tests.rs | 9 +- anchor/common/qbft/src/types.rs | 34 +-- anchor/common/ssv_types/Cargo.toml | 3 + anchor/common/ssv_types/src/lib.rs | 2 + anchor/common/ssv_types/src/message.rs | 187 +++++++++++++++ anchor/common/ssv_types/src/msgid.rs | 47 ++++ anchor/network/Cargo.toml | 2 + anchor/network/src/lib.rs | 2 +- anchor/qbft_manager/Cargo.toml | 15 ++ anchor/qbft_manager/src/lib.rs | 309 +++++++++++++++++++++++++ 15 files changed, 743 insertions(+), 201 deletions(-) create mode 100644 anchor/common/ssv_types/src/message.rs create mode 100644 anchor/common/ssv_types/src/msgid.rs create mode 100644 anchor/qbft_manager/Cargo.toml create mode 100644 anchor/qbft_manager/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a505c8491..057dd101e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5314,9 +5314,11 @@ dependencies = [ "libp2p", "lighthouse_network 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", "serde", + "ssv_types", "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", "tokio", "tracing", + "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", "version", ] @@ -6145,12 +6147,24 @@ name = "qbft" version = "0.1.0" dependencies = [ "derive_more 1.0.0", - "futures", - "tokio", "tracing", "tracing-subscriber", ] +[[package]] +name = "qbft_manager" +version = "0.1.0" +dependencies = [ + "dashmap", + "processor", + "qbft", + "slot_clock", + "ssv_types", + "tokio", + "tracing", + "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -7516,6 +7530,9 @@ dependencies = [ "base64 0.22.1", "derive_more 1.0.0", "openssl", + "qbft", + "tree_hash", + "tree_hash_derive", "types 0.2.1 (git+https://github.com/sigp/lighthouse?branch=unstable)", ] diff --git a/Cargo.toml b/Cargo.toml index e6d8b415e..70febabdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "anchor/http_metrics", "anchor/network", "anchor/processor", + "anchor/qbft_manager", "anchor/signature_collector", ] resolver = "2" @@ -27,6 +28,7 @@ version = { path = "anchor/common/version" } processor = { path = "anchor/processor" } ssv_types = { path = "anchor/common/ssv_types" } signature_collector = { path = "anchor/signature_collector" } +qbft_manager = { path = "anchor/common/qbft" } lighthouse_network = { git = "https://github.com/sigp/lighthouse", branch = "unstable" } task_executor = { git = "https://github.com/sigp/lighthouse", branch = "unstable", default-features = false, features = [ "tracing", ] } metrics = { git = "https://github.com/agemanning/lighthouse", branch = "modularize-vc" } @@ -59,6 +61,8 @@ tokio = { version = "1.39.2", features = [ ] } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["fmt", "env-filter"] } +tree_hash = "0.8" +tree_hash_derive = "0.8" base64 = "0.22.1" openssl = "0.10.68" diff --git a/anchor/common/qbft/Cargo.toml b/anchor/common/qbft/Cargo.toml index e803a1ef9..c651a175d 100644 --- a/anchor/common/qbft/Cargo.toml +++ b/anchor/common/qbft/Cargo.toml @@ -6,7 +6,7 @@ edition = { workspace = true } [dependencies] derive_more = { workspace = true } -futures = { workspace = true } -tokio = { workspace = true, features = ["sync"] } tracing = { workspace = true } + +[dev-dependencies] tracing-subscriber = { workspace = true } diff --git a/anchor/common/qbft/src/error.rs b/anchor/common/qbft/src/error.rs index 2868a842e..fcbaff5b4 100644 --- a/anchor/common/qbft/src/error.rs +++ b/anchor/common/qbft/src/error.rs @@ -1,5 +1,4 @@ /// Error associated with Config building. -// TODO: Remove this allow #[derive(Debug)] pub enum ConfigBuilderError { /// Quorum size too small diff --git a/anchor/common/qbft/src/lib.rs b/anchor/common/qbft/src/lib.rs index d51e2cfd2..6c6f1bc82 100644 --- a/anchor/common/qbft/src/lib.rs +++ b/anchor/common/qbft/src/lib.rs @@ -3,13 +3,13 @@ use std::cmp::Eq; use std::collections::{HashMap, HashSet}; use std::fmt::Debug; use std::hash::Hash; -use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; -use tracing::{debug, instrument, warn, Level}; +use tracing::{debug, error, warn}; pub use validation::{validate_consensus_data, ValidatedData, ValidationError}; +pub use error::ConfigBuilderError; pub use types::{ - Completed, ConsensusData, InMessage, InstanceHeight, InstanceState, LeaderFunction, OperatorId, - OutMessage, Round, + Completed, ConsensusData, DefaultLeaderFunction, InstanceHeight, InstanceState, LeaderFunction, + Message, OperatorId, Round, }; mod config; @@ -20,123 +20,82 @@ mod validation; #[cfg(test)] mod tests; -type RoundChangeMap = HashMap>>>; +type RoundChangeMap = HashMap>>; + +pub trait Data: Debug + Clone { + type Hash: Debug + Clone + Eq + Hash; + + fn hash(&self) -> Self::Hash; +} /// The structure that defines the Quorum Based Fault Tolerance (QBFT) instance. /// /// This builds and runs an entire QBFT process until it completes. It can complete either /// successfully (i.e that it has successfully come to consensus, or through a timeout where enough /// round changes have elapsed before coming to consensus. -pub struct Qbft +pub struct Qbft where F: LeaderFunction + Clone, - D: Debug + Clone + Eq + Hash, + D: Data, + S: FnMut(Message), { /// The initial configuration used to establish this instance of QBFT. config: Config, /// Initial data that we will propose if we are the leader. - start_data: ValidatedData, + start_data: D::Hash, /// The instance height acts as an ID for the current instance and helps distinguish it from /// other instances. instance_height: InstanceHeight, /// The current round this instance state is in.a current_round: Round, + /// All the data + data: HashMap>, /// If we have come to consensus in a previous round this is set here. - past_consensus: HashMap>, + past_consensus: HashMap, /// The messages received this round that we have collected to reach quorum. - prepare_messages: HashMap, HashSet>>, - commit_messages: HashMap, HashSet>>, + prepare_messages: HashMap>>, + commit_messages: HashMap>>, /// Stores the round change messages. The second hashmap stores optional past consensus /// data for each round change message. - round_change_messages: HashMap>, - // Channel that links the QBFT instance to the client processor and is where messages are sent - // to be distributed to the committee - message_out: UnboundedSender>, - // Channel that receives messages from the client processor - message_in: UnboundedReceiver>, + round_change_messages: HashMap>, + send_message: S, /// The current state of the instance state: InstanceState, + /// The completed value, if any + completed: Option>, } -impl Qbft +impl Qbft where F: LeaderFunction + Clone, - D: Debug + Clone + Hash + Eq, + D: Data, + S: Fn(Message), { - pub fn new( - config: Config, - start_data: ValidatedData, - ) -> ( - UnboundedSender>, - UnboundedReceiver>, - Self, - ) { - let (in_sender, message_in) = tokio::sync::mpsc::unbounded_channel(); - let (message_out, out_receiver) = tokio::sync::mpsc::unbounded_channel(); - + pub fn new(config: Config, start_data: ValidatedData, send_message: S) -> Self { let estimated_map_size = config.committee_size; - let instance = Qbft { + let mut data = HashMap::with_capacity(2); + let start_data_hash = start_data.data.hash(); + data.insert(start_data_hash.clone(), start_data); + + Qbft { current_round: config.round, instance_height: config.instance_height, config, - start_data, + start_data: start_data_hash, + data: HashMap::with_capacity(2), past_consensus: HashMap::with_capacity(2), prepare_messages: HashMap::with_capacity(estimated_map_size), commit_messages: HashMap::with_capacity(estimated_map_size), round_change_messages: HashMap::with_capacity(estimated_map_size), - message_out, - message_in, + send_message, state: InstanceState::AwaitingProposal, - }; - - (in_sender, out_receiver, instance) + completed: None, + } } - // This adds the fields to all our logs for this instance. - #[instrument(name = "QBFT",skip_all, fields(operator_id=*self.config.operator_id,instance_height=*self.config.instance_height), level= Level::ERROR)] - pub async fn start_instance(mut self) { - let mut round_end = tokio::time::interval(self.config.round_time); - self.start_round(); - loop { - // If we reached a critical error, end gracefully - if matches!(self.state, InstanceState::Complete) { - return; - } - - tokio::select! { - message = self.message_in.recv() => { - match message { - // When a Propose message is received, run the - // received_propose function - Some(InMessage::Propose(operator_id, consensus_data)) => self.received_propose(operator_id, consensus_data), - // When a Prepare message is received, run the - // received_prepare function - Some(InMessage::Prepare(operator_id, consensus_data)) => self.received_prepare(operator_id, consensus_data), - // When a Commit message is received, run the - // received_commit function - Some(InMessage::Commit(operator_id, consensus_data)) => self.received_commit(operator_id, consensus_data), - // When a RoundChange message is received, run the received_roundChange function - Some(InMessage::RoundChange(operator_id, round, maybe_past_consensus_data)) => self.received_round_change(operator_id, round, maybe_past_consensus_data), - // When a CloseRequest is received, close the instance - None => { } // Channel is closed - } - - } - _ = round_end.tick() => { - - debug!(round = *self.current_round,"Incrementing round"); - if *self.current_round > self.config.max_rounds() { - self.send_completed(Completed::TimedOut); - break; - } - self.send_round_change(self.current_round.next()); - // Start a new round - self.set_round(self.current_round.next()); - } - } - } - debug!("Instance killed"); + pub fn config(&self) -> &Config { + &self.config } /// Returns the operator id for this instance. @@ -154,22 +113,9 @@ where } } - /// Sends an outbound message - fn send_message(&mut self, message: OutMessage) { - if self.message_out.send(message).is_err() { - // The outbound channel has been closed. This instance can no longer progress. We - // should terminate the current running instance - warn!( - instance_height = *self.config.instance_height, - "Receiver channel closed. Terminating" - ); - self.state = InstanceState::Complete - } - } - /// Once we have achieved consensus on a PREPARE round, we add the data to mapping to match /// against later. - fn insert_consensus(&mut self, round: Round, data: ValidatedData) { + fn insert_consensus(&mut self, round: Round, data: D::Hash) { debug!(round = *round, ?data, "Reached prepare consensus"); if let Some(past_data) = self.past_consensus.insert(round, data.clone()) { warn!(round = *round, ?data, past_data = ?past_data, "Adding duplicate consensus data"); @@ -204,7 +150,7 @@ where /// If there is no past consensus data in the round change quorum or we disagree with quorum set /// this function will return None, and we obtain the data as if we were beginning this /// instance. - fn justify_round_change_quorum(&self) -> Option<&ValidatedData> { + fn justify_round_change_quorum(&self) -> Option<&D::Hash> { // If we have messages for the current round if let Some(new_round_messages) = self.round_change_messages.get(&self.current_round) { // If we have a quorum @@ -218,11 +164,11 @@ where .map(|consensus_data| *consensus_data.round) .unwrap_or(0) })? - .clone()?; + .as_ref()?; // We a maximum, check to make sure we have seen quorum on this let past_data = self.past_consensus.get(&max_consensus_data.round)?; - if *past_data == max_consensus_data.data { + if past_data == &max_consensus_data.data { return Some(past_data); } } @@ -246,16 +192,37 @@ where // We are the leader debug!("Current leader"); // Check justification of round change quorum - if let Some(validated_data) = self.justify_round_change_quorum().cloned() { + let hash = if let Some(validated_data) = self.justify_round_change_quorum().cloned() { debug!( old_data = ?validated_data, "Using consensus data from a previous round"); - self.send_proposal(validated_data.clone()); - self.send_prepare(validated_data); + validated_data } else { debug!("Using initialised data"); - self.send_proposal(self.start_data.clone()); - self.send_prepare(self.start_data.clone()); + self.start_data.clone() + }; + if let Some(data) = self.data.get(&hash).cloned() { + self.send_proposal(data); + self.send_prepare(hash.clone()); + } else { + error!("Unable to find data for known hash") + } + } + } + + pub fn receive(&mut self, msg: Message) { + match msg { + Message::Propose(operator_id, consensus_data) => { + self.received_propose(operator_id, consensus_data); + } + Message::Prepare(operator_id, consensus_data) => { + self.received_prepare(operator_id, consensus_data); + } + Message::Commit(operator_id, consensus_data) => { + self.received_commit(operator_id, consensus_data); + } + Message::RoundChange(operator_id, round, consensus_data) => { + self.received_round_change(operator_id, round, consensus_data); } } } @@ -263,7 +230,7 @@ where /// We have received a proposal message fn received_propose(&mut self, operator_id: OperatorId, consensus_data: ConsensusData) { // Check if proposal is from the leader we expect - if !(self.check_leader(&operator_id)) { + if !self.check_leader(&operator_id) { warn!(from = *operator_id, "PROPOSE message from non-leader"); return; } @@ -282,7 +249,7 @@ where return; } // Ensure that this message is for the correct round - if !(self.current_round == consensus_data.round) { + if self.current_round != consensus_data.round { warn!( from = *operator_id, current_round = *self.current_round, @@ -304,9 +271,10 @@ where debug!(from = *operator_id, "PROPOSE received"); + let hash = consensus_data.data.data.hash(); // Justify the proposal by checking the round changes if let Some(justified_data) = self.justify_round_change_quorum() { - if *justified_data != consensus_data.data { + if *justified_data != hash { // The data doesn't match the justified value we expect. Drop the message warn!( from = *operator_id, @@ -316,16 +284,17 @@ where ); return; } - self.send_prepare(consensus_data.data); - } else { - // We have no previous consensus data - // If of valid type, set data locally then send prepare - self.send_prepare(consensus_data.data); } + self.data.insert(hash.clone(), consensus_data.data); + self.send_prepare(hash); } /// We have received a prepare message - fn received_prepare(&mut self, operator_id: OperatorId, consensus_data: ConsensusData) { + fn received_prepare( + &mut self, + operator_id: OperatorId, + consensus_data: ConsensusData, + ) { // Check that this operator is in our committee if !self.check_committee(&operator_id) { warn!( @@ -342,7 +311,7 @@ where } // Ensure that this message is for the correct round - if !(self.current_round == consensus_data.round) { + if self.current_round != consensus_data.round { warn!( from = *operator_id, current_round = *self.current_round, @@ -369,7 +338,7 @@ where .prepare_messages .entry(consensus_data.round) .or_default() - .entry(consensus_data.data) + .entry(consensus_data.data.data) .or_default() .insert(operator_id) { @@ -397,12 +366,12 @@ where // Send the data if let Some(data) = update_data { self.send_commit(data.clone()); - self.insert_consensus(self.current_round, data.clone()); + self.insert_consensus(self.current_round, data); } } ///We have received a commit message - fn received_commit(&mut self, operator_id: OperatorId, consensus_data: ConsensusData) { + fn received_commit(&mut self, operator_id: OperatorId, consensus_data: ConsensusData) { // Check that this operator is in our committee if !self.check_committee(&operator_id) { warn!( @@ -419,7 +388,7 @@ where } // Ensure that this message is for the correct round - if !(self.current_round == consensus_data.round) { + if self.current_round != consensus_data.round { warn!( from = *operator_id, current_round = *self.current_round, @@ -446,7 +415,7 @@ where .commit_messages .entry(self.current_round) .or_default() - .entry(consensus_data.data) + .entry(consensus_data.data.data) .or_default() .insert(operator_id) { @@ -463,7 +432,7 @@ where if operators.len() >= self.config.quorum_size && matches!(self.state, InstanceState::Commit) { - self.send_completed(Completed::Success(data.data.clone())); + self.completed = Some(Completed::Success(data.clone())); self.state = InstanceState::Complete; } } @@ -475,7 +444,7 @@ where &mut self, operator_id: OperatorId, round: Round, - maybe_past_consensus_data: Option>, + maybe_past_consensus_data: Option>, ) { // Check that this operator is in our committee if !self.check_committee(&operator_id) { @@ -507,7 +476,7 @@ where } // Validate the data, if it exists - let maybe_past_consensus_data = match maybe_past_consensus_data { + /* let maybe_past_consensus_data = match maybe_past_consensus_data { Some(consensus_data) => { let Ok(consensus_data) = validate_consensus_data(consensus_data) else { warn!( @@ -520,7 +489,7 @@ where Some(consensus_data) } None => None, - }; + }; */ debug!(from = *operator_id, "ROUNDCHANGE received"); @@ -557,53 +526,59 @@ where } } + pub fn end_round(&mut self) { + debug!(round = *self.current_round, "Incrementing round"); + if *self.current_round > self.config.max_rounds() { + self.state = InstanceState::Complete; + self.completed = Some(Completed::TimedOut); + return; + } + self.send_round_change(self.current_round.next()); + // Start a new round + self.set_round(self.current_round.next()); + } + // Send message functions fn send_proposal(&mut self, data: ValidatedData) { - self.send_message(OutMessage::Propose(ConsensusData { - round: self.current_round, - data: data.data, - })); self.state = InstanceState::Prepare; debug!(?self.state, "State Changed"); - } - - fn send_prepare(&mut self, data: ValidatedData) { let consensus_data = ConsensusData { round: self.current_round, - data, + data: data.data, }; - self.send_message(OutMessage::Prepare(consensus_data.clone().into())); - // And store a prepare locally let operator_id = self.operator_id(); - self.prepare_messages - .entry(self.current_round) - .or_default() - .entry(consensus_data.data) - .or_default() - .insert(operator_id); + (self.send_message)(Message::Propose(operator_id, consensus_data.clone())); + self.received_propose(operator_id, consensus_data); + } + fn send_prepare(&mut self, data: D::Hash) { self.state = InstanceState::Prepare; debug!(?self.state, "State Changed"); + let consensus_data = ConsensusData { + round: self.current_round, + data, + }; + let operator_id = self.operator_id(); + (self.send_message)(Message::Prepare(operator_id, consensus_data.clone())); + self.received_prepare(operator_id, consensus_data); } - fn send_commit(&mut self, data: ValidatedData) { + fn send_commit(&mut self, data: D::Hash) { + self.state = InstanceState::Commit; + debug!(?self.state, "State changed"); let consensus_data = ConsensusData { round: self.current_round, data, }; - self.send_message(OutMessage::Commit(consensus_data.clone().into())); //And store a commit locally let operator_id = self.operator_id(); - self.commit_messages - .entry(self.current_round) - .or_default() - .entry(consensus_data.data) - .or_default() - .insert(operator_id); - self.state = InstanceState::Commit; - debug!(?self.state, "State changed", ); + (self.send_message)(Message::Commit(operator_id, consensus_data.clone())); + self.received_commit(operator_id, consensus_data) } fn send_round_change(&mut self, round: Round) { + self.state = InstanceState::SentRoundChange; + debug!(state = ?self.state, "New State"); + // Get the maximum round we have come to consensus on let best_consensus = self .past_consensus @@ -614,25 +589,28 @@ where data: data.clone(), }); - self.send_message(OutMessage::RoundChange( + let operator_id = self.operator_id(); + (self.send_message)(Message::RoundChange( + operator_id, round, - best_consensus.clone().map(|v| v.into()), + best_consensus.clone(), )); - // And store locally - let operator_id = self.operator_id(); - self.round_change_messages - .entry(round) - .or_default() - .insert(operator_id, best_consensus); - - self.state = InstanceState::SentRoundChange; - debug!(state = ?self.state, "New State"); + self.received_round_change(operator_id, round, best_consensus); } - fn send_completed(&mut self, completion_status: Completed) { - self.send_message(OutMessage::Completed(completion_status)); - self.state = InstanceState::Complete; - debug!(state = ?self.state, "New State"); + pub fn completed(&self) -> Option> { + self.completed + .clone() + .and_then(|completed| match completed { + Completed::TimedOut => Some(Completed::TimedOut), + Completed::Success(hash) => { + let data = self.data.get(&hash).cloned(); + if data.is_none() { + error!("could not find finished data"); + } + data.map(|data| Completed::Success(data.data)) + } + }) } } diff --git a/anchor/common/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs index 8239d7ecc..94edcb88a 100644 --- a/anchor/common/qbft/src/tests.rs +++ b/anchor/common/qbft/src/tests.rs @@ -1,11 +1,9 @@ //! A collection of unit tests for the QBFT Protocol. //! //! These test individual components and also provide full end-to-end tests of the entire protocol. - +/* todo rewrite use super::*; use crate::validation::{validate_data, ValidatedData}; -use futures::stream::select_all; -use futures::StreamExt; use std::cmp::Eq; use std::hash::Hash; use std::pin::Pin; @@ -367,8 +365,8 @@ where new_receivers } -#[tokio::test] -async fn test_basic_committee() { +#[test] +fn test_basic_committee() { // Construct and run a test committee let mut test_instance = TestQBFTCommitteeBuilder::default().run(21); @@ -376,3 +374,4 @@ async fn test_basic_committee() { // Wait until consensus is reached or all the instances have ended test_instance.wait_until_end().await; } +*/ \ No newline at end of file diff --git a/anchor/common/qbft/src/types.rs b/anchor/common/qbft/src/types.rs index ff7ab5778..d0950784f 100644 --- a/anchor/common/qbft/src/types.rs +++ b/anchor/common/qbft/src/types.rs @@ -4,6 +4,7 @@ use derive_more::{Add, Deref, From}; use std::cmp::Eq; use std::fmt::Debug; use std::hash::Hash; +use crate::Data; /// Generic LeaderFunction trait to allow for future implementations of the QBFT module pub trait LeaderFunction { @@ -50,20 +51,13 @@ impl Round { /// The operator that is participating in the consensus instance. #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, From, Deref)] -pub struct OperatorId(usize); +pub struct OperatorId(pub usize); /// The instance height behaves like an "ID" for the QBFT instance. It is used to uniquely identify /// different instances, that have the same operator id. -#[derive(Clone, Copy, Debug, Default)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, From, Deref)] pub struct InstanceHeight(usize); -impl Deref for InstanceHeight { - type Target = usize; - fn deref(&self) -> &Self::Target { - &self.0 - } -} - #[derive(Debug, Clone, Copy)] #[repr(u8)] pub enum InstanceState { @@ -82,31 +76,17 @@ pub enum InstanceState { /// Generic Data trait to allow for future implementations of the QBFT module // Messages that can be received from the message_in channel #[derive(Debug, Clone)] -pub enum InMessage { +pub enum Message { /// A PROPOSE message to be sent on the network. Propose(OperatorId, ConsensusData), /// A PREPARE message to be sent on the network. - Prepare(OperatorId, ConsensusData), + Prepare(OperatorId, ConsensusData), /// A commit message to be sent on the network. - Commit(OperatorId, ConsensusData), + Commit(OperatorId, ConsensusData), /// Round change message received from network - RoundChange(OperatorId, Round, Option>), + RoundChange(OperatorId, Round, Option>), } -/// Messages that may be sent to the message_out channel from the instance to the client processor -#[derive(Debug, Clone)] -pub enum OutMessage { - /// A PROPOSE message to be sent on the network. - Propose(ConsensusData), - /// A PREPARE message to be sent on the network. - Prepare(ConsensusData), - /// A commit message to be sent on the network. - Commit(ConsensusData), - /// The round has ended, send this message to the network to inform all participants. - RoundChange(Round, Option>), - /// The consensus instance has completed. - Completed(Completed), -} /// Type definitions for the allowable messages /// This holds the consensus data for a given round. #[derive(Debug, Clone)] diff --git a/anchor/common/ssv_types/Cargo.toml b/anchor/common/ssv_types/Cargo.toml index 5741ce1a7..4e3d17d17 100644 --- a/anchor/common/ssv_types/Cargo.toml +++ b/anchor/common/ssv_types/Cargo.toml @@ -8,4 +8,7 @@ authors = ["Sigma Prime "] base64 = { workspace = true } derive_more = { workspace = true } openssl = { workspace = true } +tree_hash = { workspace = true } +tree_hash_derive = { workspace = true } types = { workspace = true } +qbft = { workspace = true } diff --git a/anchor/common/ssv_types/src/lib.rs b/anchor/common/ssv_types/src/lib.rs index 6d25f44d2..0026b2edd 100644 --- a/anchor/common/ssv_types/src/lib.rs +++ b/anchor/common/ssv_types/src/lib.rs @@ -2,6 +2,8 @@ pub use cluster::{Cluster, ClusterId, ClusterMember, ValidatorIndex, ValidatorMe pub use operator::{Operator, OperatorId}; pub use share::Share; mod cluster; +pub mod message; +pub mod msgid; mod operator; mod share; mod util; diff --git a/anchor/common/ssv_types/src/message.rs b/anchor/common/ssv_types/src/message.rs new file mode 100644 index 000000000..4d7a1fb7f --- /dev/null +++ b/anchor/common/ssv_types/src/message.rs @@ -0,0 +1,187 @@ +use crate::msgid::MsgId; +use crate::{OperatorId, ValidatorIndex}; +use tree_hash::{PackedEncoding, TreeHash, TreeHashType}; +use tree_hash_derive::TreeHash; +use types::{AggregateAndProof, BeaconBlock, BlindedBeaconBlock, Checkpoint, CommitteeIndex, EthSpec, Hash256, PublicKeyBytes, Signature, Slot, SyncCommitteeContribution, VariableList}; +use types::typenum::U13; +// todo - dear reader, this mainly serves as plain translation of the types found in the go code +// there are a lot of byte[] there, and that got confusing, below should be more readable. +// it needs some work to actually serialize to the same stuff on wire, and I feel like we can name +// the fields better + +#[derive(Clone, Debug)] +pub struct SignedSsvMessage { + pub signatures: Vec<[u8; 256]>, + pub operator_ids: Vec, + pub ssv_message: SsvMessage, + pub full_data: Option>, +} + +#[derive(Clone, Debug)] +pub struct SsvMessage { + pub msg_type: MsgType, + pub msg_id: MsgId, + pub data: Data, +} + +#[derive(Clone, Debug)] +pub enum MsgType { + SsvConsensusMsgType, + SsvPartialSignatureMsgType, +} + +#[derive(Clone, Debug)] +pub enum Data { + QbftMessage(QbftMessage), + PartialSignatureMessage(PartialSignatureMessage), +} + +#[derive(Clone, Debug)] +pub struct QbftMessage { + pub qbft_message_type: QbftMessageType, + pub height: u64, + pub round: u64, + pub identifier: MsgId, + + pub root: Hash256, + pub round_change_justification: Vec>, // always without full_data + pub prepare_justification: Vec>, // always without full_data +} + +#[derive(Clone, Debug)] +pub enum QbftMessageType { + ProposalMsgType, + PrepareMsgType, + CommitMsgType, + RoundChangeMsgType, +} + +#[derive(Clone, Debug)] +pub struct PartialSignatureMessage { + pub partial_signature: Signature, + pub signing_root: Hash256, + pub signer: OperatorId, + pub validator_index: ValidatorIndex, +} + +#[derive(Clone, Debug)] +pub enum FullData { + ValidatorConsensusData(ValidatorConsensusData), + BeaconVote(BeaconVote), +} + +#[derive(Clone, Debug, TreeHash)] +pub struct ValidatorConsensusData { + pub duty: ValidatorDuty, + pub version: DataVersion, + pub data_ssz: Box>, +} + +impl qbft::Data for ValidatorConsensusData { + type Hash = Hash256; + + fn hash(&self) -> Self::Hash { + self.tree_hash_root() + } +} + +#[derive(Clone, Debug, TreeHash)] +pub struct ValidatorDuty { + pub r#type: BeaconRole, + pub pub_key: PublicKeyBytes, + pub slot: Slot, + pub validator_index: ValidatorIndex, + pub committee_index: CommitteeIndex, + pub committee_length: u64, + pub committees_at_slot: u64, + pub validator_committee_index: u64, + pub validator_sync_committee_indices: VariableList, +} + +#[derive(Clone, Debug)] +pub struct BeaconRole(u64); + +pub const BEACON_ROLE_ATTESTER: BeaconRole = BeaconRole(0); +pub const BEACON_ROLE_AGGREGATOR: BeaconRole = BeaconRole(1); +pub const BEACON_ROLE_PROPOSER: BeaconRole = BeaconRole(2); +pub const BEACON_ROLE_SYNC_COMMITTEE: BeaconRole = BeaconRole(3); +pub const BEACON_ROLE_SYNC_COMMITTEE_CONTRIBUTION: BeaconRole = BeaconRole(4); +pub const BEACON_ROLE_VALIDATOR_REGISTRATION: BeaconRole = BeaconRole(5); +pub const BEACON_ROLE_VOLUNTARY_EXIT: BeaconRole = BeaconRole(6); +pub const BEACON_ROLE_UNKNOWN: BeaconRole = BeaconRole(u64::MAX); + +impl TreeHash for BeaconRole { + fn tree_hash_type() -> TreeHashType { + u64::tree_hash_type() + } + + fn tree_hash_packed_encoding(&self) -> PackedEncoding { + self.0.tree_hash_packed_encoding() + } + + fn tree_hash_packing_factor() -> usize { + u64::tree_hash_packing_factor() + } + + fn tree_hash_root(&self) -> tree_hash::Hash256 { + self.0.tree_hash_root() + } +} + +#[derive(Clone, Debug)] +pub struct DataVersion(u64); + +pub const DATA_VERSION_UNKNOWN: DataVersion = DataVersion(0); +pub const DATA_VERSION_PHASE0: DataVersion = DataVersion(1); +pub const DATA_VERSION_ALTAIR: DataVersion = DataVersion(2); +pub const DATA_VERSION_BELLATRIX: DataVersion = DataVersion(3); +pub const DATA_VERSION_CAPELLA: DataVersion = DataVersion(4); +pub const DATA_VERSION_DENEB: DataVersion = DataVersion(5); + +impl TreeHash for DataVersion { + fn tree_hash_type() -> TreeHashType { + u64::tree_hash_type() + } + + fn tree_hash_packed_encoding(&self) -> PackedEncoding { + self.0.tree_hash_packed_encoding() + } + + fn tree_hash_packing_factor() -> usize { + u64::tree_hash_packing_factor() + } + + fn tree_hash_root(&self) -> tree_hash::Hash256 { + self.0.tree_hash_root() + } +} + +#[derive(Clone, Debug, TreeHash)] +#[tree_hash(enum_behaviour = "transparent")] +pub enum DataSsz { + AggregateAndProof(AggregateAndProof), + BlindedBeaconBlock(BlindedBeaconBlock), + BeaconBlock(BeaconBlock), + Contributions(VariableList, U13>), +} + +#[derive(Clone, Debug, TreeHash)] +pub struct Contribution { + pub selection_proof_sig: Signature, + pub contribution: SyncCommitteeContribution, +} + +#[derive(Clone, Debug, TreeHash)] +pub struct BeaconVote { + pub block_root: Hash256, + pub source: Checkpoint, + pub target: Checkpoint, +} + +impl qbft::Data for BeaconVote { + type Hash = Hash256; + + fn hash(&self) -> Self::Hash { + self.tree_hash_root() + } +} diff --git a/anchor/common/ssv_types/src/msgid.rs b/anchor/common/ssv_types/src/msgid.rs new file mode 100644 index 000000000..5a9e3c83f --- /dev/null +++ b/anchor/common/ssv_types/src/msgid.rs @@ -0,0 +1,47 @@ +// todo probably move that to its own thing +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub struct Domain([u8; 4]); +pub const MAINNET_DOMAIN: Domain = Domain([0, 0, 0, 1]); +pub const HOLESKY_DOMAIN: Domain = Domain([0, 0, 5, 2]); + +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub enum Role { + Committee, + Aggregator, + Proposer, + SyncCommittee, +} + +impl Role { + fn into_message_id_bytes(self) -> [u8; 4] { + match self { + Role::Committee => [0, 0, 0, 0], + Role::Aggregator => [1, 0, 0, 0], + Role::Proposer => [2, 0, 0, 0], + Role::SyncCommittee => [3, 0, 0, 0], + } + } +} + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub enum Executor { + Committee([u8; 32]), + Validator([u8; 48]), +} + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct MsgId([u8; 56]); + +impl MsgId { + pub fn new(domain: &Domain, role: Role, duty_executor: &Executor) -> Self { + let mut id = [0; 56]; + id[0..4].copy_from_slice(&domain.0); + id[4..8].copy_from_slice(&role.into_message_id_bytes()); + match duty_executor { + Executor::Committee(slice) => id[24..].copy_from_slice(slice), + Executor::Validator(slice) => id[8..].copy_from_slice(slice), + } + + MsgId(id) + } +} diff --git a/anchor/network/Cargo.toml b/anchor/network/Cargo.toml index b3b994684..428d343f0 100644 --- a/anchor/network/Cargo.toml +++ b/anchor/network/Cargo.toml @@ -11,9 +11,11 @@ futures = { workspace = true } libp2p = { version = "0.54", default-features = false, features = ["identify", "yamux", "noise", "secp256k1", "tcp", "tokio", "macros", "gossipsub", "quic", "ping"] } lighthouse_network = { workspace = true } serde = { workspace = true } +ssv_types = { workspace = true } task_executor = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } +types = { workspace = true } version = { workspace = true } [dev-dependencies] diff --git a/anchor/network/src/lib.rs b/anchor/network/src/lib.rs index 161c09600..d3dd8673b 100644 --- a/anchor/network/src/lib.rs +++ b/anchor/network/src/lib.rs @@ -5,7 +5,7 @@ mod config; mod keypair_utils; mod network; mod transport; -mod types; +pub mod types; pub use config::Config; pub use lighthouse_network::{ListenAddr, ListenAddress}; diff --git a/anchor/qbft_manager/Cargo.toml b/anchor/qbft_manager/Cargo.toml new file mode 100644 index 000000000..6a0ab0783 --- /dev/null +++ b/anchor/qbft_manager/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "qbft_manager" +version = "0.1.0" +authors = ["Sigma Prime { + pub kind: QbftMessageKind, + pub drop_on_finish: DropOnFinish, +} + +#[derive(Debug)] +pub enum QbftMessageKind { + Initialize { + initial: D, // deja vu - i've just been in this place before + config: qbft::Config, + on_completed: oneshot::Sender>, + }, + NetworkMessage(NetworkMessage), +} + +type Qbft = qbft::Qbft; + +type Map = DashMap>>; + +pub struct QbftManager { + processor: Senders, + operator_id: QbftOperatorId, + slot_clock: T, // TODO: I added this for some reason - why? + validator_consensus_data_instances: Map>, + beacon_vote_instances: Map, +} + +impl QbftManager { + pub fn new(processor: Senders, operator_id: OperatorId, slot_clock: T) -> Self { + QbftManager { + processor, + operator_id: QbftOperatorId(operator_id.0 as usize), + slot_clock, + validator_consensus_data_instances: DashMap::new(), + beacon_vote_instances: DashMap::new(), + } + } + + pub async fn decide_instance>( + &self, + id: D::Id, + initial: D, + committee: &Cluster, + ) -> Result, QbftError> { + let (result_sender, result_receiver) = oneshot::channel(); + let mut config = ConfigBuilder::default(); + config.operator_id(self.operator_id) + .committee_size(committee.cluster_members.len()) + .quorum_size(committee.cluster_members.len() - committee.faulty as usize); + let config = initial.config(&mut config, &id)?; + let sender = D::get_or_spawn_instance(self, id); + self.processor.urgent_consensus.send_immediate( + move |drop_on_finish: DropOnFinish| { + let _ = sender.send(QbftMessage { + kind: QbftMessageKind::Initialize { + initial, + config, + on_completed: result_sender, + }, + drop_on_finish, + }); + }, + QBFT_MESSAGE_NAME, + )?; + Ok(result_receiver.await?) + } + + pub fn receive_data>( + &self, + id: D::Id, + data: NetworkMessage, + ) -> Result<(), QbftError> { + let sender = D::get_or_spawn_instance(self, id); + self.processor.urgent_consensus.send_immediate( + move |drop_on_finish: DropOnFinish| { + let _ = sender.send(QbftMessage { + kind: QbftMessageKind::NetworkMessage(data), + drop_on_finish, + }); + }, + QBFT_MESSAGE_NAME, + )?; + Ok(()) + } +} + +pub trait QbftDecidable: + qbft::Data + Send + 'static +{ + type Id: Hash + Eq + Send; + + fn get_map(manager: &QbftManager) -> &Map; + + fn get_or_spawn_instance( + manager: &QbftManager, + id: Self::Id, + ) -> UnboundedSender> { + let map = Self::get_map(manager); + let ret = match map.entry(id) { + dashmap::Entry::Occupied(entry) => entry.get().clone(), + dashmap::Entry::Vacant(entry) => { + let (tx, rx) = mpsc::unbounded_channel(); + let tx = entry.insert(tx); + let _ = manager + .processor + .permitless + .send_async(Box::pin(qbft_instance(rx)), QBFT_INSTANCE_NAME); + tx.clone() + } + }; + ret + } + fn config( + &self, + builder: &mut ConfigBuilder, + id: &Self::Id, + ) -> Result, ConfigBuilderError>; +} + +impl QbftDecidable for ValidatorConsensusData { + type Id = ValidatorInstanceId; + fn get_map(manager: &QbftManager) -> &Map { + &manager.validator_consensus_data_instances + } + + fn config( + &self, + builder: &mut ConfigBuilder, + id: &Self::Id, + ) -> Result, ConfigBuilderError> { + builder.instance_height(id.instance_height).build() + } +} + +impl QbftDecidable for BeaconVote { + type Id = CommitteeInstanceId; + fn get_map(manager: &QbftManager) -> &Map { + &manager.beacon_vote_instances + } + + fn config( + &self, + builder: &mut ConfigBuilder, + id: &Self::Id, + ) -> Result, ConfigBuilderError> { + builder.instance_height(id.instance_height).build() + } +} + +enum QbftInstance)> { + Uninitialized { + // todo: proooobably limit this + message_buffer: Vec>, + }, + Initialized { + qbft: Box>, + round_end: Interval, + on_completed: oneshot::Sender>, + }, +} + +async fn qbft_instance(mut rx: UnboundedReceiver>) { + let mut instance = QbftInstance::Uninitialized { + message_buffer: Vec::new(), + }; + + loop { + let message = match &mut instance { + QbftInstance::Uninitialized { .. } => rx.recv().await, + QbftInstance::Initialized { + qbft: instance, + round_end, + .. + } => { + select! { + message = rx.recv() => message, + _ = round_end.tick() => { + instance.end_round(); + continue; + } + } + } + }; + + let Some(message) = message else { + break; + }; + + match message.kind { + QbftMessageKind::Initialize { + initial, + config, + on_completed, + } => { + instance = match instance { + QbftInstance::Uninitialized { message_buffer } => { + // todo: actually send messages somewhere + let mut instance = Box::new(Qbft::new( + config, + qbft::ValidatedData { data: initial }, + |_| {}, + )); + for message in message_buffer { + instance.receive(message); + } + QbftInstance::Initialized { + round_end: tokio::time::interval(instance.config().round_time), + qbft: instance, + on_completed, + } + } + instance @ QbftInstance::Initialized { .. } => { + warn!("got double initialization of qbft instance, ignoring"); + instance + } + } + } + QbftMessageKind::NetworkMessage(message) => match &mut instance { + QbftInstance::Initialized { qbft: instance, .. } => { + instance.receive(message); + } + QbftInstance::Uninitialized { message_buffer } => { + message_buffer.push(message); + } + }, + } + + if let QbftInstance::Initialized { + qbft, + round_end, + on_completed, + } = instance + { + if let Some(completed) = qbft.completed() { + if on_completed.send(completed).is_err() { + error!("could not send qbft result"); + } + break; + } else { + instance = QbftInstance::Initialized { + qbft, + round_end, + on_completed, + } + } + } + } +} + +#[derive(Debug)] +pub enum QbftError { + QueueClosedError, + QueueFullError, + ConfigBuilderError(ConfigBuilderError), +} + +impl From> for QbftError { + fn from(value: TrySendError) -> Self { + match value { + TrySendError::Full(_) => QbftError::QueueFullError, + TrySendError::Closed(_) => QbftError::QueueClosedError, + } + } +} + +impl From for QbftError { + fn from(_: RecvError) -> Self { + QbftError::QueueClosedError + } +} + +impl From for QbftError { + fn from(value: ConfigBuilderError) -> Self { + QbftError::ConfigBuilderError(value) + } +} From 09136e248574d391cbfcec7253c3626930aeb48e Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 2 Jan 2025 16:12:43 +0100 Subject: [PATCH 11/21] cargo fmt --- anchor/common/qbft/src/tests.rs | 2 +- anchor/common/qbft/src/types.rs | 2 +- anchor/common/ssv_types/src/message.rs | 5 ++++- anchor/qbft_manager/src/lib.rs | 8 ++++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/anchor/common/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs index 94edcb88a..93eaa1f88 100644 --- a/anchor/common/qbft/src/tests.rs +++ b/anchor/common/qbft/src/tests.rs @@ -374,4 +374,4 @@ fn test_basic_committee() { // Wait until consensus is reached or all the instances have ended test_instance.wait_until_end().await; } -*/ \ No newline at end of file +*/ diff --git a/anchor/common/qbft/src/types.rs b/anchor/common/qbft/src/types.rs index d0950784f..b9d387e53 100644 --- a/anchor/common/qbft/src/types.rs +++ b/anchor/common/qbft/src/types.rs @@ -1,10 +1,10 @@ //! A collection of types used by the QBFT modules use crate::validation::ValidatedData; +use crate::Data; use derive_more::{Add, Deref, From}; use std::cmp::Eq; use std::fmt::Debug; use std::hash::Hash; -use crate::Data; /// Generic LeaderFunction trait to allow for future implementations of the QBFT module pub trait LeaderFunction { diff --git a/anchor/common/ssv_types/src/message.rs b/anchor/common/ssv_types/src/message.rs index 4d7a1fb7f..c47052b71 100644 --- a/anchor/common/ssv_types/src/message.rs +++ b/anchor/common/ssv_types/src/message.rs @@ -2,8 +2,11 @@ use crate::msgid::MsgId; use crate::{OperatorId, ValidatorIndex}; use tree_hash::{PackedEncoding, TreeHash, TreeHashType}; use tree_hash_derive::TreeHash; -use types::{AggregateAndProof, BeaconBlock, BlindedBeaconBlock, Checkpoint, CommitteeIndex, EthSpec, Hash256, PublicKeyBytes, Signature, Slot, SyncCommitteeContribution, VariableList}; use types::typenum::U13; +use types::{ + AggregateAndProof, BeaconBlock, BlindedBeaconBlock, Checkpoint, CommitteeIndex, EthSpec, + Hash256, PublicKeyBytes, Signature, Slot, SyncCommitteeContribution, VariableList, +}; // todo - dear reader, this mainly serves as plain translation of the types found in the go code // there are a lot of byte[] there, and that got confusing, below should be more readable. // it needs some work to actually serialize to the same stuff on wire, and I feel like we can name diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 6411dc185..620ddd796 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -1,6 +1,9 @@ use dashmap::DashMap; use processor::{DropOnFinish, Senders, WorkItem}; -use qbft::{Completed, Config, ConfigBuilder, ConfigBuilderError, DefaultLeaderFunction, InstanceHeight, Message as NetworkMessage, OperatorId as QbftOperatorId}; +use qbft::{ + Completed, Config, ConfigBuilder, ConfigBuilderError, DefaultLeaderFunction, InstanceHeight, + Message as NetworkMessage, OperatorId as QbftOperatorId, +}; use slot_clock::SlotClock; use ssv_types::message::{BeaconVote, ValidatorConsensusData}; use ssv_types::{Cluster, ClusterId, OperatorId}; @@ -77,7 +80,8 @@ impl QbftManager { ) -> Result, QbftError> { let (result_sender, result_receiver) = oneshot::channel(); let mut config = ConfigBuilder::default(); - config.operator_id(self.operator_id) + config + .operator_id(self.operator_id) .committee_size(committee.cluster_members.len()) .quorum_size(committee.cluster_members.len() - committee.faulty as usize); let config = initial.config(&mut config, &id)?; From 786f3fc1fa620fbe96bea9e4dfb30a48111f486a Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 3 Jan 2025 10:09:09 +0100 Subject: [PATCH 12/21] clean up --- anchor/qbft_manager/src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 620ddd796..0dace58a4 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -1,7 +1,7 @@ use dashmap::DashMap; use processor::{DropOnFinish, Senders, WorkItem}; use qbft::{ - Completed, Config, ConfigBuilder, ConfigBuilderError, DefaultLeaderFunction, InstanceHeight, + Completed, ConfigBuilder, ConfigBuilderError, DefaultLeaderFunction, InstanceHeight, Message as NetworkMessage, OperatorId as QbftOperatorId, }; use slot_clock::SlotClock; @@ -23,14 +23,14 @@ const QBFT_MESSAGE_NAME: &str = "qbft_message"; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct CommitteeInstanceId { - committee: ClusterId, - instance_height: InstanceHeight, + pub committee: ClusterId, + pub instance_height: InstanceHeight, } #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct ValidatorInstanceId { - validator: PublicKeyBytes, - instance_height: InstanceHeight, + pub validator: PublicKeyBytes, + pub instance_height: InstanceHeight, } #[derive(Debug)] @@ -42,7 +42,7 @@ pub struct QbftMessage { #[derive(Debug)] pub enum QbftMessageKind { Initialize { - initial: D, // deja vu - i've just been in this place before + initial: D, config: qbft::Config, on_completed: oneshot::Sender>, }, @@ -56,7 +56,7 @@ type Map = DashMap>>; pub struct QbftManager { processor: Senders, operator_id: QbftOperatorId, - slot_clock: T, // TODO: I added this for some reason - why? + _slot_clock: T, // TODO: use this. e.g. properly aligning round intervals with slot etc. validator_consensus_data_instances: Map>, beacon_vote_instances: Map, } @@ -66,7 +66,7 @@ impl QbftManager { QbftManager { processor, operator_id: QbftOperatorId(operator_id.0 as usize), - slot_clock, + _slot_clock: slot_clock, validator_consensus_data_instances: DashMap::new(), beacon_vote_instances: DashMap::new(), } @@ -179,7 +179,7 @@ impl QbftDecidable for BeaconVote { &self, builder: &mut ConfigBuilder, id: &Self::Id, - ) -> Result, ConfigBuilderError> { + ) -> Result, ConfigBuilderError> { builder.instance_height(id.instance_height).build() } } From 308740a88a3ddd0329bbfda99d536ffcfc9264df Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 3 Jan 2025 10:56:36 +0100 Subject: [PATCH 13/21] reimplement test and fix issues --- Cargo.lock | 1 - anchor/common/qbft/src/lib.rs | 6 +- anchor/common/qbft/src/tests.rs | 323 ++++------------------------- anchor/common/ssv_types/Cargo.toml | 2 +- anchor/network/Cargo.toml | 1 - anchor/qbft_manager/src/lib.rs | 1 + 6 files changed, 50 insertions(+), 284 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d29e76a76..3d5910d43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5283,7 +5283,6 @@ dependencies = [ "libp2p", "lighthouse_network 0.2.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", "serde", - "ssv_types", "task_executor 0.1.0 (git+https://github.com/sigp/lighthouse?branch=unstable)", "tokio", "tracing", diff --git a/anchor/common/qbft/src/lib.rs b/anchor/common/qbft/src/lib.rs index 6c6f1bc82..2df84ce9a 100644 --- a/anchor/common/qbft/src/lib.rs +++ b/anchor/common/qbft/src/lib.rs @@ -69,7 +69,7 @@ impl Qbft where F: LeaderFunction + Clone, D: Data, - S: Fn(Message), + S: FnMut(Message), { pub fn new(config: Config, start_data: ValidatedData, send_message: S) -> Self { let estimated_map_size = config.committee_size; @@ -83,7 +83,7 @@ where instance_height: config.instance_height, config, start_data: start_data_hash, - data: HashMap::with_capacity(2), + data, past_consensus: HashMap::with_capacity(2), prepare_messages: HashMap::with_capacity(estimated_map_size), commit_messages: HashMap::with_capacity(estimated_map_size), @@ -177,7 +177,7 @@ where } // Handles the beginning of a round. - fn start_round(&mut self) { + pub fn start_round(&mut self) { debug!(round = *self.current_round, "Starting new round",); // Remove round change messages that would be for previous rounds diff --git a/anchor/common/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs index 93eaa1f88..d651c6ffd 100644 --- a/anchor/common/qbft/src/tests.rs +++ b/anchor/common/qbft/src/tests.rs @@ -1,14 +1,12 @@ //! A collection of unit tests for the QBFT Protocol. //! //! These test individual components and also provide full end-to-end tests of the entire protocol. -/* todo rewrite + +use std::cell::RefCell; use super::*; use crate::validation::{validate_data, ValidatedData}; -use std::cmp::Eq; -use std::hash::Hash; -use std::pin::Pin; -use std::task::{Context, Poll}; -use tracing::debug; +use std::collections::VecDeque; +use std::rc::Rc; use tracing_subscriber::filter::EnvFilter; use types::DefaultLeaderFunction; @@ -21,11 +19,6 @@ const ENABLE_TEST_LOGGING: bool = true; struct TestQBFTCommitteeBuilder { /// The configuration to use for all the instances. config: Config, - /// Whether we should send back dummy validation input to each instance when it requests it. - emulate_client_processor: bool, - /// Whether to emulate a broadcast network and have all network-related messages be relayed to - /// teach instance. - emulate_broadcast_network: bool, } impl Default for TestQBFTCommitteeBuilder { @@ -40,8 +33,6 @@ impl Default for TestQBFTCommitteeBuilder { TestQBFTCommitteeBuilder { config, - emulate_client_processor: true, - emulate_broadcast_network: true, } } } @@ -54,17 +45,6 @@ impl TestQBFTCommitteeBuilder { self } - /// Set whether to emulate validation or not - pub fn emulate_validation(mut self, emulate: bool) -> Self { - self.emulate_client_processor = emulate; - self - } - /// Set whether to emulate network or not - pub fn emulate_broadcast_network(mut self, emulate: bool) -> Self { - self.emulate_broadcast_network = emulate; - self - } - /// Sets the config for all instances to run pub fn set_config(mut self, config: Config) -> Self { self.config = config; @@ -73,9 +53,9 @@ impl TestQBFTCommitteeBuilder { /// Consumes self and runs a test scenario. This returns a [`TestQBFTCommittee`] which /// represents a running quorum. - pub fn run(self, data: D) -> TestQBFTCommittee + pub fn run(self, data: D) -> TestQBFTCommittee)> where - D: Debug + Default + Clone + Send + Sync + 'static + Eq + Hash, + D: Default + Data, { if ENABLE_TEST_LOGGING { let env_filter = EnvFilter::new("debug"); @@ -88,290 +68,77 @@ impl TestQBFTCommitteeBuilder { // Validate the data let validated_data = validate_data(data).unwrap(); - let (senders, mut receivers) = construct_and_run_committee(self.config, validated_data); - - if self.emulate_broadcast_network { - receivers = emulate_broadcast_network(receivers, senders.clone()); - } - - TestQBFTCommittee { senders, receivers } + construct_and_run_committee(self.config, validated_data) } } /// A testing structure representing a committee of running instances -#[allow(dead_code)] -struct TestQBFTCommittee { - /// Channels to receive all the messages coming out of all the running qbft instances - receivers: HashMap>>, - /// Channels to send messages to all the running qbft instances - senders: HashMap>>, -} - -impl TestQBFTCommittee -where - D: Debug + Default + Clone + Send + Sync + 'static + Eq + Hash, -{ - /// Waits until all the instances have ended - pub async fn wait_until_end(&mut self) { - debug!("Waiting for completion"); - // Loops through and waits for messages from all channels until there is nothing left. - - // Cheeky Hack, might need to change in the future - let receivers = std::mem::take(&mut self.receivers); - - let mut all_recievers = - select_all( - receivers - .into_iter() - .map(|(operator_id, receiver)| InstanceStream:: { - operator_id, - receiver, - }), - ); - while all_recievers.next().await.is_some() {} - debug!("Completed"); - } - - /// Sends a message to an instance. Specify its index (or id) and the message you want to send. - #[allow(dead_code)] - pub fn send_message(&mut self, operator_id: &OperatorId, message: InMessage) { - let _ = self.senders.get(operator_id).unwrap().send(message); - } -} - -// Helper type to handle Streams with instance ids. -// -// I wanted a Stream that returns the instance id as well as the message when it becomes ready. -// TODO: Can probably group this thing via a MAP in a stream function. -struct InstanceStream { - operator_id: OperatorId, - receiver: UnboundedReceiver>, -} - -impl futures::Stream for InstanceStream -where - D: Debug + Default + Clone + Eq + Hash, -{ - type Item = (OperatorId, OutMessage); - - // Required method - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - match self.receiver.poll_recv(cx) { - Poll::Ready(Some(message)) => Poll::Ready(Some((self.operator_id, message))), - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => Poll::Pending, - } - } +#[allow(clippy::type_complexity)] +struct TestQBFTCommittee)> { + msg_queue: Rc)>>>, + instances: HashMap>, } /// Constructs and runs committee of QBFT Instances /// /// This will create instances and spawn them in a task and return the sender/receiver channels for /// all created instances. -#[allow(clippy::type_complexity)] -fn construct_and_run_committee( +fn construct_and_run_committee( mut config: Config, validated_data: ValidatedData, -) -> ( - HashMap>>, - HashMap>>, -) { +) -> TestQBFTCommittee)> { // The ID of a committee is just an integer in [0,committee_size) - // A collection of channels to send messages to each instance. - let mut senders = HashMap::with_capacity(config.committee_size); - // A collection of channels to receive messages from each instances. - // We will redirect messages to each instance, simulating a broadcast network. - let mut receivers = HashMap::with_capacity(config.committee_size); + let msg_queue = Rc::new(RefCell::new(VecDeque::new())); + let mut instances = HashMap::with_capacity(config.committee_size); for id in 0..config.committee_size { + let msg_queue = Rc::clone(&msg_queue); + let id = OperatorId::from(id); // Creates a new instance - config.operator_id = OperatorId::from(id); - let (sender, receiver, instance) = Qbft::new(config.clone(), validated_data.clone()); - senders.insert(config.operator_id, sender); - receivers.insert(config.operator_id, receiver); - - // spawn the instance - debug!(id, "Starting instance"); - tokio::spawn(instance.start_instance()); + config.operator_id = id; + let mut instance = Qbft::new(config.clone(), validated_data.clone(), move |message| msg_queue.borrow_mut().push_back((id, message))); + instance.start_round(); + instances.insert(id, instance); } - (senders, receivers) + TestQBFTCommittee { + msg_queue, instances + } } -/// This function takes the senders and receivers and will duplicate messages from all instances -/// and send those messages to all other instances. -/// This simulates a kind of broadcast network. -/// Specifically it handles: -/// ProposeMessage -/// PrepareMessage -/// CommitMessage -/// RoundChange -/// And forwards the others untouched. -fn emulate_broadcast_network( - receivers: HashMap>>, - senders: HashMap>>, -) -> HashMap>> { - debug!("Emulating a gossip network"); - let emulate_gossip_network_fn = - |message: OutMessage, - operator_id: &OperatorId, - senders: &mut HashMap>>, - new_senders: &mut HashMap>>| { - // Duplicate the message to the new channel - let _ = new_senders.get(operator_id).unwrap().send(message.clone()); - - match message { - OutMessage::Propose(consensus_data) => { - // Send the message to all other nodes - senders - .iter_mut() - .for_each(|(current_operator_id, sender)| { - if current_operator_id != operator_id { - let _ = sender - .send(InMessage::Propose(*operator_id, consensus_data.clone())); - } - }); - } - OutMessage::Prepare(prepare_message) => { - senders - .iter_mut() - .for_each(|(current_operator_id, sender)| { - if current_operator_id != operator_id { - let _ = sender.send(InMessage::Prepare( - *operator_id, - prepare_message.clone(), - )); - } - }); - } - OutMessage::Commit(commit_message) => { - // Ignoring commits in round 2 for testing - senders - .iter_mut() - .for_each(|(current_operator_id, sender)| { - if current_operator_id != operator_id { - let _ = sender - .send(InMessage::Commit(*operator_id, commit_message.clone())); - } - }) - } - OutMessage::RoundChange(round, optional_data) => { - senders - .iter_mut() - .for_each(|(current_operator_id, sender)| { - if current_operator_id != operator_id { - let _ = sender.send(InMessage::RoundChange( - *operator_id, - round, - optional_data.clone(), - )); - } - }); - } - _ => {} // We don't interact with any of the others +impl)> TestQBFTCommittee { + fn wait_until_end(mut self) { + loop { + let msg = self.msg_queue.borrow_mut().pop_front(); + let Some((sender, msg)) = msg else { + // we are done! + return; }; - }; - - generically_handle_messages(receivers, senders, emulate_gossip_network_fn) -} - -/// This is a base function to prevent duplication of code. It's used by `emulate_gossip_network` -/// and `handle_all_out_messages`. It groups the logic of taking the channels, cloning them and -/// returning new channels. Leaving the logic of message handling as a parameter. -fn generically_handle_messages( - receivers: HashMap>>, - mut senders: HashMap>>, - // This is a function that takes the outbound message from the instances and the old inbound - // sending channel and the new inbound sending channel. Given the outbound message, we can send a - // response to the old inbound sender, and potentially duplicate the message to the new receiver - // via the second Sender. - mut message_handling: T, -) -> HashMap>> -where - T: FnMut( - OutMessage, - &OperatorId, - &mut HashMap>>, - &mut HashMap>>, - ) - + 'static - + Send - + Sync, -{ - // Build a new set of channels to replace the ones we have taken ownership of. We will just - // forward network messages to these channels - let mut new_receivers = HashMap::with_capacity(receivers.len()); - let mut new_senders = HashMap::with_capacity(senders.len()); - - // Populate the new channels. - for operator_id in receivers.keys() { - let (new_sender, new_receiver) = tokio::sync::mpsc::unbounded_channel::>(); - new_receivers.insert(*operator_id, new_receiver); - new_senders.insert(*operator_id, new_sender); + for instance in self.instances.iter_mut().filter_map(|(id, instance)| (id.0 != sender.0).then_some(instance)) { + instance.receive(msg.clone()); + } + } } +} - // Run a task to handle all the out messages - - tokio::spawn(async move { - // First need to group all the receive channels into a single Stream that we can await. - // We will use a FuturesUnordered which groups a collection of futures. - // We also need to know the number of which receiver sent us the message so we know - // which sender to forward to. For this reason we make a little intermediate type with the - // index. - - let mut grouped_receivers = select_all(receivers.into_iter().map( - |(operator_id, receiver)| InstanceStream { - operator_id, - receiver, - }, - )); +#[derive(Debug, Copy, Clone, Default)] +struct TestData(usize); - while let Some((operator_id, out_message)) = grouped_receivers.next().await { - /* - debug!( - ?out_message, - operator = *operator_id, - "Handling message from instance" - ); - */ - // Custom handling of the out message - message_handling(out_message, &operator_id, &mut senders, &mut new_senders); - // Add back a new future to await for the next message - } +impl Data for TestData { + type Hash = usize; - /* loop { - match grouped_receivers.next().await { - Some((index, out_message)) => { - debug!( - ?out_message, - "Instance" = index, - "Handling message from instance" - ); - // Custom handling of the out message - message_handling(out_message, index, &mut senders, &mut new_senders); - // Add back a new future to await for the next message - } - None => { - // At least one instance has finished. - break; - } - } - }*/ - debug!("Task shutdown"); - }); - - // Return the channels that will just handle network messages - new_receivers + fn hash(&self) -> Self::Hash { + self.0 + } } #[test] fn test_basic_committee() { // Construct and run a test committee - let mut test_instance = TestQBFTCommitteeBuilder::default().run(21); + let test_instance = TestQBFTCommitteeBuilder::default().run(TestData(21)); // Wait until consensus is reached or all the instances have ended - test_instance.wait_until_end().await; + test_instance.wait_until_end(); } -*/ diff --git a/anchor/common/ssv_types/Cargo.toml b/anchor/common/ssv_types/Cargo.toml index 4e3d17d17..7c7682ef2 100644 --- a/anchor/common/ssv_types/Cargo.toml +++ b/anchor/common/ssv_types/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Sigma Prime "] base64 = { workspace = true } derive_more = { workspace = true } openssl = { workspace = true } +qbft = { workspace = true } tree_hash = { workspace = true } tree_hash_derive = { workspace = true } types = { workspace = true } -qbft = { workspace = true } diff --git a/anchor/network/Cargo.toml b/anchor/network/Cargo.toml index 428d343f0..0d6a9747b 100644 --- a/anchor/network/Cargo.toml +++ b/anchor/network/Cargo.toml @@ -11,7 +11,6 @@ futures = { workspace = true } libp2p = { version = "0.54", default-features = false, features = ["identify", "yamux", "noise", "secp256k1", "tcp", "tokio", "macros", "gossipsub", "quic", "ping"] } lighthouse_network = { workspace = true } serde = { workspace = true } -ssv_types = { workspace = true } task_executor = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 0dace58a4..2a3707b7f 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -237,6 +237,7 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) qbft::ValidatedData { data: initial }, |_| {}, )); + instance.start_round(); for message in message_buffer { instance.receive(message); } From 3a6ccb9d4a595c9f6adf88ce1985dc8b88595434 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Fri, 3 Jan 2025 17:48:02 +0100 Subject: [PATCH 14/21] implement attestation and block signing --- Cargo.lock | 97 ++++----- Cargo.toml | 2 +- anchor/client/Cargo.toml | 1 + anchor/client/src/lib.rs | 33 +-- anchor/validator_store/Cargo.toml | 3 + anchor/validator_store/src/lib.rs | 330 +++++++++++++++++++++++++----- 6 files changed, 358 insertions(+), 108 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cf9711508..cfba404e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -177,8 +177,11 @@ version = "0.1.0" dependencies = [ "dashmap", "processor", + "qbft", + "qbft_manager", "safe_arith", "signature_collector", + "slot_clock", "ssv_types", "tracing", "types", @@ -503,9 +506,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "1b1244b10dcd56c92219da4e14caa97e312079e185f04ba3eea25061561dc0a0" dependencies = [ "proc-macro2", "quote", @@ -662,7 +665,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon_node_fallback" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "eth2", "futures", @@ -769,7 +772,7 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "arbitrary", @@ -886,9 +889,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "jobserver", "libc", @@ -1027,7 +1030,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "clap", @@ -1059,6 +1062,7 @@ dependencies = [ "network", "parking_lot", "processor", + "qbft_manager", "sensitive_url", "serde", "signature_collector", @@ -1093,7 +1097,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "itertools 0.10.5", ] @@ -1101,7 +1105,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "quote", "syn 1.0.109", @@ -1639,7 +1643,7 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "clap", "clap_utils", @@ -1891,7 +1895,7 @@ dependencies = [ [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "derivative", "eth2_keystore", @@ -1921,7 +1925,7 @@ dependencies = [ [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "paste", "types", @@ -1930,7 +1934,7 @@ dependencies = [ [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bls", "ethereum_hashing", @@ -1943,7 +1947,7 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bls", "num-bigint-dig", @@ -1955,7 +1959,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "aes 0.7.5", "bls", @@ -1977,7 +1981,7 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bytes", "discv5", @@ -2166,7 +2170,7 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "winapi", "windows-acl", @@ -2187,7 +2191,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "safe_arith", @@ -2452,7 +2456,7 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "async-channel", "asynchronous-codec", @@ -2481,7 +2485,7 @@ dependencies = [ [[package]] name = "graffiti_file" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bls", "serde", @@ -3174,7 +3178,7 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bytes", ] @@ -3322,7 +3326,7 @@ dependencies = [ [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "arbitrary", "c-kzg", @@ -3917,7 +3921,7 @@ dependencies = [ [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -3966,7 +3970,7 @@ dependencies = [ [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "git-version", "target_info", @@ -4015,7 +4019,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "chrono", "metrics", @@ -4055,7 +4059,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "fnv", ] @@ -4120,7 +4124,7 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -4154,7 +4158,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "prometheus", ] @@ -4852,7 +4856,7 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "reqwest", "sensitive_url", @@ -5007,7 +5011,7 @@ dependencies = [ [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", @@ -5716,7 +5720,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" [[package]] name = "salsa20" @@ -5837,7 +5841,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "serde", "url", @@ -6034,7 +6038,7 @@ dependencies = [ [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -6153,7 +6157,7 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "metrics", "parking_lot", @@ -6264,7 +6268,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "state_processing" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "arbitrary", "bls", @@ -6296,7 +6300,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "bls", "db-key", @@ -6379,7 +6383,7 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -6494,7 +6498,7 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "async-channel", "futures", @@ -6508,12 +6512,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", "once_cell", "rustix 0.38.42", "windows-sys 0.59.0", @@ -6543,7 +6548,7 @@ dependencies = [ [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "quote", "syn 1.0.109", @@ -6946,7 +6951,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7109,7 +7114,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "lru_cache", "parking_lot", @@ -7157,7 +7162,7 @@ dependencies = [ [[package]] name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "metrics", ] @@ -7165,7 +7170,7 @@ dependencies = [ [[package]] name = "validator_services" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "beacon_node_fallback", "bls", @@ -7188,7 +7193,7 @@ dependencies = [ [[package]] name = "validator_store" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#ebfe234d364f6a6fb9eef98664658f5f08cad4d7" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" dependencies = [ "slashing_protection", "types", diff --git a/Cargo.toml b/Cargo.toml index a381706bd..f1a0ade97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ processor = { path = "anchor/processor" } anchor_validator_store = { path = "anchor/validator_store" } ssv_types = { path = "anchor/common/ssv_types" } signature_collector = { path = "anchor/signature_collector" } -qbft_manager = { path = "anchor/common/qbft" } +qbft_manager = { path = "anchor/qbft_manager" } lighthouse_network = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } task_executor = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store", default-features = false, features = [ "tracing", ] } metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } diff --git a/anchor/client/Cargo.toml b/anchor/client/Cargo.toml index d0da3917d..5195d7028 100644 --- a/anchor/client/Cargo.toml +++ b/anchor/client/Cargo.toml @@ -23,6 +23,7 @@ hyper = { workspace = true } network = { workspace = true } parking_lot = { workspace = true } processor = { workspace = true } +qbft_manager = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } signature_collector = { workspace = true } diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 63e9428bc..7a996352c 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -14,6 +14,7 @@ use eth2::{BeaconNodeHttpClient, Timeouts}; use eth2_config::Eth2Config; use network::Network; use parking_lot::RwLock; +use qbft_manager::QbftManager; use sensitive_url::SensitiveUrl; use signature_collector::SignatureCollectorManager; use slot_clock::{SlotClock, SystemTimeSlotClock}; @@ -89,13 +90,6 @@ impl Client { // dirty hack to be able to connect to local kurtosis devnet Arc::get_mut(&mut spec).unwrap().genesis_fork_version = [16, 0, 0, 56]; - // Start the processor - let processor_senders = processor::spawn(config.processor, executor.clone()); - - // Create the processor-adjacent managers - let signature_collector = - Arc::new(SignatureCollectorManager::new(processor_senders.clone())); - // Optionally start the metrics server. let http_metrics_shared_state = if config.http_metrics.enabled { let shared_state = Arc::new(RwLock::new(http_metrics::Shared { genesis_time: None })); @@ -269,9 +263,22 @@ impl Client { let proposer_nodes = Arc::new(proposer_nodes); start_fallback_updater_service::<_, E>(executor.clone(), proposer_nodes.clone())?; - let validator_store = Arc::new(AnchorValidatorStore::new( + // Start the processor + let processor_senders = processor::spawn(config.processor, executor.clone()); + + // Create the processor-adjacent managers + let signature_collector = + Arc::new(SignatureCollectorManager::new(processor_senders.clone())); + let qbft_manager = Arc::new(QbftManager::new( + processor_senders.clone(), + OperatorId(1), + slot_clock.clone(), + )); + + let validator_store = Arc::new(AnchorValidatorStore::<_, E>::new( processor_senders, signature_collector, + qbft_manager, spec.clone(), genesis_validators_root, OperatorId(123), @@ -347,22 +354,22 @@ impl Client { // Wait until genesis has occurred. wait_for_genesis(&beacon_nodes, genesis_time).await?; - duties_service::start_update_service::<_, _, E>(duties_service.clone(), block_service_tx); + duties_service::start_update_service(duties_service.clone(), block_service_tx); block_service - .start_update_service::(block_service_rx) + .start_update_service(block_service_rx) .map_err(|e| format!("Unable to start block service: {}", e))?; attestation_service - .start_update_service::(&spec) + .start_update_service(&spec) .map_err(|e| format!("Unable to start attestation service: {}", e))?; sync_committee_service - .start_update_service::(&spec) + .start_update_service(&spec) .map_err(|e| format!("Unable to start sync committee service: {}", e))?; preparation_service - .start_update_service::(&spec) + .start_update_service(&spec) .map_err(|e| format!("Unable to start preparation service: {}", e))?; Ok(()) diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml index be97837a3..2c20f0bb6 100644 --- a/anchor/validator_store/Cargo.toml +++ b/anchor/validator_store/Cargo.toml @@ -8,8 +8,11 @@ rust-version = "1.81.0" [dependencies] dashmap = "6.1.0" processor = { workspace = true } +qbft = { workspace = true } +qbft_manager = { workspace = true } safe_arith = { workspace = true } signature_collector = { workspace = true } +slot_clock = { workspace = true } ssv_types = { workspace = true } tracing = { workspace = true } types = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index e20ea28ca..091ae3b54 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -1,13 +1,22 @@ +extern crate core; + use dashmap::DashMap; +use qbft::Completed; +use qbft_manager::{CommitteeInstanceId, QbftError, QbftManager, ValidatorInstanceId}; use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; +use slot_clock::SlotClock; +use ssv_types::message::{ + BeaconVote, DataSsz, ValidatorConsensusData, ValidatorDuty, BEACON_ROLE_AGGREGATOR, + BEACON_ROLE_PROPOSER, DATA_VERSION_ALTAIR, DATA_VERSION_BELLATRIX, DATA_VERSION_CAPELLA, + DATA_VERSION_DENEB, DATA_VERSION_PHASE0, DATA_VERSION_UNKNOWN, +}; use ssv_types::{Cluster, OperatorId}; use std::sync::Arc; use tracing::{error, warn}; use types::attestation::Attestation; use types::beacon_block::BeaconBlock; use types::graffiti::Graffiti; -use types::payload::AbstractExecPayload; use types::selection_proof::SelectionProof; use types::signed_aggregate_and_proof::SignedAggregateAndProof; use types::signed_beacon_block::SignedBeaconBlock; @@ -23,11 +32,12 @@ use types::validator_registration_data::{ }; use types::voluntary_exit::VoluntaryExit; use types::{ - Address, ChainSpec, Domain, EthSpec, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, + AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, Domain, EthSpec, + FullPayload, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, SyncAggregatorSelectionData, }; use validator_store::{ - DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, ValidatorStore, + DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignBlock, ValidatorStore, }; struct InitializedCluster { @@ -35,31 +45,41 @@ struct InitializedCluster { decrypted_key_share: SecretKey, } -pub struct AnchorValidatorStore { +pub struct AnchorValidatorStore { clusters: DashMap, signature_collector: Arc, + qbft_manager: Arc>, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, } -impl AnchorValidatorStore { +impl AnchorValidatorStore { pub fn new( _processor: processor::Senders, signature_collector: Arc, + qbft_manager: Arc>, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, - ) -> AnchorValidatorStore { + ) -> AnchorValidatorStore { Self { clusters: DashMap::new(), signature_collector, + qbft_manager, spec, genesis_validators_root, operator_id, } } + fn cluster(&self, validator_pubkey: PublicKeyBytes) -> Result { + self.clusters + .get(&validator_pubkey) + .map(|c| c.cluster.clone()) + .ok_or(Error::UnknownPubkey(validator_pubkey)) + } + fn get_domain(&self, epoch: Epoch, domain: Domain) -> Hash256 { self.spec.get_domain( epoch, @@ -97,6 +117,74 @@ impl AnchorValidatorStore { drop(cluster); Ok((*collector.await.map_err(SpecificError::from)?).clone()) } + + async fn sign_abstract_block< + P: AbstractExecPayload, + F: FnOnce(BeaconBlock) -> DataSsz, + >( + &self, + validator_pubkey: PublicKeyBytes, + block: BeaconBlock, + current_slot: Slot, + wrapper: F, + ) -> Result, Error> { + // Make sure the block slot is not higher than the current slot to avoid potential attacks. + if block.slot() > current_slot { + warn!( + block_slot = block.slot().as_u64(), + current_slot = current_slot.as_u64(), + "Not signing block with slot greater than current slot", + ); + return Err(Error::GreaterThanCurrentSlot { + slot: block.slot(), + current_slot, + }); + } + + // todo slashing protection + + let cluster = self.cluster(validator_pubkey)?; + + // first, we have to get to consensus + let completed = self + .qbft_manager + .decide_instance( + ValidatorInstanceId { + validator: validator_pubkey, + instance_height: block.slot().as_usize().into(), + }, + ValidatorConsensusData { + duty: ValidatorDuty { + r#type: BEACON_ROLE_PROPOSER, + pub_key: validator_pubkey, + slot: block.slot().as_usize().into(), + validator_index: cluster.validator_metadata.validator_index, + committee_index: 0, + committee_length: 0, + committees_at_slot: 0, + validator_committee_index: 0, + validator_sync_committee_indices: Default::default(), + }, + version: match &block { + BeaconBlock::Base(_) => DATA_VERSION_PHASE0, + BeaconBlock::Altair(_) => DATA_VERSION_ALTAIR, + BeaconBlock::Bellatrix(_) => DATA_VERSION_BELLATRIX, + BeaconBlock::Capella(_) => DATA_VERSION_CAPELLA, + BeaconBlock::Deneb(_) => DATA_VERSION_DENEB, + BeaconBlock::Electra(_) => DATA_VERSION_UNKNOWN, + }, + data_ssz: Box::new(wrapper(block)), + }, + &cluster, + ) + .await + .map_err(SpecificError::from)?; + let data = match completed { + Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), + Completed::Success(data) => data, + }; + Ok(*data.data_ssz) + } } #[derive(Debug)] @@ -104,6 +192,9 @@ pub enum SpecificError { ExitsUnsupported, SignatureCollectionFailed(CollectionError), ArithError(ArithError), + QbftError(QbftError), + Timeout, + InvalidQbftData, } impl From for SpecificError { @@ -118,10 +209,17 @@ impl From for SpecificError { } } +impl From for SpecificError { + fn from(err: QbftError) -> SpecificError { + SpecificError::QbftError(err) + } +} + pub type Error = ValidatorStoreError; -impl ValidatorStore for AnchorValidatorStore { +impl ValidatorStore for AnchorValidatorStore { type Error = SpecificError; + type E = E; fn validator_index(&self, pubkey: &PublicKeyBytes) -> Option { self.clusters @@ -163,7 +261,7 @@ impl ValidatorStore for AnchorValidatorStore { Some(1) } - async fn randao_reveal( + async fn randao_reveal( &self, validator_pubkey: PublicKeyBytes, signing_epoch: Epoch, @@ -193,42 +291,63 @@ impl ValidatorStore for AnchorValidatorStore { } } - async fn sign_block>( + async fn sign_attestation( &self, - _validator_pubkey: PublicKeyBytes, - block: BeaconBlock, - current_slot: Slot, - ) -> Result, Error> { - // Make sure the block slot is not higher than the current slot to avoid potential attacks. - if block.slot() > current_slot { - warn!( - block_slot = block.slot().as_u64(), - current_slot = current_slot.as_u64(), - "Not signing block with slot greater than current slot", - ); - return Err(Error::GreaterThanCurrentSlot { - slot: block.slot(), - current_slot, + validator_pubkey: PublicKeyBytes, + validator_committee_position: usize, + attestation: &mut Attestation, + current_epoch: Epoch, + ) -> Result<(), Error> { + // Make sure the target epoch is not higher than the current epoch to avoid potential attacks. + if attestation.data().target.epoch > current_epoch { + return Err(Error::GreaterThanCurrentEpoch { + epoch: attestation.data().target.epoch, + current_epoch, }); } // todo slashing protection - // first, we have to get to consensus - todo!() - } + let cluster = self.cluster(validator_pubkey)?; + + let completed = self + .qbft_manager + .decide_instance( + CommitteeInstanceId { + committee: cluster.cluster_id, + instance_height: current_epoch.as_usize().into(), + }, + BeaconVote { + block_root: attestation.data().beacon_block_root, + source: attestation.data().source, + target: attestation.data().target, + }, + &cluster, + ) + .await + .map_err(SpecificError::from)?; + let data = match completed { + Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), + Completed::Success(data) => data, + }; + attestation.data_mut().beacon_block_root = data.block_root; + attestation.data_mut().source = data.source; + attestation.data_mut().target = data.target; - async fn sign_attestation( - &self, - _validator_pubkey: PublicKeyBytes, - _validator_committee_position: usize, - _attestation: &mut Attestation, - _current_epoch: Epoch, - ) -> Result<(), Error> { - todo!() + // yay - we agree! let's sign the att we agreed on + let domain_hash = self.get_domain(current_epoch, Domain::BeaconAttester); + let signing_root = attestation.data().signing_root(domain_hash); + let signature = self + .collect_signature(validator_pubkey, signing_root) + .await?; + attestation + .add_signature(&signature, validator_committee_position) + .map_err(Error::UnableToSignAttestation)?; + + Ok(()) } - async fn sign_voluntary_exit( + async fn sign_voluntary_exit( &self, _validator_pubkey: PublicKeyBytes, _voluntary_exit: VoluntaryExit, @@ -237,7 +356,7 @@ impl ValidatorStore for AnchorValidatorStore { Err(Error::SpecificError(SpecificError::ExitsUnsupported)) } - async fn sign_validator_registration_data( + async fn sign_validator_registration_data( &self, validator_registration_data: ValidatorRegistrationData, ) -> Result { @@ -254,17 +373,69 @@ impl ValidatorStore for AnchorValidatorStore { }) } - async fn produce_signed_aggregate_and_proof( + async fn produce_signed_aggregate_and_proof( &self, - _validator_pubkey: PublicKeyBytes, - _aggregator_index: u64, - _aggregate: Attestation, - _selection_proof: SelectionProof, + validator_pubkey: PublicKeyBytes, + aggregator_index: u64, + aggregate: Attestation, + selection_proof: SelectionProof, ) -> Result, Error> { - todo!() + let signing_epoch = aggregate.data().target.epoch; + let cluster = self.cluster(validator_pubkey)?; + + let message = + AggregateAndProof::from_attestation(aggregator_index, aggregate, selection_proof); + + // first, we have to get to consensus + let completed = self + .qbft_manager + .decide_instance( + ValidatorInstanceId { + validator: validator_pubkey, + // todo not sure if correct height + instance_height: message.aggregate().data().slot.as_usize().into(), + }, + ValidatorConsensusData { + duty: ValidatorDuty { + r#type: BEACON_ROLE_AGGREGATOR, + pub_key: validator_pubkey, + slot: message.aggregate().data().slot, + validator_index: cluster.validator_metadata.validator_index, + committee_index: message.aggregate().data().index, + // todo fill rest correctly + committee_length: 0, + committees_at_slot: 0, + validator_committee_index: 0, + validator_sync_committee_indices: Default::default(), + }, + version: DATA_VERSION_PHASE0, + data_ssz: Box::new(DataSsz::AggregateAndProof(message)), + }, + &cluster, + ) + .await + .map_err(SpecificError::from)?; + let data = match completed { + Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), + Completed::Success(data) => data, + }; + let message = match *data.data_ssz { + DataSsz::AggregateAndProof(message) => message, + _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), + }; + + let signing_context = self.get_domain(signing_epoch, Domain::AggregateAndProof); + let signing_root = message.signing_root(signing_context); + let signature = self + .collect_signature(validator_pubkey, signing_root) + .await?; + + Ok(SignedAggregateAndProof::from_aggregate_and_proof( + message, signature, + )) } - async fn produce_selection_proof( + async fn produce_selection_proof( &self, validator_pubkey: PublicKeyBytes, slot: Slot, @@ -278,7 +449,7 @@ impl ValidatorStore for AnchorValidatorStore { .map(SelectionProof::from) } - async fn produce_sync_selection_proof( + async fn produce_sync_selection_proof( &self, validator_pubkey: &PublicKeyBytes, slot: Slot, @@ -297,7 +468,7 @@ impl ValidatorStore for AnchorValidatorStore { .map(SyncSelectionProof::from) } - async fn produce_sync_committee_signature( + async fn produce_sync_committee_signature( &self, _slot: Slot, _beacon_block_root: Hash256, @@ -307,7 +478,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - async fn produce_signed_contribution_and_proof( + async fn produce_signed_contribution_and_proof( &self, _aggregator_index: u64, _aggregator_pubkey: PublicKeyBytes, @@ -317,7 +488,7 @@ impl ValidatorStore for AnchorValidatorStore { todo!() } - fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { + fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { // TODO slashing protection } @@ -325,8 +496,71 @@ impl ValidatorStore for AnchorValidatorStore { self.clusters.get(pubkey).map(|v| ProposalData { validator_index: Some(v.cluster.validator_metadata.validator_index.0 as u64), fee_recipient: Some(v.cluster.validator_metadata.fee_recipient), - gas_limit: 30_000_000, // TODO support scalooors + gas_limit: 29_999_998, // TODO support scalooors builder_proposals: false, // TODO support MEVooors }) } } + +impl SignBlock, SpecificError> + for AnchorValidatorStore +{ + async fn sign_block( + &self, + validator_pubkey: PublicKeyBytes, + block: BeaconBlock>, + current_slot: Slot, + ) -> Result>, ValidatorStoreError> { + let data = self + .sign_abstract_block(validator_pubkey, block, current_slot, DataSsz::BeaconBlock) + .await?; + let block = match data { + DataSsz::BeaconBlock(block) => block, + // todo what do if we agree on a blind block + _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), + }; + + // yay - we agree! let's sign the block we agreed on + let domain_hash = self.get_domain(block.epoch(), Domain::BeaconProposer); + let signing_root = block.signing_root(domain_hash); + let signature = self + .collect_signature(validator_pubkey, signing_root) + .await?; + + Ok(SignedBeaconBlock::from_block(block, signature)) + } +} + +impl SignBlock, SpecificError> + for AnchorValidatorStore +{ + async fn sign_block( + &self, + validator_pubkey: PublicKeyBytes, + block: BeaconBlock>, + current_slot: Slot, + ) -> Result>, Error> { + let data = self + .sign_abstract_block( + validator_pubkey, + block, + current_slot, + DataSsz::BlindedBeaconBlock, + ) + .await?; + let block = match data { + DataSsz::BlindedBeaconBlock(block) => block, + // todo what do if we agree on a non-blind block + _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), + }; + + // yay - we agree! let's sign the block we agreed on + let domain_hash = self.get_domain(block.epoch(), Domain::BeaconProposer); + let signing_root = block.signing_root(domain_hash); + let signature = self + .collect_signature(validator_pubkey, signing_root) + .await?; + + Ok(SignedBeaconBlock::from_block(block, signature)) + } +} From 1a57f1f5be16ce73211d2b00cc6a6dd10461448b Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Mon, 6 Jan 2025 10:23:52 +0100 Subject: [PATCH 15/21] remove decided qbft instances --- anchor/common/qbft/src/lib.rs | 6 ++- anchor/common/qbft/src/types.rs | 2 +- anchor/processor/src/lib.rs | 4 ++ anchor/qbft_manager/src/lib.rs | 96 +++++++++++++++++++++++++++------ 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/anchor/common/qbft/src/lib.rs b/anchor/common/qbft/src/lib.rs index 2df84ce9a..23de40202 100644 --- a/anchor/common/qbft/src/lib.rs +++ b/anchor/common/qbft/src/lib.rs @@ -94,12 +94,16 @@ where } } + pub fn start_data_hash(&self) -> &D::Hash { + &self.start_data + } + pub fn config(&self) -> &Config { &self.config } /// Returns the operator id for this instance. - fn operator_id(&self) -> OperatorId { + pub fn operator_id(&self) -> OperatorId { self.config.operator_id } diff --git a/anchor/common/qbft/src/types.rs b/anchor/common/qbft/src/types.rs index b9d387e53..ef0e47e50 100644 --- a/anchor/common/qbft/src/types.rs +++ b/anchor/common/qbft/src/types.rs @@ -56,7 +56,7 @@ pub struct OperatorId(pub usize); /// The instance height behaves like an "ID" for the QBFT instance. It is used to uniquely identify /// different instances, that have the same operator id. #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, From, Deref)] -pub struct InstanceHeight(usize); +pub struct InstanceHeight(pub usize); #[derive(Debug, Clone, Copy)] #[repr(u8)] diff --git a/anchor/processor/src/lib.rs b/anchor/processor/src/lib.rs index 8d63f743f..d1bf8816a 100644 --- a/anchor/processor/src/lib.rs +++ b/anchor/processor/src/lib.rs @@ -107,6 +107,10 @@ impl Sender { } result } + + pub fn is_closed(&self) -> bool { + self.tx.is_closed() + } } /// Bag of available senders relevant for the Anchor client. diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 2a3707b7f..8aa735b97 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -9,17 +9,22 @@ use ssv_types::message::{BeaconVote, ValidatorConsensusData}; use ssv_types::{Cluster, ClusterId, OperatorId}; use std::fmt::Debug; use std::hash::Hash; +use std::sync::Arc; use tokio::select; use tokio::sync::mpsc::error::TrySendError; use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; use tokio::sync::oneshot::error::RecvError; use tokio::sync::{mpsc, oneshot}; -use tokio::time::Interval; +use tokio::time::{sleep, Interval}; use tracing::{error, warn}; use types::{EthSpec, Hash256, PublicKeyBytes}; const QBFT_INSTANCE_NAME: &str = "qbft_instance"; const QBFT_MESSAGE_NAME: &str = "qbft_message"; +const QBFT_CLEANER_NAME: &str = "qbft_cleaner"; + +/// number of slots to keep before the current slot +const QBFT_RETAIN_SLOTS: u64 = 1; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct CommitteeInstanceId { @@ -30,9 +35,17 @@ pub struct CommitteeInstanceId { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct ValidatorInstanceId { pub validator: PublicKeyBytes, + pub duty: ValidatorDuty, pub instance_height: InstanceHeight, } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum ValidatorDuty { + Proposal, + Aggregator, + SyncCommitteeAggregator, +} + #[derive(Debug)] pub struct QbftMessage { pub kind: QbftMessageKind, @@ -56,20 +69,31 @@ type Map = DashMap>>; pub struct QbftManager { processor: Senders, operator_id: QbftOperatorId, - _slot_clock: T, // TODO: use this. e.g. properly aligning round intervals with slot etc. + slot_clock: T, validator_consensus_data_instances: Map>, beacon_vote_instances: Map, } impl QbftManager { - pub fn new(processor: Senders, operator_id: OperatorId, slot_clock: T) -> Self { - QbftManager { + pub fn new( + processor: Senders, + operator_id: OperatorId, + slot_clock: T, + ) -> Result, QbftError> { + let manager = Arc::new(QbftManager { processor, operator_id: QbftOperatorId(operator_id.0 as usize), - _slot_clock: slot_clock, + slot_clock, validator_consensus_data_instances: DashMap::new(), beacon_vote_instances: DashMap::new(), - } + }); + + manager + .processor + .permitless + .send_async(Arc::clone(&manager).cleaner(), QBFT_CLEANER_NAME)?; + + Ok(manager) } pub async fn decide_instance>( @@ -119,6 +143,23 @@ impl QbftManager { )?; Ok(()) } + + async fn cleaner(self: Arc) { + while !self.processor.permitless.is_closed() { + sleep( + self.slot_clock + .duration_to_next_slot() + .unwrap_or(self.slot_clock.slot_duration()), + ) + .await; + let Some(slot) = self.slot_clock.now() else { + continue; + }; + let cutoff = slot.saturating_sub(QBFT_RETAIN_SLOTS); + self.beacon_vote_instances + .retain(|k, _| k.instance_height.0 >= cutoff.as_usize()) + } + } } pub trait QbftDecidable: @@ -192,7 +233,10 @@ enum QbftInstance)> { Initialized { qbft: Box>, round_end: Interval, - on_completed: oneshot::Sender>, + on_completed: Vec>>, + }, + Decided { + value: Completed, }, } @@ -203,7 +247,7 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) loop { let message = match &mut instance { - QbftInstance::Uninitialized { .. } => rx.recv().await, + QbftInstance::Uninitialized { .. } | QbftInstance::Decided { .. } => rx.recv().await, QbftInstance::Initialized { qbft: instance, round_end, @@ -244,12 +288,29 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) QbftInstance::Initialized { round_end: tokio::time::interval(instance.config().round_time), qbft: instance, - on_completed, + on_completed: vec![on_completed], } } - instance @ QbftInstance::Initialized { .. } => { - warn!("got double initialization of qbft instance, ignoring"); - instance + QbftInstance::Initialized { + qbft, + round_end, + on_completed: mut on_completed_vec, + } => { + if qbft.start_data_hash() != &initial.hash() { + warn!("got conflicting double initialization of qbft instance"); + } + on_completed_vec.push(on_completed); + QbftInstance::Initialized { + qbft, + round_end, + on_completed: on_completed_vec, + } + } + QbftInstance::Decided { value } => { + if on_completed.send(value.clone()).is_err() { + error!("could not send qbft result"); + } + QbftInstance::Decided { value } } } } @@ -260,6 +321,9 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) QbftInstance::Uninitialized { message_buffer } => { message_buffer.push(message); } + QbftInstance::Decided { .. } => { + // no longer relevant + } }, } @@ -270,10 +334,12 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) } = instance { if let Some(completed) = qbft.completed() { - if on_completed.send(completed).is_err() { - error!("could not send qbft result"); + for on_completed in on_completed { + if on_completed.send(completed.clone()).is_err() { + error!("could not send qbft result"); + } } - break; + instance = QbftInstance::Decided { value: completed }; } else { instance = QbftInstance::Initialized { qbft, From e2575980405993c0871d674013b657ff709f5e6e Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Mon, 6 Jan 2025 10:25:24 +0100 Subject: [PATCH 16/21] cargo fmt... --- anchor/common/qbft/src/tests.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/anchor/common/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs index d651c6ffd..180fe4166 100644 --- a/anchor/common/qbft/src/tests.rs +++ b/anchor/common/qbft/src/tests.rs @@ -2,9 +2,9 @@ //! //! These test individual components and also provide full end-to-end tests of the entire protocol. -use std::cell::RefCell; use super::*; use crate::validation::{validate_data, ValidatedData}; +use std::cell::RefCell; use std::collections::VecDeque; use std::rc::Rc; use tracing_subscriber::filter::EnvFilter; @@ -31,9 +31,7 @@ impl Default for TestQBFTCommitteeBuilder { ..Default::default() }; - TestQBFTCommitteeBuilder { - config, - } + TestQBFTCommitteeBuilder { config } } } @@ -97,13 +95,16 @@ fn construct_and_run_committee( let id = OperatorId::from(id); // Creates a new instance config.operator_id = id; - let mut instance = Qbft::new(config.clone(), validated_data.clone(), move |message| msg_queue.borrow_mut().push_back((id, message))); + let mut instance = Qbft::new(config.clone(), validated_data.clone(), move |message| { + msg_queue.borrow_mut().push_back((id, message)) + }); instance.start_round(); instances.insert(id, instance); } TestQBFTCommittee { - msg_queue, instances + msg_queue, + instances, } } @@ -115,7 +116,11 @@ impl)> TestQBFTCommittee { // we are done! return; }; - for instance in self.instances.iter_mut().filter_map(|(id, instance)| (id.0 != sender.0).then_some(instance)) { + for instance in self + .instances + .iter_mut() + .filter_map(|(id, instance)| (id.0 != sender.0).then_some(instance)) + { instance.receive(msg.clone()); } } From 114c8b5df05c9bb57571a814d485050aa96e274b Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Mon, 6 Jan 2025 12:47:48 +0100 Subject: [PATCH 17/21] clean up qbft and fix leader selection --- anchor/common/qbft/src/config.rs | 19 ++++++----------- anchor/common/qbft/src/lib.rs | 36 +++++++++++++++++++------------- anchor/common/qbft/src/tests.rs | 17 ++++----------- anchor/common/qbft/src/types.rs | 26 ++++++++++++++++------- anchor/qbft_manager/src/lib.rs | 11 +++++++--- 5 files changed, 57 insertions(+), 52 deletions(-) diff --git a/anchor/common/qbft/src/config.rs b/anchor/common/qbft/src/config.rs index 6d70e9ab2..bd049c8e9 100644 --- a/anchor/common/qbft/src/config.rs +++ b/anchor/common/qbft/src/config.rs @@ -1,6 +1,5 @@ use super::error::ConfigBuilderError; use crate::types::{DefaultLeaderFunction, InstanceHeight, LeaderFunction, OperatorId, Round}; -use std::collections::HashSet; use std::fmt::Debug; use std::time::Duration; @@ -13,8 +12,7 @@ where pub instance_height: InstanceHeight, pub round: Round, pub pr: usize, - pub committee_size: usize, - pub committee_members: HashSet, + pub committee_members: Vec, pub quorum_size: usize, pub round_time: Duration, pub max_rounds: usize, @@ -27,13 +25,9 @@ impl Config { pub fn operator_id(&self) -> OperatorId { self.operator_id } - /// The committee size - pub fn committee_size(&self) -> usize { - self.committee_size - } - pub fn commmittee_members(&self) -> HashSet { - self.committee_members.clone() + pub fn commmittee_members(&self) -> &[OperatorId] { + &self.committee_members } /// The quorum size required for the committee to reach consensus @@ -81,8 +75,7 @@ impl Default for ConfigBuilder { config: Config { operator_id: OperatorId::default(), instance_height: InstanceHeight::default(), - committee_size: 0, - committee_members: HashSet::new(), + committee_members: vec![], quorum_size: 4, round: Round::default(), pr: 0, @@ -110,8 +103,8 @@ impl ConfigBuilder { self } - pub fn committee_size(&mut self, committee_size: usize) -> &mut Self { - self.config.committee_size = committee_size; + pub fn committee_members(&mut self, committee_members: Vec) -> &mut Self { + self.config.committee_members = committee_members; self } diff --git a/anchor/common/qbft/src/lib.rs b/anchor/common/qbft/src/lib.rs index 23de40202..935c4cd8c 100644 --- a/anchor/common/qbft/src/lib.rs +++ b/anchor/common/qbft/src/lib.rs @@ -72,13 +72,13 @@ where S: FnMut(Message), { pub fn new(config: Config, start_data: ValidatedData, send_message: S) -> Self { - let estimated_map_size = config.committee_size; + let estimated_map_size = config.committee_members.len(); let mut data = HashMap::with_capacity(2); let start_data_hash = start_data.data.hash(); data.insert(start_data_hash.clone(), start_data); - Qbft { + let mut qbft = Qbft { current_round: config.round, instance_height: config.instance_height, config, @@ -91,7 +91,9 @@ where send_message, state: InstanceState::AwaitingProposal, completed: None, - } + }; + qbft.start_round(); + qbft } pub fn start_data_hash(&self) -> &D::Hash { @@ -109,7 +111,7 @@ where /// Obtains the maximum number of faulty nodes that this consensus can tolerate fn get_f(&self) -> usize { - let f = (self.config.committee_size - 1) % 3; + let f = (self.config.committee_members.len() - 1) % 3; if f > 0 { f } else { @@ -138,7 +140,7 @@ where operator_id, self.current_round, self.instance_height, - self.config.committee_size, + &self.config.committee_members, ) } @@ -165,8 +167,8 @@ where .max_by_key(|maybe_past_consensus_data| { maybe_past_consensus_data .as_ref() - .map(|consensus_data| *consensus_data.round) - .unwrap_or(0) + .map(|consensus_data| consensus_data.round) + .unwrap_or_default() })? .as_ref()?; @@ -181,8 +183,8 @@ where } // Handles the beginning of a round. - pub fn start_round(&mut self) { - debug!(round = *self.current_round, "Starting new round",); + fn start_round(&mut self) { + debug!(round = *self.current_round, "Starting new round"); // Remove round change messages that would be for previous rounds self.round_change_messages @@ -214,6 +216,7 @@ where } } + /// message must be authenticated by the caller! pub fn receive(&mut self, msg: Message) { match msg { Message::Propose(operator_id, consensus_data) => { @@ -468,7 +471,7 @@ where } // Ensure that this message is for the correct round - if round < self.current_round || *round > self.config.max_rounds { + if round < self.current_round || round.get() > self.config.max_rounds { warn!( from = *operator_id, current_round = *self.current_round, @@ -532,20 +535,23 @@ where pub fn end_round(&mut self) { debug!(round = *self.current_round, "Incrementing round"); - if *self.current_round > self.config.max_rounds() { + let Some(next_round) = self.current_round.next() else { + self.state = InstanceState::Complete; + self.completed = Some(Completed::TimedOut); + return; + }; + if next_round.get() > self.config.max_rounds() { self.state = InstanceState::Complete; self.completed = Some(Completed::TimedOut); return; } - self.send_round_change(self.current_round.next()); + self.send_round_change(next_round); // Start a new round - self.set_round(self.current_round.next()); + self.set_round(next_round); } // Send message functions fn send_proposal(&mut self, data: ValidatedData) { - self.state = InstanceState::Prepare; - debug!(?self.state, "State Changed"); let consensus_data = ConsensusData { round: self.current_round, data: data.data, diff --git a/anchor/common/qbft/src/tests.rs b/anchor/common/qbft/src/tests.rs index 180fe4166..19d7d4afc 100644 --- a/anchor/common/qbft/src/tests.rs +++ b/anchor/common/qbft/src/tests.rs @@ -24,10 +24,8 @@ struct TestQBFTCommitteeBuilder { impl Default for TestQBFTCommitteeBuilder { fn default() -> Self { let config = Config:: { - // Set a default committee size of 5. - committee_size: 5, // Populate the committee members - committee_members: (0..5).map(OperatorId::from).collect::>(), + committee_members: (0..5).map(OperatorId::from).collect(), ..Default::default() }; @@ -37,12 +35,6 @@ impl Default for TestQBFTCommitteeBuilder { #[allow(dead_code)] impl TestQBFTCommitteeBuilder { - /// Sets the size of the testing committee. - pub fn committee_size(mut self, committee_size: usize) -> Self { - self.config.committee_size = committee_size; - self - } - /// Sets the config for all instances to run pub fn set_config(mut self, config: Config) -> Self { self.config = config; @@ -88,17 +80,16 @@ fn construct_and_run_committee( // The ID of a committee is just an integer in [0,committee_size) let msg_queue = Rc::new(RefCell::new(VecDeque::new())); - let mut instances = HashMap::with_capacity(config.committee_size); + let mut instances = HashMap::with_capacity(config.committee_members.len()); - for id in 0..config.committee_size { + for id in 0..config.committee_members.len() { let msg_queue = Rc::clone(&msg_queue); let id = OperatorId::from(id); // Creates a new instance config.operator_id = id; - let mut instance = Qbft::new(config.clone(), validated_data.clone(), move |message| { + let instance = Qbft::new(config.clone(), validated_data.clone(), move |message| { msg_queue.borrow_mut().push_back((id, message)) }); - instance.start_round(); instances.insert(id, instance); } diff --git a/anchor/common/qbft/src/types.rs b/anchor/common/qbft/src/types.rs index ef0e47e50..11e547108 100644 --- a/anchor/common/qbft/src/types.rs +++ b/anchor/common/qbft/src/types.rs @@ -1,10 +1,11 @@ //! A collection of types used by the QBFT modules use crate::validation::ValidatedData; use crate::Data; -use derive_more::{Add, Deref, From}; +use derive_more::{Deref, From}; use std::cmp::Eq; use std::fmt::Debug; use std::hash::Hash; +use std::num::NonZeroUsize; /// Generic LeaderFunction trait to allow for future implementations of the QBFT module pub trait LeaderFunction { @@ -14,7 +15,7 @@ pub trait LeaderFunction { operator_id: &OperatorId, round: Round, instance_height: InstanceHeight, - committee_size: usize, + committee: &[OperatorId], ) -> bool; } @@ -27,20 +28,29 @@ impl LeaderFunction for DefaultLeaderFunction { operator_id: &OperatorId, round: Round, instance_height: InstanceHeight, - committee_size: usize, + committee: &[OperatorId], ) -> bool { - *operator_id == ((*round + *instance_height) % committee_size).into() + *operator_id + == *committee + .get(((round.get() - Round::default().get()) + *instance_height) % committee.len()) + .expect("slice bounds kept by modulo length") } } /// This represents an individual round, these change on regular time intervals -#[derive(Clone, Copy, Debug, Deref, Default, Add, PartialEq, Eq, Hash, PartialOrd)] -pub struct Round(usize); +#[derive(Clone, Copy, Debug, Deref, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Round(NonZeroUsize); + +impl Default for Round { + fn default() -> Self { + Round(NonZeroUsize::new(1).expect("1 != 0")) + } +} impl Round { /// Returns the next round - pub fn next(&self) -> Round { - Round(self.0 + 1) + pub fn next(&self) -> Option { + self.0.checked_add(1).map(Round) } /// Sets the current round diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 8aa735b97..3ae461c2f 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -106,8 +106,14 @@ impl QbftManager { let mut config = ConfigBuilder::default(); config .operator_id(self.operator_id) - .committee_size(committee.cluster_members.len()) - .quorum_size(committee.cluster_members.len() - committee.faulty as usize); + .quorum_size(committee.cluster_members.len() - committee.faulty as usize) + .committee_members( + committee + .cluster_members + .iter() + .map(|m| QbftOperatorId(m.operator_id.0 as usize)) + .collect(), + ); let config = initial.config(&mut config, &id)?; let sender = D::get_or_spawn_instance(self, id); self.processor.urgent_consensus.send_immediate( @@ -281,7 +287,6 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) qbft::ValidatedData { data: initial }, |_| {}, )); - instance.start_round(); for message in message_buffer { instance.receive(message); } From 2cccae3dc5dc9d92c6267fddff8f8a29a6ae6eee Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Mon, 6 Jan 2025 16:25:26 +0100 Subject: [PATCH 18/21] notes on sync issues and small corrections --- anchor/client/src/lib.rs | 18 +++++----- anchor/qbft_manager/src/lib.rs | 4 +-- anchor/validator_store/src/lib.rs | 58 ++++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 24 deletions(-) diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 7a996352c..68e002a9b 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -269,11 +269,11 @@ impl Client { // Create the processor-adjacent managers let signature_collector = Arc::new(SignatureCollectorManager::new(processor_senders.clone())); - let qbft_manager = Arc::new(QbftManager::new( - processor_senders.clone(), - OperatorId(1), - slot_clock.clone(), - )); + let Ok(qbft_manager) = + QbftManager::new(processor_senders.clone(), OperatorId(1), slot_clock.clone()) + else { + return Err("Unable to initialize qbft manager".into()); + }; let validator_store = Arc::new(AnchorValidatorStore::<_, E>::new( processor_senders, @@ -303,7 +303,7 @@ impl Client { //ctx.write().duties_service = Some(duties_service.clone()); } - let block_service_builder = BlockServiceBuilder::new() + let mut block_service_builder = BlockServiceBuilder::new() .slot_clock(slot_clock.clone()) .validator_store(validator_store.clone()) .beacon_nodes(beacon_nodes.clone()) @@ -313,9 +313,9 @@ impl Client { //.graffiti_file(config.graffiti_file.clone()); // If we have proposer nodes, add them to the block service builder. - //if proposer_nodes_num > 0 { - // block_service_builder = block_service_builder.proposer_nodes(proposer_nodes.clone()); - //} + if proposer_nodes.num_total().await > 0 { + block_service_builder = block_service_builder.proposer_nodes(proposer_nodes.clone()); + } let block_service = block_service_builder.build()?; diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index 3ae461c2f..e336ad788 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -35,12 +35,12 @@ pub struct CommitteeInstanceId { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct ValidatorInstanceId { pub validator: PublicKeyBytes, - pub duty: ValidatorDuty, + pub duty: ValidatorDutyKind, pub instance_height: InstanceHeight, } #[derive(Debug, Clone, Hash, PartialEq, Eq)] -pub enum ValidatorDuty { +pub enum ValidatorDutyKind { Proposal, Aggregator, SyncCommitteeAggregator, diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 091ae3b54..6da8afc2e 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -1,8 +1,8 @@ -extern crate core; - use dashmap::DashMap; use qbft::Completed; -use qbft_manager::{CommitteeInstanceId, QbftError, QbftManager, ValidatorInstanceId}; +use qbft_manager::{ + CommitteeInstanceId, QbftError, QbftManager, ValidatorDutyKind, ValidatorInstanceId, +}; use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; use slot_clock::SlotClock; @@ -32,8 +32,8 @@ use types::validator_registration_data::{ }; use types::voluntary_exit::VoluntaryExit; use types::{ - AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, Domain, EthSpec, - FullPayload, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, + AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, Checkpoint, Domain, + EthSpec, FullPayload, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, SyncAggregatorSelectionData, }; use validator_store::{ @@ -41,8 +41,8 @@ use validator_store::{ }; struct InitializedCluster { - cluster: Cluster, - decrypted_key_share: SecretKey, + pub cluster: Cluster, + pub decrypted_key_share: SecretKey, } pub struct AnchorValidatorStore { @@ -151,6 +151,7 @@ impl AnchorValidatorStore { .decide_instance( ValidatorInstanceId { validator: validator_pubkey, + duty: ValidatorDutyKind::Proposal, instance_height: block.slot().as_usize().into(), }, ValidatorConsensusData { @@ -315,7 +316,7 @@ impl ValidatorStore for AnchorValidatorStore { .decide_instance( CommitteeInstanceId { committee: cluster.cluster_id, - instance_height: current_epoch.as_usize().into(), + instance_height: attestation.data().slot.as_usize().into(), }, BeaconVote { block_root: attestation.data().beacon_block_root, @@ -392,7 +393,7 @@ impl ValidatorStore for AnchorValidatorStore { .decide_instance( ValidatorInstanceId { validator: validator_pubkey, - // todo not sure if correct height + duty: ValidatorDutyKind::Aggregator, instance_height: message.aggregate().data().slot.as_usize().into(), }, ValidatorConsensusData { @@ -402,7 +403,7 @@ impl ValidatorStore for AnchorValidatorStore { slot: message.aggregate().data().slot, validator_index: cluster.validator_metadata.validator_index, committee_index: message.aggregate().data().index, - // todo fill rest correctly + // todo it seems the below are not needed (anymore?) committee_length: 0, committees_at_slot: 0, validator_committee_index: 0, @@ -470,11 +471,40 @@ impl ValidatorStore for AnchorValidatorStore { async fn produce_sync_committee_signature( &self, - _slot: Slot, - _beacon_block_root: Hash256, + slot: Slot, + beacon_block_root: Hash256, _validator_index: u64, - _validator_pubkey: &PublicKeyBytes, + validator_pubkey: &PublicKeyBytes, ) -> Result { + let cluster = self.cluster(*validator_pubkey)?; + + let completed = self + .qbft_manager + .decide_instance( + CommitteeInstanceId { + committee: cluster.cluster_id, + instance_height: slot.as_usize().into(), + }, + BeaconVote { + block_root: beacon_block_root, + // todo noooo. where do we get those here? + // -> actively fetch is possibly inefficient + // -> cant wait for sign_attestation, as that might not be called + // -> with timeout?... eh + // -> modifying interface should be ruled out + // -> modified sync_committee_service? that always triggers an attestation + // -> modified attestation_service? that submits the attestation data every slot? + source: Checkpoint::default(), + target: Checkpoint::default(), + }, + &cluster, + ) + .await + .map_err(SpecificError::from)?; + let _data = match completed { + Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), + Completed::Success(data) => data, + }; todo!() } @@ -485,6 +515,8 @@ impl ValidatorStore for AnchorValidatorStore { _contribution: SyncCommitteeContribution, _selection_proof: SyncSelectionProof, ) -> Result, Error> { + // todo: ah, we need to vote for all subnets at once here -> shift interface ton one call + // for all contributions todo!() } From c44994932217ab5ab92f040d5bbca392cf767bfa Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Tue, 7 Jan 2025 18:53:20 +0100 Subject: [PATCH 19/21] implement sync features in validator store --- Cargo.lock | 228 +++---- anchor/client/src/lib.rs | 2 +- anchor/common/qbft/src/error.rs | 2 +- anchor/common/ssv_types/src/message.rs | 2 +- anchor/qbft_manager/src/lib.rs | 2 +- anchor/signature_collector/src/lib.rs | 2 +- anchor/validator_store/Cargo.toml | 9 +- anchor/validator_store/src/lib.rs | 202 +++++-- .../src/sync_committee_service.rs | 564 ++++++++++++++++++ 9 files changed, 846 insertions(+), 167 deletions(-) create mode 100644 anchor/validator_store/src/sync_committee_service.rs diff --git a/Cargo.lock b/Cargo.lock index cfba404e8..439824274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,9 +100,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-primitives" -version = "0.8.16" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0540fd0355d400b59633c27bd4b42173e59943f28e9d3376b77a24771d432d04" +checksum = "788bb18e8f61d5d9340b52143f27771daf7e1dccbaf2741621d2493f9debf52e" dependencies = [ "alloy-rlp", "arbitrary", @@ -114,7 +114,6 @@ dependencies = [ "foldhash", "getrandom", "hashbrown 0.15.2", - "hex-literal", "indexmap", "itoa", "k256", @@ -149,7 +148,7 @@ checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -175,7 +174,10 @@ dependencies = [ name = "anchor_validator_store" version = "0.1.0" dependencies = [ + "beacon_node_fallback", "dashmap", + "eth2", + "futures", "processor", "qbft", "qbft_manager", @@ -183,8 +185,12 @@ dependencies = [ "signature_collector", "slot_clock", "ssv_types", + "task_executor", + "tokio", "tracing", "types", + "validator_metrics", + "validator_services", "validator_store", ] @@ -442,7 +448,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "synstructure", ] @@ -454,7 +460,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -506,13 +512,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.84" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1244b10dcd56c92219da4e14caa97e312079e185f04ba3eea25061561dc0a0" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -547,7 +553,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -665,7 +671,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon_node_fallback" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "eth2", "futures", @@ -699,7 +705,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.94", + "syn 2.0.95", "which", ] @@ -772,7 +778,7 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "arbitrary", @@ -988,9 +994,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", "clap_derive", @@ -998,9 +1004,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -1011,14 +1017,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1030,7 +1036,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "clap", @@ -1097,7 +1103,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "itertools 0.10.5", ] @@ -1105,7 +1111,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "quote", "syn 1.0.109", @@ -1374,7 +1380,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1422,7 +1428,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1444,7 +1450,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1583,7 +1589,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1594,7 +1600,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1615,7 +1621,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "unicode-xid", ] @@ -1643,7 +1649,7 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "clap", "clap_utils", @@ -1753,7 +1759,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1864,7 +1870,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -1895,7 +1901,7 @@ dependencies = [ [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "derivative", "eth2_keystore", @@ -1925,7 +1931,7 @@ dependencies = [ [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "paste", "types", @@ -1934,7 +1940,7 @@ dependencies = [ [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bls", "ethereum_hashing", @@ -1947,7 +1953,7 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bls", "num-bigint-dig", @@ -1959,7 +1965,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "aes 0.7.5", "bls", @@ -1981,7 +1987,7 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bytes", "discv5", @@ -2043,7 +2049,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -2170,7 +2176,7 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "winapi", "windows-acl", @@ -2191,7 +2197,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "safe_arith", @@ -2326,7 +2332,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -2444,7 +2450,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -2456,7 +2462,7 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "async-channel", "asynchronous-codec", @@ -2485,7 +2491,7 @@ dependencies = [ [[package]] name = "graffiti_file" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bls", "serde", @@ -2598,12 +2604,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hex_fmt" version = "0.3.0" @@ -3043,7 +3043,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -3142,7 +3142,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -3178,7 +3178,7 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bytes", ] @@ -3326,7 +3326,7 @@ dependencies = [ [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "arbitrary", "c-kzg", @@ -3779,7 +3779,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -3921,7 +3921,7 @@ dependencies = [ [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -3970,7 +3970,7 @@ dependencies = [ [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "git-version", "target_info", @@ -4019,7 +4019,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "chrono", "metrics", @@ -4059,7 +4059,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "fnv", ] @@ -4124,7 +4124,7 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -4158,7 +4158,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "prometheus", ] @@ -4553,7 +4553,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -4748,29 +4748,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -4856,7 +4856,7 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "reqwest", "sensitive_url", @@ -4864,12 +4864,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" dependencies = [ "proc-macro2", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -4974,7 +4974,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -5005,13 +5005,13 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", @@ -5720,7 +5720,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" [[package]] name = "salsa20" @@ -5806,9 +5806,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -5841,7 +5841,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "serde", "url", @@ -5864,14 +5864,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -5897,7 +5897,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6038,7 +6038,7 @@ dependencies = [ [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -6157,7 +6157,7 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "metrics", "parking_lot", @@ -6268,7 +6268,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "state_processing" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "arbitrary", "bls", @@ -6300,7 +6300,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "bls", "db-key", @@ -6383,7 +6383,7 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -6403,9 +6403,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.94" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "987bc0be1cdea8b10216bd06e2ca407d40b9543468fafd3ddfb02f36e77f71f3" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -6432,7 +6432,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6498,7 +6498,7 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "async-channel", "futures", @@ -6548,7 +6548,7 @@ dependencies = [ [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "quote", "syn 1.0.109", @@ -6580,7 +6580,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6591,7 +6591,7 @@ checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6713,7 +6713,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6842,7 +6842,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6923,7 +6923,7 @@ dependencies = [ "darling 0.20.10", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -6951,7 +6951,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7114,7 +7114,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "lru_cache", "parking_lot", @@ -7162,7 +7162,7 @@ dependencies = [ [[package]] name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "metrics", ] @@ -7170,7 +7170,7 @@ dependencies = [ [[package]] name = "validator_services" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "beacon_node_fallback", "bls", @@ -7193,7 +7193,7 @@ dependencies = [ [[package]] name = "validator_store" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#e0da923c27a9ceac603e937ffb8c979d7775a9e0" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" dependencies = [ "slashing_protection", "types", @@ -7283,7 +7283,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "wasm-bindgen-shared", ] @@ -7318,7 +7318,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7680,9 +7680,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.21" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f5bb5257f2407a5425c6e749bfd9692192a73e70a6060516ac04f889087d68" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] @@ -7836,7 +7836,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "synstructure", ] @@ -7858,7 +7858,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -7878,7 +7878,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", "synstructure", ] @@ -7900,7 +7900,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] @@ -7922,7 +7922,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.94", + "syn 2.0.95", ] [[package]] diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 68e002a9b..2f4371d0b 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -3,6 +3,7 @@ mod cli; pub mod config; +use anchor_validator_store::sync_committee_service::SyncCommitteeService; use anchor_validator_store::AnchorValidatorStore; use beacon_node_fallback::{ start_fallback_updater_service, ApiTopic, BeaconNodeFallback, CandidateBeaconNode, @@ -37,7 +38,6 @@ use validator_services::block_service::BlockServiceBuilder; use validator_services::duties_service; use validator_services::duties_service::DutiesServiceBuilder; use validator_services::preparation_service::PreparationServiceBuilder; -use validator_services::sync_committee_service::SyncCommitteeService; /// The time between polls when waiting for genesis. const WAITING_FOR_GENESIS_POLL_TIME: Duration = Duration::from_secs(12); diff --git a/anchor/common/qbft/src/error.rs b/anchor/common/qbft/src/error.rs index fcbaff5b4..866f521de 100644 --- a/anchor/common/qbft/src/error.rs +++ b/anchor/common/qbft/src/error.rs @@ -1,5 +1,5 @@ /// Error associated with Config building. -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ConfigBuilderError { /// Quorum size too small QuorumSizeTooSmall, diff --git a/anchor/common/ssv_types/src/message.rs b/anchor/common/ssv_types/src/message.rs index c47052b71..a60d9e6ff 100644 --- a/anchor/common/ssv_types/src/message.rs +++ b/anchor/common/ssv_types/src/message.rs @@ -174,7 +174,7 @@ pub struct Contribution { pub contribution: SyncCommitteeContribution, } -#[derive(Clone, Debug, TreeHash)] +#[derive(Clone, Debug, TreeHash, PartialEq, Eq)] pub struct BeaconVote { pub block_root: Hash256, pub source: Checkpoint, diff --git a/anchor/qbft_manager/src/lib.rs b/anchor/qbft_manager/src/lib.rs index e336ad788..c839c3036 100644 --- a/anchor/qbft_manager/src/lib.rs +++ b/anchor/qbft_manager/src/lib.rs @@ -356,7 +356,7 @@ async fn qbft_instance(mut rx: UnboundedReceiver>) } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum QbftError { QueueClosedError, QueueFullError, diff --git a/anchor/signature_collector/src/lib.rs b/anchor/signature_collector/src/lib.rs index 41e1685f2..c5968d775 100644 --- a/anchor/signature_collector/src/lib.rs +++ b/anchor/signature_collector/src/lib.rs @@ -131,7 +131,7 @@ pub enum CollectorMessageKind { }, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum CollectionError { QueueClosedError, QueueFullError, diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml index 2c20f0bb6..3a1ae3be7 100644 --- a/anchor/validator_store/Cargo.toml +++ b/anchor/validator_store/Cargo.toml @@ -6,7 +6,10 @@ authors = ["Sigma Prime "] rust-version = "1.81.0" [dependencies] -dashmap = "6.1.0" +beacon_node_fallback = { workspace = true } +dashmap = { workspace = true } +eth2 = { workspace = true } +futures = "0.3.31" processor = { workspace = true } qbft = { workspace = true } qbft_manager = { workspace = true } @@ -14,6 +17,10 @@ safe_arith = { workspace = true } signature_collector = { workspace = true } slot_clock = { workspace = true } ssv_types = { workspace = true } +task_executor = { workspace = true } +tokio = { workspace = true, features = ["sync", "time"] } tracing = { workspace = true } types = { workspace = true } +validator_metrics = { workspace = true } +validator_services = { workspace = true } validator_store = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 6da8afc2e..7f9abcae6 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -1,4 +1,7 @@ +pub mod sync_committee_service; + use dashmap::DashMap; +use futures::future::join_all; use qbft::Completed; use qbft_manager::{ CommitteeInstanceId, QbftError, QbftManager, ValidatorDutyKind, ValidatorInstanceId, @@ -7,9 +10,10 @@ use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; use slot_clock::SlotClock; use ssv_types::message::{ - BeaconVote, DataSsz, ValidatorConsensusData, ValidatorDuty, BEACON_ROLE_AGGREGATOR, - BEACON_ROLE_PROPOSER, DATA_VERSION_ALTAIR, DATA_VERSION_BELLATRIX, DATA_VERSION_CAPELLA, - DATA_VERSION_DENEB, DATA_VERSION_PHASE0, DATA_VERSION_UNKNOWN, + BeaconVote, Contribution, DataSsz, ValidatorConsensusData, ValidatorDuty, + BEACON_ROLE_AGGREGATOR, BEACON_ROLE_PROPOSER, BEACON_ROLE_SYNC_COMMITTEE_CONTRIBUTION, + DATA_VERSION_ALTAIR, DATA_VERSION_BELLATRIX, DATA_VERSION_CAPELLA, DATA_VERSION_DENEB, + DATA_VERSION_PHASE0, DATA_VERSION_UNKNOWN, }; use ssv_types::{Cluster, OperatorId}; use std::sync::Arc; @@ -32,9 +36,9 @@ use types::validator_registration_data::{ }; use types::voluntary_exit::VoluntaryExit; use types::{ - AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, Checkpoint, Domain, - EthSpec, FullPayload, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, - SyncAggregatorSelectionData, + AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, + ContributionAndProof, Domain, EthSpec, FullPayload, Hash256, PublicKeyBytes, SecretKey, + Signature, SignedRoot, SyncAggregatorSelectionData, VariableList, }; use validator_store::{ DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignBlock, ValidatorStore, @@ -186,16 +190,149 @@ impl AnchorValidatorStore { }; Ok(*data.data_ssz) } + + pub async fn produce_sync_committee_signature_with_full_vote( + &self, + slot: Slot, + vote: BeaconVote, + validator_index: u64, + validator_pubkey: &PublicKeyBytes, + ) -> Result { + let epoch = slot.epoch(E::slots_per_epoch()); + let cluster = self.cluster(*validator_pubkey)?; + let beacon_block_root = vote.block_root; + + let completed = self + .qbft_manager + .decide_instance( + CommitteeInstanceId { + committee: cluster.cluster_id, + instance_height: slot.as_usize().into(), + }, + vote, + &cluster, + ) + .await + .map_err(SpecificError::from)?; + let data = match completed { + Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), + Completed::Success(data) => data, + }; + + let domain = self.get_domain(epoch, Domain::SyncCommittee); + let signing_root = data.block_root.signing_root(domain); + let signature = self + .collect_signature(*validator_pubkey, signing_root) + .await?; + + Ok(SyncCommitteeMessage { + slot, + beacon_block_root, + validator_index, + signature, + }) + } + + pub async fn produce_signed_contribution_and_proofs( + &self, + aggregator_index: u64, + aggregator_pubkey: PublicKeyBytes, + signing_data: Vec>, + ) -> Vec, Error>> { + let error = |err: Error| signing_data.iter().map(move |_| Err(err.clone())).collect(); + + let Some(slot) = signing_data.first().map(|data| data.contribution.slot) else { + return vec![]; + }; + let epoch = slot.epoch(E::slots_per_epoch()); + let cluster = match self.cluster(aggregator_pubkey) { + Ok(cluster) => cluster, + Err(err) => return error(err), + }; + + let data = match VariableList::new( + signing_data + .iter() + .map(|signing_data| Contribution { + selection_proof_sig: signing_data.selection_proof.clone().into(), + contribution: signing_data.contribution.clone(), + }) + .collect(), + ) { + Ok(data) => data, + Err(_) => return error(SpecificError::TooManySyncSubnetsToSign.into()), + }; + + let completed = self + .qbft_manager + .decide_instance( + ValidatorInstanceId { + validator: aggregator_pubkey, + duty: ValidatorDutyKind::SyncCommitteeAggregator, + instance_height: slot.as_usize().into(), + }, + ValidatorConsensusData { + duty: ValidatorDuty { + r#type: BEACON_ROLE_SYNC_COMMITTEE_CONTRIBUTION, + pub_key: aggregator_pubkey, + slot, + validator_index: cluster.validator_metadata.validator_index, + committee_index: 0, + committee_length: 0, + committees_at_slot: 0, + validator_committee_index: aggregator_index, + validator_sync_committee_indices: Default::default(), + }, + version: DATA_VERSION_PHASE0, + data_ssz: Box::new(DataSsz::Contributions(data)), + }, + &cluster, + ) + .await; + let data = match completed { + Ok(Completed::Success(data)) => data, + Ok(Completed::TimedOut) => return error(SpecificError::Timeout.into()), + Err(err) => return error(SpecificError::QbftError(err).into()), + }; + let data = match *data.data_ssz { + DataSsz::Contributions(data) => data, + _ => return error(SpecificError::InvalidQbftData.into()), + }; + + let domain_hash = self.get_domain(epoch, Domain::ContributionAndProof); + let signing_futures = data + .into_iter() + .map(|contribution| async move { + let message = ContributionAndProof { + aggregator_index, + contribution: contribution.contribution, + selection_proof: contribution.selection_proof_sig, + }; + let signing_root = message.signing_root(domain_hash); + self.collect_signature(aggregator_pubkey, signing_root) + .await + .map(|signature| SignedContributionAndProof { message, signature }) + }) + .collect::>(); + + join_all(signing_futures).await + } } -#[derive(Debug)] +pub struct ContributionAndProofSigningData { + contribution: SyncCommitteeContribution, + selection_proof: SyncSelectionProof, +} + +#[derive(Debug, Clone)] pub enum SpecificError { - ExitsUnsupported, + Unsupported, SignatureCollectionFailed(CollectionError), ArithError(ArithError), QbftError(QbftError), Timeout, InvalidQbftData, + TooManySyncSubnetsToSign, } impl From for SpecificError { @@ -354,7 +491,7 @@ impl ValidatorStore for AnchorValidatorStore { _voluntary_exit: VoluntaryExit, ) -> Result { // there should be no situation ever where we want to sign an exit - Err(Error::SpecificError(SpecificError::ExitsUnsupported)) + Err(Error::SpecificError(SpecificError::Unsupported)) } async fn sign_validator_registration_data( @@ -425,8 +562,8 @@ impl ValidatorStore for AnchorValidatorStore { _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), }; - let signing_context = self.get_domain(signing_epoch, Domain::AggregateAndProof); - let signing_root = message.signing_root(signing_context); + let domain_hash = self.get_domain(signing_epoch, Domain::AggregateAndProof); + let signing_root = message.signing_root(domain_hash); let signature = self .collect_signature(validator_pubkey, signing_root) .await?; @@ -471,41 +608,13 @@ impl ValidatorStore for AnchorValidatorStore { async fn produce_sync_committee_signature( &self, - slot: Slot, - beacon_block_root: Hash256, + _slot: Slot, + _beacon_block_root: Hash256, _validator_index: u64, - validator_pubkey: &PublicKeyBytes, + _validator_pubkey: &PublicKeyBytes, ) -> Result { - let cluster = self.cluster(*validator_pubkey)?; - - let completed = self - .qbft_manager - .decide_instance( - CommitteeInstanceId { - committee: cluster.cluster_id, - instance_height: slot.as_usize().into(), - }, - BeaconVote { - block_root: beacon_block_root, - // todo noooo. where do we get those here? - // -> actively fetch is possibly inefficient - // -> cant wait for sign_attestation, as that might not be called - // -> with timeout?... eh - // -> modifying interface should be ruled out - // -> modified sync_committee_service? that always triggers an attestation - // -> modified attestation_service? that submits the attestation data every slot? - source: Checkpoint::default(), - target: Checkpoint::default(), - }, - &cluster, - ) - .await - .map_err(SpecificError::from)?; - let _data = match completed { - Completed::TimedOut => return Err(Error::SpecificError(SpecificError::Timeout)), - Completed::Success(data) => data, - }; - todo!() + // use `produce_sync_committee_signature_with_full_vote` instead + Err(Error::SpecificError(SpecificError::Unsupported)) } async fn produce_signed_contribution_and_proof( @@ -515,9 +624,8 @@ impl ValidatorStore for AnchorValidatorStore { _contribution: SyncCommitteeContribution, _selection_proof: SyncSelectionProof, ) -> Result, Error> { - // todo: ah, we need to vote for all subnets at once here -> shift interface ton one call - // for all contributions - todo!() + // use `produce_signed_contribution_and_proofs` instead + Err(Error::SpecificError(SpecificError::Unsupported)) } fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { diff --git a/anchor/validator_store/src/sync_committee_service.rs b/anchor/validator_store/src/sync_committee_service.rs new file mode 100644 index 000000000..2b1678259 --- /dev/null +++ b/anchor/validator_store/src/sync_committee_service.rs @@ -0,0 +1,564 @@ +//! Shamelessly stolen from lighthouse and adapted for anchor purposes: +//! - Provide attestation data when requesting signature to ensure valid `BeaconVote` for qbft +//! - One aggregation request per validator including every subnet + +use crate::{AnchorValidatorStore, ContributionAndProofSigningData}; +use beacon_node_fallback::{ApiTopic, BeaconNodeFallback}; +use futures::future::join_all; +use futures::future::FutureExt; +use slot_clock::SlotClock; +use ssv_types::message::BeaconVote; +use std::collections::HashMap; +use std::ops::Deref; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Arc; +use task_executor::TaskExecutor; +use tokio::time::{sleep, sleep_until, Duration, Instant}; +use tracing::{debug, error, info, trace}; +use types::{ + ChainSpec, EthSpec, Hash256, PublicKeyBytes, Slot, SyncCommitteeSubscription, + SyncContributionData, SyncDuty, SyncSelectionProof, SyncSubnetId, +}; +use validator_services::duties_service::DutiesService; +use validator_store::Error as ValidatorStoreError; + +pub const SUBSCRIPTION_LOOKAHEAD_EPOCHS: u64 = 4; + +pub struct SyncCommitteeService { + inner: Arc>, +} + +impl Clone for SyncCommitteeService { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + } + } +} + +impl Deref for SyncCommitteeService { + type Target = Inner; + + fn deref(&self) -> &Self::Target { + self.inner.deref() + } +} + +pub struct Inner { + duties_service: Arc, T>>, + validator_store: Arc>, + slot_clock: T, + beacon_nodes: Arc>, + executor: TaskExecutor, + /// Boolean to track whether the service has posted subscriptions to the BN at least once. + /// + /// This acts as a latch that fires once upon start-up, and then never again. + first_subscription_done: AtomicBool, +} + +impl SyncCommitteeService { + pub fn new( + duties_service: Arc, T>>, + validator_store: Arc>, + slot_clock: T, + beacon_nodes: Arc>, + executor: TaskExecutor, + ) -> Self { + Self { + inner: Arc::new(Inner { + duties_service, + validator_store, + slot_clock, + beacon_nodes, + executor, + first_subscription_done: AtomicBool::new(false), + }), + } + } + + /// Check if the Altair fork has been activated and therefore sync duties should be performed. + /// + /// Slot clock errors are mapped to `false`. + fn altair_fork_activated(&self) -> bool { + self.duties_service + .spec + .altair_fork_epoch + .and_then(|fork_epoch| { + let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); + Some(current_epoch >= fork_epoch) + }) + .unwrap_or(false) + } + + pub fn start_update_service(self, spec: &ChainSpec) -> Result<(), String> { + let slot_duration = Duration::from_secs(spec.seconds_per_slot); + let duration_to_next_slot = self + .slot_clock + .duration_to_next_slot() + .ok_or("Unable to determine duration to next slot")?; + + info!( + next_update_millis = duration_to_next_slot.as_millis(), + "Sync committee service started" + ); + + let executor = self.executor.clone(); + + let interval_fut = async move { + loop { + if let Some(duration_to_next_slot) = self.slot_clock.duration_to_next_slot() { + // Wait for contribution broadcast interval 1/3 of the way through the slot. + sleep(duration_to_next_slot + slot_duration / 3).await; + + // Do nothing if the Altair fork has not yet occurred. + if !self.altair_fork_activated() { + continue; + } + + if let Err(e) = self.spawn_contribution_tasks(slot_duration).await { + error!( + error = ?e, + "Failed to spawn sync contribution tasks" + ) + } else { + trace!("Spawned sync contribution tasks") + } + + // Do subscriptions for future slots/epochs. + self.spawn_subscription_tasks(); + } else { + error!("Failed to read slot clock"); + // If we can't read the slot clock, just wait another slot. + sleep(slot_duration).await; + } + } + }; + + executor.spawn(interval_fut, "sync_committee_service"); + Ok(()) + } + + async fn spawn_contribution_tasks(&self, slot_duration: Duration) -> Result<(), String> { + let slot = self.slot_clock.now().ok_or("Failed to read slot clock")?; + let duration_to_next_slot = self + .slot_clock + .duration_to_next_slot() + .ok_or("Unable to determine duration to next slot")?; + + // If a validator needs to publish a sync aggregate, they must do so at 2/3 + // through the slot. This delay triggers at this time + let aggregate_production_instant = Instant::now() + + duration_to_next_slot + .checked_sub(slot_duration / 3) + .unwrap_or_else(|| Duration::from_secs(0)); + + let Some(slot_duties) = self + .duties_service + .sync_duties + .get_duties_for_slot::(slot, &self.duties_service.spec) + else { + debug!("No duties known for slot {}", slot); + return Ok(()); + }; + + if slot_duties.duties.is_empty() { + debug!(%slot, "No local validators in current sync committee"); + return Ok(()); + } + + // ANCHOR SPECIFIC - fetch source and target to enable proper qbft voting + let attestation_data = self + .beacon_nodes + .first_success(|beacon_node| async move { + let _timer = validator_metrics::start_timer_vec( + &validator_metrics::ATTESTATION_SERVICE_TIMES, + &[validator_metrics::ATTESTATIONS_HTTP_GET], + ); + beacon_node + .get_validator_attestation_data(slot, 0) + .await + .map_err(|e| format!("Failed to produce attestation data: {:?}", e)) + .map(|result| result.data) + }) + .await + .map_err(|e| e.to_string())?; + + let block_root = attestation_data.beacon_block_root; + let beacon_vote = BeaconVote { + block_root, + source: attestation_data.source, + target: attestation_data.target, + }; + + // Spawn one task to publish all of the sync committee signatures. + let validator_duties = slot_duties.duties; + let service = self.clone(); + self.inner.executor.spawn( + async move { + service + .publish_sync_committee_signatures(slot, beacon_vote, validator_duties) + .map(|_| ()) + .await + }, + "sync_committee_signature_publish", + ); + + let aggregators = slot_duties.aggregators; + let service = self.clone(); + self.inner.executor.spawn( + async move { + service + .publish_sync_committee_aggregates( + slot, + block_root, + aggregators, + aggregate_production_instant, + ) + .map(|_| ()) + .await + }, + "sync_committee_aggregate_publish", + ); + + Ok(()) + } + + /// Publish sync committee signatures. + async fn publish_sync_committee_signatures( + &self, + slot: Slot, + vote: BeaconVote, + validator_duties: Vec, + ) -> Result<(), ()> { + // Create futures to produce sync committee signatures. + let signature_futures = validator_duties.iter().map(|duty| { + let vote = vote.clone(); + async move { + match self + .validator_store + .produce_sync_committee_signature_with_full_vote( + slot, + vote.clone(), + duty.validator_index, + &duty.pubkey, + ) + .await + { + Ok(signature) => Some(signature), + Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { + // A pubkey can be missing when a validator was recently + // removed via the API. + debug!( + ?pubkey, + validator_index = duty.validator_index, + %slot, + "Missing pubkey for sync committee signature" + ); + None + } + Err(e) => { + error!( + validator_index = duty.validator_index, + %slot, + error = ?e, + "Failed to sign sync committee signature" + ); + None + } + } + } + }); + + // Execute all the futures in parallel, collecting any successful results. + let committee_signatures = &join_all(signature_futures) + .await + .into_iter() + .flatten() + .collect::>(); + + self.beacon_nodes + .request(ApiTopic::SyncCommittee, |beacon_node| async move { + beacon_node + .post_beacon_pool_sync_committee_signatures(committee_signatures) + .await + }) + .await + .map_err(|e| { + error!( + %slot, + error = %e, + "Unable to publish sync committee messages" + ); + })?; + + info!( + count = committee_signatures.len(), + head_block = ?vote.block_root, + %slot, + "Successfully published sync committee messages" + ); + + Ok(()) + } + + async fn publish_sync_committee_aggregates( + &self, + slot: Slot, + beacon_block_root: Hash256, + aggregators: HashMap>, + aggregate_instant: Instant, + ) { + sleep_until(aggregate_instant).await; + + let contributions = aggregators.keys().map(|&subnet_id| { + self.beacon_nodes + .first_success(move |beacon_node| async move { + let sync_contribution_data = SyncContributionData { + slot, + beacon_block_root, + subcommittee_index: *subnet_id, + }; + + beacon_node + .get_validator_sync_committee_contribution(&sync_contribution_data) + .await + .map(|data| data.map(|data| (subnet_id, data.data))) + }) + }); + + let contributions = join_all(contributions) + .await + .into_iter() + .filter_map(|result| match result { + Ok(Some((subnet_id, data))) => Some((*subnet_id, data)), + Ok(None) => { + error!(%slot, ?beacon_block_root, "No aggregate contribution found"); + None + } + Err(err) => { + error!( + %slot, + ?beacon_block_root, + error = %err, + "Failed to produce sync contribution" + ); + None + } + }) + .collect::>(); + + let mut aggregators_by_validator = HashMap::new(); + for (subnet, aggregators) in aggregators { + for aggregator in aggregators { + if let Some(contribution) = contributions.get(&subnet).cloned() { + aggregators_by_validator + .entry((aggregator.0, aggregator.1)) + .or_insert(vec![]) + .push(ContributionAndProofSigningData { + contribution, + selection_proof: aggregator.2, + }); + } + } + } + + // Create futures to produce signed contributions. + let signature_futures = aggregators_by_validator.into_iter().map( + |((aggregator_index, aggregator_pk), data)| { + self.validator_store.produce_signed_contribution_and_proofs( + aggregator_index, + aggregator_pk, + data, + ) + }, + ); + + // Execute all the futures in parallel, collecting any successful results. + let signed_contributions = &join_all(signature_futures) + .await + .into_iter() + .flatten() + .filter_map(|result| match result { + Ok(signed_contribution) => Some(signed_contribution), + Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { + // A pubkey can be missing when a validator was recently + // removed via the API. + debug!(?pubkey, %slot, "Missing pubkey for sync contribution"); + None + } + Err(e) => { + error!( + %slot, + error = ?e, + "Unable to sign sync committee contribution" + ); + None + } + }) + .collect::>(); + + // Publish to the beacon node. + if let Err(err) = self + .beacon_nodes + .first_success(|beacon_node| async move { + beacon_node + .post_validator_contribution_and_proofs(signed_contributions) + .await + }) + .await + { + error!( + %slot, + error = %err, + "Unable to publish signed contributions and proofs" + ); + } + + info!( + beacon_block_root = %beacon_block_root, + %slot, + "Successfully published sync contributions" + ); + } + + fn spawn_subscription_tasks(&self) { + let service = self.clone(); + + self.inner.executor.spawn( + async move { + service.publish_subscriptions().await.unwrap_or_else(|e| { + error!( + error = ?e, + "Error publishing subscriptions" + ) + }); + }, + "sync_committee_subscription_publish", + ); + } + + async fn publish_subscriptions(self) -> Result<(), String> { + let spec = &self.duties_service.spec; + let slot = self.slot_clock.now().ok_or("Failed to read slot clock")?; + + let mut duty_slots = vec![]; + let mut all_succeeded = true; + + // At the start of every epoch during the current period, re-post the subscriptions + // to the beacon node. This covers the case where the BN has forgotten the subscriptions + // due to a restart, or where the VC has switched to a fallback BN. + let current_period = sync_period_of_slot::(slot, spec)?; + + if !self.first_subscription_done.load(Ordering::Relaxed) + || slot.as_u64() % E::slots_per_epoch() == 0 + { + duty_slots.push((slot, current_period)); + } + + // Near the end of the current period, push subscriptions for the next period to the + // beacon node. We aggressively push every slot in the lead-up, as this is the main way + // that we want to ensure that the BN is subscribed (well in advance). + let lookahead_slot = slot + SUBSCRIPTION_LOOKAHEAD_EPOCHS * E::slots_per_epoch(); + + let lookahead_period = sync_period_of_slot::(lookahead_slot, spec)?; + + if lookahead_period > current_period { + duty_slots.push((lookahead_slot, lookahead_period)); + } + + if duty_slots.is_empty() { + return Ok(()); + } + + // Collect subscriptions. + let mut subscriptions = vec![]; + + for (duty_slot, sync_committee_period) in duty_slots { + debug!(%duty_slot, %slot, "Fetching subscription duties"); + match self + .duties_service + .sync_duties + .get_duties_for_slot::(duty_slot, spec) + { + Some(duties) => subscriptions.extend(subscriptions_from_sync_duties( + duties.duties, + sync_committee_period, + spec, + )), + None => { + debug!( + slot = %duty_slot, + "No duties for subscription" + ); + all_succeeded = false; + } + } + } + + if subscriptions.is_empty() { + debug!(%slot, "No sync subscriptions to send"); + return Ok(()); + } + + // Post subscriptions to BN. + debug!( + count = subscriptions.len(), + "Posting sync subscriptions to BN" + ); + let subscriptions_slice = &subscriptions; + + for subscription in subscriptions_slice { + debug!( + validator_index = subscription.validator_index, + validator_sync_committee_indices = ?subscription.sync_committee_indices, + until_epoch = %subscription.until_epoch, + "Subscription" + ); + } + + if let Err(e) = self + .beacon_nodes + .request(ApiTopic::Subscriptions, |beacon_node| async move { + beacon_node + .post_validator_sync_committee_subscriptions(subscriptions_slice) + .await + }) + .await + { + error!( + %slot, + error = %e, + "Unable to post sync committee subscriptions" + ); + all_succeeded = false; + } + + // Disable first-subscription latch once all duties have succeeded once. + if all_succeeded { + self.first_subscription_done.store(true, Ordering::Relaxed); + } + + Ok(()) + } +} + +fn sync_period_of_slot(slot: Slot, spec: &ChainSpec) -> Result { + slot.epoch(E::slots_per_epoch()) + .sync_committee_period(spec) + .map_err(|e| format!("Error computing sync period: {:?}", e)) +} + +fn subscriptions_from_sync_duties( + duties: Vec, + sync_committee_period: u64, + spec: &ChainSpec, +) -> impl Iterator { + let until_epoch = spec.epochs_per_sync_committee_period * (sync_committee_period + 1); + duties + .into_iter() + .map(move |duty| SyncCommitteeSubscription { + validator_index: duty.validator_index, + sync_committee_indices: duty.validator_sync_committee_indices, + until_epoch, + }) +} From 7ce3eb6f665571fbeb117c18711b6cc0bd92463f Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Thu, 9 Jan 2025 14:07:47 +0100 Subject: [PATCH 20/21] blocks can be decided blinded and unblinded independent from initial value, initial slashing protection --- Cargo.lock | 395 ++++++------------------------ Cargo.toml | 59 ++--- anchor/client/Cargo.toml | 1 + anchor/client/src/lib.rs | 16 +- anchor/validator_store/Cargo.toml | 3 +- anchor/validator_store/src/lib.rs | 295 ++++++++++++++++------ 6 files changed, 344 insertions(+), 425 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 439824274..37434cb07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,7 +123,7 @@ dependencies = [ "proptest-derive", "rand", "ruint", - "rustc-hash 2.1.0", + "rustc-hash", "serde", "sha3", "tiny-keccak", @@ -178,11 +178,12 @@ dependencies = [ "dashmap", "eth2", "futures", - "processor", + "parking_lot", "qbft", "qbft_manager", "safe_arith", "signature_collector", + "slashing_protection", "slot_clock", "ssv_types", "task_executor", @@ -493,7 +494,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 0.38.42", + "rustix 0.38.43", "slab", "tracing", "windows-sys 0.59.0", @@ -505,7 +506,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.0", "event-listener-strategy", "pin-project-lite", ] @@ -671,7 +672,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon_node_fallback" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "eth2", "futures", @@ -686,29 +687,6 @@ dependencies = [ "validator_metrics", ] -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.6.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.95", - "which", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -778,7 +756,7 @@ dependencies = [ [[package]] name = "bls" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "arbitrary", @@ -904,15 +882,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -981,17 +950,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.24" @@ -1036,7 +994,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clap_utils" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "clap", @@ -1072,6 +1030,7 @@ dependencies = [ "sensitive_url", "serde", "signature_collector", + "slashing_protection", "slot_clock", "ssv_types", "strum", @@ -1085,15 +1044,6 @@ dependencies = [ "version", ] -[[package]] -name = "cmake" -version = "0.1.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" -dependencies = [ - "cc", -] - [[package]] name = "colorchoice" version = "1.0.3" @@ -1103,7 +1053,7 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compare_fields" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "itertools 0.10.5", ] @@ -1111,7 +1061,7 @@ dependencies = [ [[package]] name = "compare_fields_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "quote", "syn 1.0.109", @@ -1519,12 +1469,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "db-key" -version = "0.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72465f46d518f6015d9cf07f7f3013a95dd6b9c2747c3d65ae0cce43929d14f" - [[package]] name = "delay_map" version = "0.4.0" @@ -1649,7 +1593,7 @@ dependencies = [ [[package]] name = "directory" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "clap", "clap_utils", @@ -1901,17 +1845,19 @@ dependencies = [ [[package]] name = "eth2" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "derivative", + "enr", "eth2_keystore", "ethereum_serde_utils", "ethereum_ssz", "ethereum_ssz_derive", "futures", "futures-util", - "lighthouse_network", + "libp2p-identity", "mediatype", + "multiaddr", "pretty_reqwest_error", "procfs", "proto_array", @@ -1923,7 +1869,6 @@ dependencies = [ "serde_json", "slashing_protection", "ssz_types", - "store", "types", "zeroize", ] @@ -1931,7 +1876,7 @@ dependencies = [ [[package]] name = "eth2_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "paste", "types", @@ -1940,7 +1885,7 @@ dependencies = [ [[package]] name = "eth2_interop_keypairs" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "bls", "ethereum_hashing", @@ -1953,7 +1898,7 @@ dependencies = [ [[package]] name = "eth2_key_derivation" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "bls", "num-bigint-dig", @@ -1965,7 +1910,7 @@ dependencies = [ [[package]] name = "eth2_keystore" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "aes 0.7.5", "bls", @@ -1987,7 +1932,7 @@ dependencies = [ [[package]] name = "eth2_network_config" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "bytes", "discv5", @@ -2060,9 +2005,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -2075,7 +2020,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.0", "pin-project-lite", ] @@ -2151,12 +2096,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "ffi-opaque" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec54ac60a7f2ee9a97cad9946f9bf629a3bc6a7ae59e68983dc9318f5a54b81a" - [[package]] name = "fiat-crypto" version = "0.2.9" @@ -2176,7 +2115,7 @@ dependencies = [ [[package]] name = "filesystem" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "winapi", "windows-acl", @@ -2197,7 +2136,7 @@ dependencies = [ [[package]] name = "fixed_bytes" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "safe_arith", @@ -2462,7 +2401,7 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "gossipsub" version = "0.5.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "async-channel", "asynchronous-codec", @@ -2491,7 +2430,7 @@ dependencies = [ [[package]] name = "graffiti_file" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "bls", "serde", @@ -2705,15 +2644,6 @@ dependencies = [ "hmac 0.8.1", ] -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - [[package]] name = "hostname" version = "0.3.1" @@ -3178,20 +3108,11 @@ dependencies = [ [[package]] name = "int_to_bytes" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "bytes", ] -[[package]] -name = "integer-sqrt" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" -dependencies = [ - "num-traits", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -3247,15 +3168,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -3326,7 +3238,7 @@ dependencies = [ [[package]] name = "kzg" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "arbitrary", "c-kzg", @@ -3351,35 +3263,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "leveldb" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32651baaaa5596b3a6e0bee625e73fd0334c167db0ea5ac68750ef9a629a2d6a" -dependencies = [ - "db-key", - "leveldb-sys", - "libc", -] - -[[package]] -name = "leveldb-sys" -version = "2.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd94a4d0242a437e5e41a27c782b69a624469ca1c4d1e5cb3c337f74a8031d4" -dependencies = [ - "cmake", - "ffi-opaque", - "libc", - "num_cpus", -] - [[package]] name = "libc" version = "0.2.169" @@ -3410,16 +3293,6 @@ dependencies = [ "rle-decode-fast", ] -[[package]] -name = "libloading" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - [[package]] name = "libm" version = "0.2.11" @@ -3921,7 +3794,7 @@ dependencies = [ [[package]] name = "lighthouse_network" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -3931,6 +3804,7 @@ dependencies = [ "dirs 3.0.2", "discv5", "either", + "eth2", "ethereum_ssz", "ethereum_ssz_derive", "fnv", @@ -3970,7 +3844,7 @@ dependencies = [ [[package]] name = "lighthouse_version" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "git-version", "target_info", @@ -3990,9 +3864,9 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -4019,7 +3893,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logging" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "chrono", "metrics", @@ -4059,7 +3933,7 @@ dependencies = [ [[package]] name = "lru_cache" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "fnv", ] @@ -4124,7 +3998,7 @@ dependencies = [ [[package]] name = "merkle_proof" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -4158,7 +4032,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "prometheus", ] @@ -4742,7 +4616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.9", + "thiserror 2.0.10", "ucd-trie", ] @@ -4810,7 +4684,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.42", + "rustix 0.38.43", "tracing", "windows-sys 0.59.0", ] @@ -4856,22 +4730,12 @@ dependencies = [ [[package]] name = "pretty_reqwest_error" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "reqwest", "sensitive_url", ] -[[package]] -name = "prettyplease" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483f8c21f64f3ea09fe0f30f5d48c3e8eefe5dac9129f0075f76593b4c1da705" -dependencies = [ - "proc-macro2", - "syn 2.0.95", -] - [[package]] name = "primeorder" version = "0.13.6" @@ -5011,7 +4875,7 @@ dependencies = [ [[package]] name = "proto_array" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "ethereum_ssz", "ethereum_ssz_derive", @@ -5109,10 +4973,10 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.0", + "rustc-hash", "rustls 0.23.20", "socket2", - "thiserror 2.0.9", + "thiserror 2.0.10", "tokio", "tracing", ] @@ -5127,11 +4991,11 @@ dependencies = [ "getrandom", "rand", "ring 0.17.8", - "rustc-hash 2.1.0", + "rustc-hash", "rustls 0.23.20", "rustls-pki-types", "slab", - "thiserror 2.0.9", + "thiserror 2.0.10", "tinyvec", "tracing", "web-time", @@ -5545,12 +5409,6 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.0" @@ -5606,14 +5464,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.14", + "linux-raw-sys 0.4.15", "windows-sys 0.59.0", ] @@ -5720,7 +5578,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe_arith" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" [[package]] name = "salsa20" @@ -5841,7 +5699,7 @@ dependencies = [ [[package]] name = "sensitive_url" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "serde", "url", @@ -6038,7 +5896,7 @@ dependencies = [ [[package]] name = "slashing_protection" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "arbitrary", "ethereum_serde_utils", @@ -6157,7 +6015,7 @@ dependencies = [ [[package]] name = "slot_clock" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "metrics", "parking_lot", @@ -6265,67 +6123,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "state_processing" -version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" -dependencies = [ - "arbitrary", - "bls", - "derivative", - "ethereum_hashing", - "ethereum_ssz", - "ethereum_ssz_derive", - "int_to_bytes", - "integer-sqrt", - "itertools 0.10.5", - "merkle_proof", - "metrics", - "rand", - "rayon", - "safe_arith", - "smallvec", - "ssz_types", - "test_random_derive", - "tree_hash", - "types", -] - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "store" -version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" -dependencies = [ - "bls", - "db-key", - "directory", - "ethereum_ssz", - "ethereum_ssz_derive", - "itertools 0.10.5", - "leveldb", - "logging", - "lru", - "metrics", - "parking_lot", - "safe_arith", - "serde", - "slog", - "sloggers", - "smallvec", - "state_processing", - "strum", - "superstruct", - "types", - "xdelta3", - "zstd 0.13.2", -] - [[package]] name = "strsim" version = "0.10.0" @@ -6383,7 +6186,7 @@ dependencies = [ [[package]] name = "swap_or_not_shuffle" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "ethereum_hashing", @@ -6498,7 +6301,7 @@ checksum = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" [[package]] name = "task_executor" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "async-channel", "futures", @@ -6520,7 +6323,7 @@ dependencies = [ "fastrand", "getrandom", "once_cell", - "rustix 0.38.42", + "rustix 0.38.43", "windows-sys 0.59.0", ] @@ -6541,14 +6344,14 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5352447f921fda68cf61b4101566c0bdb5104eff6804d0678e5227580ab6a4e9" dependencies = [ - "rustix 0.38.42", + "rustix 0.38.43", "windows-sys 0.59.0", ] [[package]] name = "test_random_derive" version = "0.2.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "quote", "syn 1.0.109", @@ -6565,11 +6368,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" dependencies = [ - "thiserror-impl 2.0.9", + "thiserror-impl 2.0.10", ] [[package]] @@ -6585,9 +6388,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.9" +version = "2.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" dependencies = [ "proc-macro2", "quote", @@ -6680,9 +6483,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.42.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", @@ -6707,9 +6510,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -6951,7 +6754,7 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "types" version = "0.2.1" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7114,7 +6917,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "unused_port" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "lru_cache", "parking_lot", @@ -7162,7 +6965,7 @@ dependencies = [ [[package]] name = "validator_metrics" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "metrics", ] @@ -7170,7 +6973,7 @@ dependencies = [ [[package]] name = "validator_services" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "beacon_node_fallback", "bls", @@ -7193,7 +6996,7 @@ dependencies = [ [[package]] name = "validator_store" version = "0.1.0" -source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#4510b736581431aedc8719b0fa983d75c9f62da4" +source = "git+https://github.com/dknopik/lighthouse?branch=modularize-validator-store#6ad04b0075cb91e9f618254eb896cb07b485c4ac" dependencies = [ "slashing_protection", "types", @@ -7368,18 +7171,6 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.42", -] - [[package]] name = "widestring" version = "0.4.3" @@ -7747,25 +7538,11 @@ dependencies = [ "time", ] -[[package]] -name = "xdelta3" -version = "0.1.5" -source = "git+http://github.com/sigp/xdelta3-rs?rev=50d63cdf1878e5cf3538e9aae5eed34a22c64e4a#50d63cdf1878e5cf3538e9aae5eed34a22c64e4a" -dependencies = [ - "bindgen", - "cc", - "futures-io", - "futures-util", - "libc", - "log", - "rand", -] - [[package]] name = "xml-rs" -version = "0.8.24" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8b391c9a790b496184c29f7f93b9ed5b16abb306c05415b68bcc16e4d06432" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" [[package]] name = "xmltree" @@ -7942,7 +7719,7 @@ dependencies = [ "pbkdf2 0.11.0", "sha1", "time", - "zstd 0.11.2+zstd.1.5.2", + "zstd", ] [[package]] @@ -7951,16 +7728,7 @@ version = "0.11.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" dependencies = [ - "zstd-safe 5.0.2+zstd.1.5.2", -] - -[[package]] -name = "zstd" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" -dependencies = [ - "zstd-safe 7.2.1", + "zstd-safe", ] [[package]] @@ -7973,15 +7741,6 @@ dependencies = [ "zstd-sys", ] -[[package]] -name = "zstd-safe" -version = "7.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" -dependencies = [ - "zstd-sys", -] - [[package]] name = "zstd-sys" version = "2.0.13+zstd.1.5.6" diff --git a/Cargo.toml b/Cargo.toml index f1a0ade97..d75b7ba8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,46 +20,42 @@ resolver = "2" edition = "2021" [workspace.dependencies] -client = { path = "anchor/client" } -qbft = { path = "anchor/common/qbft" } -http_api = { path = "anchor/http_api" } -http_metrics = { path = "anchor/http_metrics" } -network = { path = "anchor/network" } -version = { path = "anchor/common/version" } -processor = { path = "anchor/processor" } anchor_validator_store = { path = "anchor/validator_store" } -ssv_types = { path = "anchor/common/ssv_types" } -signature_collector = { path = "anchor/signature_collector" } -qbft_manager = { path = "anchor/qbft_manager" } -lighthouse_network = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -task_executor = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store", default-features = false, features = [ "tracing", ] } -metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -validator_metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -sensitive_url = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -slot_clock = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -unused_port = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -types = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -validator_services = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -eth2_config = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -eth2 = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -validator_store = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -beacon_node_fallback = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -safe_arith = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } -derive_more = { version = "1.0.0", features = ["full"] } async-channel = "1.9" axum = "0.7.7" +base64 = "0.22.1" +beacon_node_fallback = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } clap = { version = "4.5.15", features = ["derive", "wrap_help"] } +client = { path = "anchor/client" } dashmap = "6.1.0" -discv5 = "0.9.0" +derive_more = { version = "1.0.0", features = ["full"] } dirs = "5.0.1" +discv5 = "0.9.0" either = "1.13.0" +eth2 = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +eth2_config = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } futures = "0.3.30" -tower-http = { version = "0.6", features = ["cors"] } +http_api = { path = "anchor/http_api" } +http_metrics = { path = "anchor/http_metrics" } hyper = "1.4" +lighthouse_network = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +network = { path = "anchor/network" } num_cpus = "1" +openssl = "0.10.68" parking_lot = "0.12" +processor = { path = "anchor/processor" } +qbft = { path = "anchor/common/qbft" } +qbft_manager = { path = "anchor/qbft_manager" } +safe_arith = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +sensitive_url = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } serde = { version = "1.0.208", features = ["derive"] } +signature_collector = { path = "anchor/signature_collector" } +slashing_protection = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +slot_clock = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +ssv_types = { path = "anchor/common/ssv_types" } strum = { version = "0.24", features = ["derive"] } +task_executor = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store", default-features = false, features = [ "tracing", ] } tokio = { version = "1.39.2", features = [ "rt", "rt-multi-thread", @@ -67,12 +63,17 @@ tokio = { version = "1.39.2", features = [ "signal", "macros", ] } +tower-http = { version = "0.6", features = ["cors"] } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["fmt", "env-filter"] } tree_hash = "0.8" tree_hash_derive = "0.8" -base64 = "0.22.1" -openssl = "0.10.68" +types = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +unused_port = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_metrics = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_services = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +validator_store = { git = "https://github.com/dknopik/lighthouse", branch = "modularize-validator-store" } +version = { path = "anchor/common/version" } [profile.maxperf] inherits = "release" diff --git a/anchor/client/Cargo.toml b/anchor/client/Cargo.toml index 5195d7028..84562eba0 100644 --- a/anchor/client/Cargo.toml +++ b/anchor/client/Cargo.toml @@ -27,6 +27,7 @@ qbft_manager = { workspace = true } sensitive_url = { workspace = true } serde = { workspace = true } signature_collector = { workspace = true } +slashing_protection = { workspace = true } slot_clock = { workspace = true } ssv_types = { workspace = true } strum = { workspace = true } diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index 2f4371d0b..ca4d2050a 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -18,6 +18,7 @@ use parking_lot::RwLock; use qbft_manager::QbftManager; use sensitive_url::SensitiveUrl; use signature_collector::SignatureCollectorManager; +use slashing_protection::SlashingDatabase; use slot_clock::{SlotClock, SystemTimeSlotClock}; use ssv_types::OperatorId; use std::fs::File; @@ -39,6 +40,9 @@ use validator_services::duties_service; use validator_services::duties_service::DutiesServiceBuilder; use validator_services::preparation_service::PreparationServiceBuilder; +/// The filename within the `validators` directory that contains the slashing protection DB. +const SLASHING_PROTECTION_FILENAME: &str = "slashing_protection.sqlite"; + /// The time between polls when waiting for genesis. const WAITING_FOR_GENESIS_POLL_TIME: Duration = Duration::from_secs(12); @@ -122,6 +126,16 @@ impl Client { // Spawn the network listening task executor.spawn(network.run(), "network"); + // Initialize slashing protection. + let slashing_db_path = config.data_dir.join(SLASHING_PROTECTION_FILENAME); + let slashing_protection = + SlashingDatabase::open_or_create(&slashing_db_path).map_err(|e| { + format!( + "Failed to open or create slashing protection database: {:?}", + e + ) + })?; + let last_beacon_node_index = config .beacon_nodes .len() @@ -276,9 +290,9 @@ impl Client { }; let validator_store = Arc::new(AnchorValidatorStore::<_, E>::new( - processor_senders, signature_collector, qbft_manager, + slashing_protection, spec.clone(), genesis_validators_root, OperatorId(123), diff --git a/anchor/validator_store/Cargo.toml b/anchor/validator_store/Cargo.toml index 3a1ae3be7..e0ed9732f 100644 --- a/anchor/validator_store/Cargo.toml +++ b/anchor/validator_store/Cargo.toml @@ -10,11 +10,12 @@ beacon_node_fallback = { workspace = true } dashmap = { workspace = true } eth2 = { workspace = true } futures = "0.3.31" -processor = { workspace = true } +parking_lot = { workspace = true } qbft = { workspace = true } qbft_manager = { workspace = true } safe_arith = { workspace = true } signature_collector = { workspace = true } +slashing_protection = { workspace = true } slot_clock = { workspace = true } ssv_types = { workspace = true } task_executor = { workspace = true } diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 7f9abcae6..392f893b8 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -2,12 +2,14 @@ pub mod sync_committee_service; use dashmap::DashMap; use futures::future::join_all; +use parking_lot::Mutex; use qbft::Completed; use qbft_manager::{ CommitteeInstanceId, QbftError, QbftManager, ValidatorDutyKind, ValidatorInstanceId, }; use safe_arith::{ArithError, SafeArith}; use signature_collector::{CollectionError, SignatureCollectorManager, SignatureRequest}; +use slashing_protection::{NotSafe, Safe, SlashingDatabase}; use slot_clock::SlotClock; use ssv_types::message::{ BeaconVote, Contribution, DataSsz, ValidatorConsensusData, ValidatorDuty, @@ -16,8 +18,9 @@ use ssv_types::message::{ DATA_VERSION_PHASE0, DATA_VERSION_UNKNOWN, }; use ssv_types::{Cluster, OperatorId}; +use std::fmt::Debug; use std::sync::Arc; -use tracing::{error, warn}; +use tracing::{error, info, warn}; use types::attestation::Attestation; use types::beacon_block::BeaconBlock; use types::graffiti::Graffiti; @@ -36,14 +39,20 @@ use types::validator_registration_data::{ }; use types::voluntary_exit::VoluntaryExit; use types::{ - AbstractExecPayload, Address, AggregateAndProof, BlindedPayload, ChainSpec, - ContributionAndProof, Domain, EthSpec, FullPayload, Hash256, PublicKeyBytes, SecretKey, - Signature, SignedRoot, SyncAggregatorSelectionData, VariableList, + AbstractExecPayload, Address, AggregateAndProof, ChainSpec, ContributionAndProof, Domain, + EthSpec, Hash256, PublicKeyBytes, SecretKey, Signature, SignedRoot, + SyncAggregatorSelectionData, VariableList, }; use validator_store::{ - DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignBlock, ValidatorStore, + DoppelgangerStatus, Error as ValidatorStoreError, ProposalData, SignedBlock, UnsignedBlock, + ValidatorStore, }; +/// Number of epochs of slashing protection history to keep. +/// +/// This acts as a maximum safe-guard against clock drift. +const SLASHING_PROTECTION_HISTORY_EPOCHS: u64 = 512; + struct InitializedCluster { pub cluster: Cluster, pub decrypted_key_share: SecretKey, @@ -53,6 +62,8 @@ pub struct AnchorValidatorStore { clusters: DashMap, signature_collector: Arc, qbft_manager: Arc>, + slashing_protection: SlashingDatabase, + slashing_protection_last_prune: Arc>, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, @@ -60,9 +71,9 @@ pub struct AnchorValidatorStore { impl AnchorValidatorStore { pub fn new( - _processor: processor::Senders, signature_collector: Arc, qbft_manager: Arc>, + slashing_protection: SlashingDatabase, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, @@ -71,12 +82,32 @@ impl AnchorValidatorStore { clusters: DashMap::new(), signature_collector, qbft_manager, + slashing_protection, + slashing_protection_last_prune: Arc::new(Mutex::new(Epoch::new(0))), spec, genesis_validators_root, operator_id, } } + pub fn add_cluster( + &self, + cluster: Cluster, + decrypted_key_share: SecretKey, + ) -> Result<(), Error> { + let pubkey_bytes = cluster.validator_metadata.validator_pubkey.compress(); + self.clusters.insert( + pubkey_bytes, + InitializedCluster { + cluster, + decrypted_key_share, + }, + ); + self.slashing_protection + .register_validator(pubkey_bytes) + .map_err(Error::Slashable) + } + fn cluster(&self, validator_pubkey: PublicKeyBytes) -> Result { self.clusters .get(&validator_pubkey) @@ -122,7 +153,7 @@ impl AnchorValidatorStore { Ok((*collector.await.map_err(SpecificError::from)?).clone()) } - async fn sign_abstract_block< + async fn decide_abstract_block< P: AbstractExecPayload, F: FnOnce(BeaconBlock) -> DataSsz, >( @@ -145,8 +176,6 @@ impl AnchorValidatorStore { }); } - // todo slashing protection - let cluster = self.cluster(validator_pubkey)?; // first, we have to get to consensus @@ -191,6 +220,31 @@ impl AnchorValidatorStore { Ok(*data.data_ssz) } + async fn sign_abstract_block>( + &self, + validator_pubkey: PublicKeyBytes, + block: BeaconBlock, + ) -> Result, Error> { + let domain_hash = self.get_domain(block.epoch(), Domain::BeaconProposer); + + let header = block.block_header(); + handle_slashing_check_result( + self.slashing_protection.check_and_insert_block_proposal( + &validator_pubkey, + &header, + domain_hash, + ), + &header, + "block", + )?; + + let signing_root = block.signing_root(domain_hash); + let signature = self + .collect_signature(validator_pubkey, signing_root) + .await?; + Ok(SignedBeaconBlock::from_block(block, signature)) + } + pub async fn produce_sync_committee_signature_with_full_vote( &self, slot: Slot, @@ -319,6 +373,48 @@ impl AnchorValidatorStore { } } +fn handle_slashing_check_result( + slashing_status: Result, + object: impl Debug, + kind: &'static str, +) -> Result<(), Error> { + match slashing_status { + // We can safely sign this attestation. + Ok(Safe::Valid) => Ok(()), + Ok(Safe::SameData) => { + warn!("Skipping signing of previously signed {kind}",); + validator_metrics::inc_counter_vec( + &validator_metrics::SIGNED_ATTESTATIONS_TOTAL, + &[validator_metrics::SAME_DATA], + ); + Err(Error::SameData) + } + Err(NotSafe::UnregisteredValidator(pk)) => { + error!( + "public_key" = format!("{:?}", pk), + "Internal error: validator was not properly registered for slashing protection", + ); + validator_metrics::inc_counter_vec( + &validator_metrics::SIGNED_ATTESTATIONS_TOTAL, + &[validator_metrics::UNREGISTERED], + ); + Err(Error::Slashable(NotSafe::UnregisteredValidator(pk))) + } + Err(e) => { + error!( + "object" = format!("{:?}", object), + "error" = format!("{:?}", e), + "Not signing slashable {kind}", + ); + validator_metrics::inc_counter_vec( + &validator_metrics::SIGNED_ATTESTATIONS_TOTAL, + &[validator_metrics::SLASHABLE], + ); + Err(Error::Slashable(e)) + } + } +} + pub struct ContributionAndProofSigningData { contribution: SyncCommitteeContribution, selection_proof: SyncSelectionProof, @@ -429,6 +525,47 @@ impl ValidatorStore for AnchorValidatorStore { } } + async fn sign_block( + &self, + validator_pubkey: PublicKeyBytes, + block: UnsignedBlock, + current_slot: Slot, + ) -> Result, Error> { + let data = match block { + UnsignedBlock::Full(block) => { + self.decide_abstract_block( + validator_pubkey, + block, + current_slot, + DataSsz::BeaconBlock, + ) + .await + } + UnsignedBlock::Blinded(block) => { + self.decide_abstract_block( + validator_pubkey, + block, + current_slot, + DataSsz::BlindedBeaconBlock, + ) + .await + } + }?; + + // yay - we agree! let's sign the block we agreed on + match data { + DataSsz::BeaconBlock(block) => Ok(self + .sign_abstract_block(validator_pubkey, block) + .await? + .into()), + DataSsz::BlindedBeaconBlock(block) => Ok(self + .sign_abstract_block(validator_pubkey, block) + .await? + .into()), + _ => Err(Error::SpecificError(SpecificError::InvalidQbftData)), + } + } + async fn sign_attestation( &self, validator_pubkey: PublicKeyBytes, @@ -444,8 +581,6 @@ impl ValidatorStore for AnchorValidatorStore { }); } - // todo slashing protection - let cluster = self.cluster(validator_pubkey)?; let completed = self @@ -474,6 +609,17 @@ impl ValidatorStore for AnchorValidatorStore { // yay - we agree! let's sign the att we agreed on let domain_hash = self.get_domain(current_epoch, Domain::BeaconAttester); + + handle_slashing_check_result( + self.slashing_protection.check_and_insert_attestation( + &validator_pubkey, + attestation.data(), + domain_hash, + ), + attestation.data(), + "attestation", + )?; + let signing_root = attestation.data().signing_root(domain_hash); let signature = self .collect_signature(validator_pubkey, signing_root) @@ -628,8 +774,68 @@ impl ValidatorStore for AnchorValidatorStore { Err(Error::SpecificError(SpecificError::Unsupported)) } - fn prune_slashing_protection_db(&self, _current_epoch: Epoch, _first_run: bool) { - // TODO slashing protection + // stolen from lighthouse + /// Prune the slashing protection database so that it remains performant. + /// + /// This function will only do actual pruning periodically, so it should usually be + /// cheap to call. The `first_run` flag can be used to print a more verbose message when pruning + /// runs. + fn prune_slashing_protection_db(&self, current_epoch: Epoch, first_run: bool) { + // Attempt to prune every SLASHING_PROTECTION_HISTORY_EPOCHs, with a tolerance for + // missing the epoch that aligns exactly. + let mut last_prune = self.slashing_protection_last_prune.lock(); + if current_epoch / SLASHING_PROTECTION_HISTORY_EPOCHS + <= *last_prune / SLASHING_PROTECTION_HISTORY_EPOCHS + { + return; + } + + if first_run { + info!( + "epoch" = %current_epoch, + "msg" = "pruning may take several minutes the first time it runs", + "Pruning slashing protection DB", + ); + } else { + info!( + "epoch" = %current_epoch, + "Pruning slashing protection DB", + ); + } + + let _timer = + validator_metrics::start_timer(&validator_metrics::SLASHING_PROTECTION_PRUNE_TIMES); + + let new_min_target_epoch = current_epoch.saturating_sub(SLASHING_PROTECTION_HISTORY_EPOCHS); + let new_min_slot = new_min_target_epoch.start_slot(E::slots_per_epoch()); + + let all_pubkeys: Vec<_> = self.voting_pubkeys(DoppelgangerStatus::ignored); + + if let Err(e) = self + .slashing_protection + .prune_all_signed_attestations(all_pubkeys.iter(), new_min_target_epoch) + { + error!( + "error" = ?e, + "Error during pruning of signed attestations", + ); + return; + } + + if let Err(e) = self + .slashing_protection + .prune_all_signed_blocks(all_pubkeys.iter(), new_min_slot) + { + error!( + "error" = ?e, + "Error during pruning of signed blocks", + ); + return; + } + + *last_prune = current_epoch; + + info!("Completed pruning of slashing protection DB"); } fn proposal_data(&self, pubkey: &PublicKeyBytes) -> Option { @@ -641,66 +847,3 @@ impl ValidatorStore for AnchorValidatorStore { }) } } - -impl SignBlock, SpecificError> - for AnchorValidatorStore -{ - async fn sign_block( - &self, - validator_pubkey: PublicKeyBytes, - block: BeaconBlock>, - current_slot: Slot, - ) -> Result>, ValidatorStoreError> { - let data = self - .sign_abstract_block(validator_pubkey, block, current_slot, DataSsz::BeaconBlock) - .await?; - let block = match data { - DataSsz::BeaconBlock(block) => block, - // todo what do if we agree on a blind block - _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), - }; - - // yay - we agree! let's sign the block we agreed on - let domain_hash = self.get_domain(block.epoch(), Domain::BeaconProposer); - let signing_root = block.signing_root(domain_hash); - let signature = self - .collect_signature(validator_pubkey, signing_root) - .await?; - - Ok(SignedBeaconBlock::from_block(block, signature)) - } -} - -impl SignBlock, SpecificError> - for AnchorValidatorStore -{ - async fn sign_block( - &self, - validator_pubkey: PublicKeyBytes, - block: BeaconBlock>, - current_slot: Slot, - ) -> Result>, Error> { - let data = self - .sign_abstract_block( - validator_pubkey, - block, - current_slot, - DataSsz::BlindedBeaconBlock, - ) - .await?; - let block = match data { - DataSsz::BlindedBeaconBlock(block) => block, - // todo what do if we agree on a non-blind block - _ => return Err(Error::SpecificError(SpecificError::InvalidQbftData)), - }; - - // yay - we agree! let's sign the block we agreed on - let domain_hash = self.get_domain(block.epoch(), Domain::BeaconProposer); - let signing_root = block.signing_root(domain_hash); - let signature = self - .collect_signature(validator_pubkey, signing_root) - .await?; - - Ok(SignedBeaconBlock::from_block(block, signature)) - } -} From cb46d27f063c4030737eed12e83834b6d96b0857 Mon Sep 17 00:00:00 2001 From: Daniel Knopik Date: Tue, 14 Jan 2025 13:58:42 +0100 Subject: [PATCH 21/21] clean up a bit --- Cargo.toml | 4 +- anchor/client/src/lib.rs | 5 +-- anchor/common/ssv_types/src/lib.rs | 2 - anchor/common/ssv_types/src/qbft_msgid.rs | 47 ----------------------- anchor/validator_store/src/lib.rs | 4 +- 5 files changed, 6 insertions(+), 56 deletions(-) delete mode 100644 anchor/common/ssv_types/src/qbft_msgid.rs diff --git a/Cargo.toml b/Cargo.toml index d604bc400..9d729a3e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -98,7 +98,7 @@ validator_store = { git = "https://github.com/sigp/lighthouse", branch = "anchor version = { path = "anchor/common/version" } [profile.maxperf] -codegen-units = 1 -incremental = false inherits = "release" lto = "fat" +codegen-units = 1 +incremental = false diff --git a/anchor/client/src/lib.rs b/anchor/client/src/lib.rs index ca4d2050a..2be725f44 100644 --- a/anchor/client/src/lib.rs +++ b/anchor/client/src/lib.rs @@ -90,9 +90,8 @@ impl Client { "Starting the Anchor client" ); - let mut spec = Eth2Config::mainnet().spec; - // dirty hack to be able to connect to local kurtosis devnet - Arc::get_mut(&mut spec).unwrap().genesis_fork_version = [16, 0, 0, 56]; + // TODO make configurable + let spec = Eth2Config::mainnet().spec; // Optionally start the metrics server. let http_metrics_shared_state = if config.http_metrics.enabled { diff --git a/anchor/common/ssv_types/src/lib.rs b/anchor/common/ssv_types/src/lib.rs index 89a190083..ac7cb2f5e 100644 --- a/anchor/common/ssv_types/src/lib.rs +++ b/anchor/common/ssv_types/src/lib.rs @@ -1,12 +1,10 @@ pub use cluster::{Cluster, ClusterId, ClusterMember, ValidatorIndex, ValidatorMetadata}; pub use operator::{Operator, OperatorId}; -pub use qbft_msgid::{Domain, Executor, MessageId, Role, HOLESKY_DOMAIN, MAINNET_DOMAIN}; pub use share::Share; mod cluster; pub mod message; pub mod msgid; mod operator; -mod qbft_msgid; mod share; mod sql_conversions; mod util; diff --git a/anchor/common/ssv_types/src/qbft_msgid.rs b/anchor/common/ssv_types/src/qbft_msgid.rs deleted file mode 100644 index 9210a8fb4..000000000 --- a/anchor/common/ssv_types/src/qbft_msgid.rs +++ /dev/null @@ -1,47 +0,0 @@ -// todo probably move that to its own thing -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] -pub struct Domain([u8; 4]); -pub const MAINNET_DOMAIN: Domain = Domain([0, 0, 0, 1]); -pub const HOLESKY_DOMAIN: Domain = Domain([0, 0, 5, 2]); - -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] -pub enum Role { - Committee, - Aggregator, - Proposer, - SyncCommittee, -} - -impl Role { - fn into_message_id_bytes(self) -> [u8; 4] { - match self { - Role::Committee => [0, 0, 0, 0], - Role::Aggregator => [1, 0, 0, 0], - Role::Proposer => [2, 0, 0, 0], - Role::SyncCommittee => [3, 0, 0, 0], - } - } -} - -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub enum Executor { - Committee([u8; 32]), - Validator([u8; 48]), -} - -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub struct MessageId([u8; 56]); - -impl MessageId { - pub fn new(domain: &Domain, role: Role, duty_executor: &Executor) -> Self { - let mut id = [0; 56]; - id[0..4].copy_from_slice(&domain.0); - id[4..8].copy_from_slice(&role.into_message_id_bytes()); - match duty_executor { - Executor::Committee(slice) => id[24..].copy_from_slice(slice), - Executor::Validator(slice) => id[8..].copy_from_slice(slice), - } - - MessageId(id) - } -} diff --git a/anchor/validator_store/src/lib.rs b/anchor/validator_store/src/lib.rs index 1ef15e335..4c12b566f 100644 --- a/anchor/validator_store/src/lib.rs +++ b/anchor/validator_store/src/lib.rs @@ -65,7 +65,7 @@ pub struct AnchorValidatorStore { signature_collector: Arc, qbft_manager: Arc>, slashing_protection: SlashingDatabase, - slashing_protection_last_prune: Arc>, + slashing_protection_last_prune: Mutex, spec: Arc, genesis_validators_root: Hash256, operator_id: OperatorId, @@ -85,7 +85,7 @@ impl AnchorValidatorStore { signature_collector, qbft_manager, slashing_protection, - slashing_protection_last_prune: Arc::new(Mutex::new(Epoch::new(0))), + slashing_protection_last_prune: Mutex::new(Epoch::new(0)), spec, genesis_validators_root, operator_id,