From be02372307bc4b8eaacb0d43e420b1c15dee6ea9 Mon Sep 17 00:00:00 2001 From: PoulavBhowmick03 Date: Mon, 22 Jun 2026 21:16:42 +0530 Subject: [PATCH] wrap State with Arc --- lean_client/containers/src/block.rs | 8 +++++++- lean_client/containers/tests/test_vectors/runner.rs | 4 ++-- lean_client/fork_choice/src/handlers.rs | 7 ++++--- lean_client/fork_choice/src/store.rs | 11 +++++++---- lean_client/http_api/src/test_driver.rs | 2 +- lean_client/src/main.rs | 2 +- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lean_client/containers/src/block.rs b/lean_client/containers/src/block.rs index f8a6b63..8ab3533 100644 --- a/lean_client/containers/src/block.rs +++ b/lean_client/containers/src/block.rs @@ -40,7 +40,13 @@ pub struct SignedBlock { } impl SignedBlock { - pub fn verify_signatures(&self, parent_state: State) -> Result<()> { + /// Verify all XMSS signatures in this signed block. + /// + /// Verifies each aggregated attestation proof against the participant + /// validator public keys from parent state. + /// + /// Returns `Ok(())` if all signatures are valid, or an error describing the failure. + pub fn verify_signatures(&self, parent_state: &State) -> Result<()> { let block = &self.block; let aggregated_attestations = &block.body.attestations; diff --git a/lean_client/containers/tests/test_vectors/runner.rs b/lean_client/containers/tests/test_vectors/runner.rs index 441a351..05ec860 100644 --- a/lean_client/containers/tests/test_vectors/runner.rs +++ b/lean_client/containers/tests/test_vectors/runner.rs @@ -719,7 +719,7 @@ impl TestRunner { println!(" Expecting exception: {}", exception); // Verify signatures - we expect this to fail (return Err) - match signed_block.verify_signatures(anchor_state) { + match signed_block.verify_signatures(&anchor_state) { Ok(()) => { println!( " \x1b[31m✗ FAIL: Signatures verified successfully but should have failed!\x1b[0m\n" @@ -734,7 +734,7 @@ impl TestRunner { } } - match signed_block.verify_signatures(anchor_state) { + match signed_block.verify_signatures(&anchor_state) { Ok(()) => { println!(" ✓ All signatures verified successfully"); println!("\n\x1b[32m✓ PASS\x1b[0m\n"); diff --git a/lean_client/fork_choice/src/handlers.rs b/lean_client/fork_choice/src/handlers.rs index d93083e..e6fcf7f 100644 --- a/lean_client/fork_choice/src/handlers.rs +++ b/lean_client/fork_choice/src/handlers.rs @@ -688,7 +688,7 @@ pub fn on_block( /// driving the function with synthetic signature placeholders (e.g. spec-test fixtures /// that ship unsigned blocks). pub fn verify_and_transition( - parent_state: State, + parent_state: Arc, signed_block: SignedBlock, verify_signatures: bool, ) -> Result { @@ -699,7 +699,7 @@ pub fn verify_and_transition( }); if verify_signatures { - signed_block.verify_signatures(parent_state.clone())?; + signed_block.verify_signatures(&parent_state)?; } parent_state.state_transition(&signed_block.block) } @@ -714,6 +714,7 @@ pub fn apply_verified_block( block_root: H256, ) -> Result<()> { let block = signed_block.block.clone(); + let new_state = Arc::new(new_state); tracing::debug!( block_slot = block.slot.0, @@ -724,7 +725,7 @@ pub fn apply_verified_block( ); store.blocks.insert(block_root, block.clone()); - store.states.insert(block_root, new_state.clone()); + store.states.insert(block_root, Arc::clone(&new_state)); METRICS.get().map(|m| { m.grandine_store_blocks_size.set(store.blocks.len() as i64); diff --git a/lean_client/fork_choice/src/store.rs b/lean_client/fork_choice/src/store.rs index 6e99434..2d3fa44 100644 --- a/lean_client/fork_choice/src/store.rs +++ b/lean_client/fork_choice/src/store.rs @@ -1,4 +1,5 @@ use std::collections::{HashMap, HashSet}; +use std::sync::Arc; use anyhow::{Result, anyhow, ensure}; use containers::{ @@ -64,7 +65,9 @@ pub struct Store { pub blocks: HashMap, - pub states: HashMap, + /// States are stored behind `Arc` so the many places that hand out a + /// snapshot of a state instead of deep-copying the whole state. + pub states: HashMap>, pub latest_known_attestations: HashMap, @@ -266,7 +269,7 @@ pub fn get_forkchoice_store( }, states: { let mut m = HashMap::new(); - m.insert(block_root, anchor_state); + m.insert(block_root, Arc::new(anchor_state)); m }, latest_known_attestations: HashMap::new(), @@ -369,7 +372,7 @@ pub fn get_fork_choice_head( } } -pub fn get_latest_justified(states: &HashMap) -> Option<&Checkpoint> { +pub fn get_latest_justified(states: &HashMap>) -> Option<&Checkpoint> { states .values() .map(|state| &state.latest_justified) @@ -616,7 +619,7 @@ pub struct BlockProductionInputs { pub slot: Slot, pub validator_index: u64, pub head_root: H256, - pub head_state: State, + pub head_state: Arc, pub known_block_roots: HashSet, /// Joined view of `latest_known_aggregated_payloads` keyed by `data_root`, /// with the `AttestationData` carried in the value. Entries whose diff --git a/lean_client/http_api/src/test_driver.rs b/lean_client/http_api/src/test_driver.rs index bc1a830..afa6a4a 100644 --- a/lean_client/http_api/src/test_driver.rs +++ b/lean_client/http_api/src/test_driver.rs @@ -309,7 +309,7 @@ async fn run_verify_signatures( } }; - Json(match signed_block.verify_signatures(anchor_state) { + Json(match signed_block.verify_signatures(&anchor_state) { Ok(()) => VerifySignaturesResponse { succeeded: true, error: None, diff --git a/lean_client/src/main.rs b/lean_client/src/main.rs index b0eef68..edf2360 100644 --- a/lean_client/src/main.rs +++ b/lean_client/src/main.rs @@ -952,7 +952,7 @@ async fn main() -> Result<()> { // proposer_signature is NOT covered by the hash — verify it // explicitly so a peer serving a validly-hashed but unsigned // block cannot become our anchor. - match signed_block.verify_signatures(anchor_state.clone()) { + match signed_block.verify_signatures(&anchor_state) { Ok(()) => { info!( slot = signed_block.block.slot.0,