From 9509bc8d50893f3e8da9a4a64628ed2c2f63a703 Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 15:37:34 -0700 Subject: [PATCH 1/6] refactor: fn sample_store is duplicated in all tests --- crates/common/fork_choice/lean/src/store.rs | 258 +++++++++++--------- crates/rpc/lean/src/handlers/checkpoint.rs | 64 +---- crates/rpc/lean/src/handlers/state.rs | 65 +---- 3 files changed, 150 insertions(+), 237 deletions(-) diff --git a/crates/common/fork_choice/lean/src/store.rs b/crates/common/fork_choice/lean/src/store.rs index 0ea353211..b7ae1fd19 100644 --- a/crates/common/fork_choice/lean/src/store.rs +++ b/crates/common/fork_choice/lean/src/store.rs @@ -1792,43 +1792,114 @@ pub fn compute_subnet_id(validator_id: u64, num_committees: u64) -> u64 { validator_id % num_committees } +pub mod test_utils { + use ream_consensus_lean::{ + attestation::{AggregatedAttestations, AttestationData}, + block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, + checkpoint::Checkpoint, + utils::generate_default_validators, + }; + use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; + use ream_post_quantum_crypto::leansig::signature::Signature; + use ream_storage::db::ReamDB; + use ssz_types::VariableList; + use tree_hash::TreeHash; + + use crate::{genesis::setup_genesis, store::Store}; + + pub async fn sample_store(no_of_validators: usize) -> Store { + set_lean_network_spec(LeanNetworkSpec::ephemery().into()); + let (genesis_block, genesis_state) = setup_genesis( + lean_network_spec().genesis_time, + generate_default_validators(no_of_validators), + ); + + let checkpoint = Checkpoint { + slot: genesis_block.slot, + root: genesis_block.tree_hash_root(), + }; + let signed_genesis_block = SignedBlockWithAttestation { + message: BlockWithAttestation { + proposer_attestation: AggregatedAttestations { + validator_id: genesis_block.proposer_index, + data: AttestationData { + slot: genesis_block.slot, + head: checkpoint, + target: checkpoint, + source: checkpoint, + }, + }, + block: genesis_block, + }, + signature: BlockSignatures { + attestation_signatures: VariableList::default(), + proposer_signature: Signature::blank(), + }, + }; + + let temp_path = std::env::temp_dir().join(format!( + "lean_test_{}_{:?}", + std::process::id(), + std::thread::current().id() + )); + std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); + let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); + let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); + + Store::get_forkchoice_store( + signed_genesis_block, + genesis_state, + lean_db, + Some(0), + #[cfg(feature = "devnet3")] + None, + ) + .expect("Failed to create forkchoice store") + } +} + #[cfg(test)] mod tests { use alloy_primitives::{B256, FixedBytes}; #[cfg(feature = "devnet3")] use anyhow::ensure; #[cfg(feature = "devnet2")] + use ream_consensus_lean::block::{ + Block, BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation, + }; + #[cfg(feature = "devnet2")] use ream_consensus_lean::validator::Validator; use ream_consensus_lean::{ attestation::{ AggregatedAttestation, AggregatedAttestations, AggregatedSignatureProof, AttestationData, SignatureKey, SignedAttestation, }, - block::{ - Block, BlockSignatures, BlockWithAttestation, BlockWithSignatures, - SignedBlockWithAttestation, - }, + block::BlockWithSignatures, checkpoint::Checkpoint, - state::LeanState, - utils::generate_default_validators, validator::is_proposer, }; use ream_consensus_misc::constants::lean::INTERVALS_PER_SLOT; - use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; + use ream_network_spec::networks::lean_network_spec; + #[cfg(feature = "devnet2")] + use ream_network_spec::networks::{LeanNetworkSpec, set_lean_network_spec}; #[cfg(feature = "devnet2")] use ream_post_quantum_crypto::leansig::private_key::PrivateKey; use ream_post_quantum_crypto::leansig::signature::Signature; - use ream_storage::{ - db::{ReamDB, lean::LeanDB}, - tables::{field::REDBField, table::REDBTable}, - }; - use ssz_types::{BitList, VariableList, typenum::U4096}; + #[cfg(feature = "devnet2")] + use ream_storage::db::{ReamDB, lean::LeanDB}; + use ream_storage::tables::{field::REDBField, table::REDBTable}; + #[cfg(feature = "devnet2")] + use ssz_types::VariableList; + use ssz_types::{BitList, typenum::U4096}; + #[cfg(feature = "devnet2")] use tempdir::TempDir; use tree_hash::TreeHash; + #[cfg(feature = "devnet2")] use super::Store; - use crate::genesis::setup_genesis; + use super::test_utils::sample_store; + #[cfg(feature = "devnet2")] pub fn db_setup() -> LeanDB { let temp_dir = TempDir::new("lean_test").unwrap(); let temp_path = temp_dir.path().to_path_buf(); @@ -1836,42 +1907,7 @@ mod tests { ream_db.init_lean_db().unwrap() } - pub async fn sample_store(no_of_validators: usize) -> (Store, LeanState) { - set_lean_network_spec(LeanNetworkSpec::ephemery().into()); - let (genesis_block, genesis_state) = setup_genesis( - lean_network_spec().genesis_time, - generate_default_validators(no_of_validators), - ); - - let checkpoint = Checkpoint { - slot: genesis_block.slot, - root: genesis_block.tree_hash_root(), - }; - let signed_genesis_block = build_signed_block_with_attestation( - AttestationData { - slot: genesis_block.slot, - head: checkpoint, - target: checkpoint, - source: checkpoint, - }, - genesis_block.clone(), - VariableList::default(), - ); - - ( - Store::get_forkchoice_store( - signed_genesis_block, - genesis_state.clone(), - db_setup(), - Some(0), - #[cfg(feature = "devnet3")] - None, - ) - .unwrap(), - genesis_state, - ) - } - + #[cfg(feature = "devnet2")] pub fn build_signed_block_with_attestation( attestation_data: AttestationData, block: Block, @@ -1896,7 +1932,7 @@ mod tests { #[tokio::test] #[ignore] async fn test_head_checkpoint_slot_mismatch_rejected() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let slot_1 = 1; let block_sigs = store.produce_block_with_signatures(slot_1, 1).await?; let block_root = block_sigs.block.tree_hash_root(); @@ -1937,7 +1973,7 @@ mod tests { #[tokio::test] #[ignore] async fn test_head_slot_less_than_source_rejected() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let block_1_sigs = store.produce_block_with_signatures(1, 1).await?; let block_1_root = block_1_sigs.block.tree_hash_root(); let block_2_sigs = store.produce_block_with_signatures(2, 2).await?; @@ -1982,7 +2018,7 @@ mod tests { #[tokio::test] #[ignore] async fn test_head_slot_less_than_target_rejected() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let block_1_sigs = store.produce_block_with_signatures(1, 1).await?; let block_1_root = block_1_sigs.block.tree_hash_root(); let block_2_sigs = store.produce_block_with_signatures(2, 2).await?; @@ -2024,7 +2060,7 @@ mod tests { #[tokio::test] #[ignore] async fn test_valid_attestation_with_correct_head_passes() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let slot_1 = 1; let block_sigs = store.produce_block_with_signatures(slot_1, 1).await?; let block_root = block_sigs.block.tree_hash_root(); @@ -2057,7 +2093,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_head_equal_to_source_and_target_passes() -> anyhow::Result<()> { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let genesis_checkpoint = { let db = store.store.lock().await; db.latest_justified_provider().get()? @@ -2103,7 +2139,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_prunes_entries_with_target_at_finalized() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let attestation_data = _make_attestation_data(5, 5); let data_root = attestation_data.tree_hash_root(); let sig_key = SignatureKey::new(1, &attestation_data); @@ -2151,7 +2187,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_prunes_entries_with_target_before_finalized() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let attestation_data = _make_attestation_data(3, 3); let data_root = attestation_data.tree_hash_root(); let sig_key = SignatureKey::new(1, &attestation_data); @@ -2189,7 +2225,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_keeps_entries_with_target_after_finalized() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let attestation_data = _make_attestation_data(10, 10); let data_root = attestation_data.tree_hash_root(); let sig_key = SignatureKey::new(1, &attestation_data); @@ -2228,7 +2264,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_prunes_related_structures_together() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let stale_attestation = _make_attestation_data(3, 3); let stale_root = stale_attestation.tree_hash_root(); @@ -2332,7 +2368,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_returns_self_when_nothing_to_prune() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let fresh_attestation = _make_attestation_data(10, 10); let data_root = fresh_attestation.tree_hash_root(); @@ -2360,7 +2396,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_handles_empty_attestation_data() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; ensure!( store.attestation_data_by_root.is_empty(), "Store should start empty" @@ -2378,7 +2414,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_prunes_multiple_validators_same_data_root() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let stale_data = _make_attestation_data(3, 3); let data_root = stale_data.tree_hash_root(); let sig_key_1 = SignatureKey::new(1, &stale_data); @@ -2426,7 +2462,7 @@ mod tests { #[cfg(feature = "devnet3")] #[tokio::test] async fn test_mixed_stale_and_fresh_entries() -> anyhow::Result<()> { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let mut roots = vec![]; { @@ -2468,7 +2504,7 @@ mod tests { /// Test block production fails for unauthorized proposer. #[tokio::test] async fn test_produce_block_unauthorized_proposer() { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let block_with_signature = store.produce_block_with_signatures(1, 2).await; assert!(block_with_signature.is_err()); } @@ -2610,10 +2646,8 @@ mod tests { #[cfg(feature = "devnet2")] #[tokio::test] pub async fn test_produce_block_sequential_slots() { - let (mut store, mut genesis_state) = sample_store(10).await; + let mut store = sample_store(10).await; let block_provider = store.store.lock().await.block_provider(); - - genesis_state.process_slots(1).unwrap(); let genesis_hash = store.store.lock().await.head_provider().get().unwrap(); let BlockWithSignatures { block, .. } = @@ -2632,7 +2666,7 @@ mod tests { /// Test block production with no available attestations. #[tokio::test] pub async fn test_produce_block_empty_attestations() { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let head = store.get_proposal_head(3).await.unwrap(); let BlockWithSignatures { block, .. } = @@ -2652,7 +2686,7 @@ mod tests { let slot = 1; let validator_id = 5; - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let latest_justified_checkpoint = store .store .lock() @@ -2675,9 +2709,9 @@ mod tests { pub async fn test_produce_attestation_head_reference() { let slot = 2; #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let block_provider = store.store.lock().await.block_provider(); let attestation = AggregatedAttestations { validator_id: 8, @@ -2694,7 +2728,7 @@ mod tests { /// Test that attestation calculates target correctly. #[tokio::test] pub async fn test_produce_attestation_target_calculation() { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let attestation = AggregatedAttestations { validator_id: 9, data: store.produce_attestation_data(3).await.unwrap(), @@ -2708,7 +2742,7 @@ mod tests { #[tokio::test] pub async fn test_produce_attestation_different_validators() { let slot = 4; - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let mut attestations = Vec::new(); for validator_id in 0..5 { @@ -2733,7 +2767,7 @@ mod tests { /// Test attestation production across sequential slots. #[tokio::test] pub async fn test_produce_attestation_sequential_slots() { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let latest_justified_provider = store.store.lock().await.latest_justified_provider(); let mut aggregation_bits = BitList::::with_capacity(32).unwrap(); @@ -2760,7 +2794,7 @@ mod tests { /// Test that attestation source uses current justified checkpoint. #[tokio::test] pub async fn test_produce_attestation_justification_consistency() { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let (latest_justified_provider, block_provider) = { let db = store.store.lock().await; (db.latest_justified_provider(), db.block_provider()) @@ -2791,7 +2825,7 @@ mod tests { /// Test error when wrong validator tries to produce block. #[tokio::test] pub async fn test_produce_block_wrong_proposer() { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let block = store.produce_block_with_signatures(5, 3).await; assert!(block.is_err()); @@ -2804,7 +2838,7 @@ mod tests { /// Test error when parent state is missing. #[tokio::test] pub async fn test_produce_block_missing_parent_state() { - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; store .store .lock() @@ -2830,7 +2864,7 @@ mod tests { /// Test validator operations with invalid parameters. #[tokio::test] pub async fn test_validator_operations_invalid_parameters() { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; // shoudl fail assert!(!is_proposer(1000000, 1000000, 10)); @@ -2848,14 +2882,14 @@ mod tests { #[tokio::test] pub async fn test_on_tick_basic() { #[cfg(feature = "devnet2")] - let (store, state) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, state) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); - let target_time = state.config.genesis_time + 200; + let target_time = lean_network_spec().genesis_time + 200; #[cfg(feature = "devnet2")] store.on_tick(target_time, true).await.unwrap(); @@ -2872,14 +2906,14 @@ mod tests { #[tokio::test] pub async fn test_on_tick_no_proposal() { #[cfg(feature = "devnet2")] - let (store, state) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, state) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); - let target_time = state.config.genesis_time + 100; + let target_time = lean_network_spec().genesis_time + 100; #[cfg(feature = "devnet2")] store.on_tick(target_time, true).await.unwrap(); @@ -2896,14 +2930,14 @@ mod tests { #[tokio::test] pub async fn test_on_tick_already_current() { #[cfg(feature = "devnet2")] - let (store, state) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, state) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); - let current_target = state.config.genesis_time + initial_time; + let current_target = lean_network_spec().genesis_time + initial_time; #[cfg(feature = "devnet2")] store.on_tick(current_target, false).await.unwrap(); @@ -2920,14 +2954,14 @@ mod tests { #[tokio::test] pub async fn test_on_tick_small_increment() { #[cfg(feature = "devnet2")] - let (store, state) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, state) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); - let target_time = state.config.genesis_time + initial_time + 1; + let target_time = lean_network_spec().genesis_time + initial_time + 1; #[cfg(feature = "devnet2")] store.on_tick(target_time, false).await.unwrap(); @@ -2946,10 +2980,10 @@ mod tests { #[tokio::test] pub async fn test_tick_interval_basic() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); @@ -2969,10 +3003,10 @@ mod tests { #[tokio::test] pub async fn test_tick_interval_with_proposal() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); @@ -2992,10 +3026,10 @@ mod tests { #[tokio::test] pub async fn test_tick_interval_sequence() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); @@ -3019,10 +3053,10 @@ mod tests { #[tokio::test] pub async fn test_tick_interval_actions_by_phase() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let mut root = [0u8; 32]; root[..4].copy_from_slice(b"test"); @@ -3074,9 +3108,9 @@ mod tests { // Test conversion from slot to time. #[tokio::test] pub async fn test_slot_to_time_conversion() { - let (_, state) = sample_store(10).await; + let _ = sample_store(10).await; - let genesis_time = state.config.genesis_time; + let genesis_time = lean_network_spec().genesis_time; let slot_0_time = genesis_time; assert!(slot_0_time == genesis_time); @@ -3091,9 +3125,9 @@ mod tests { // Test conversion from time to slot. #[tokio::test] pub async fn test_time_to_slot_conversion() { - let (_, state) = sample_store(10).await; + let _ = sample_store(10).await; - let genesis_time = state.config.genesis_time; + let genesis_time = lean_network_spec().genesis_time; let time_at_genesis = genesis_time; let slot_0 = (time_at_genesis - genesis_time) / lean_network_spec().seconds_per_slot; @@ -3134,10 +3168,10 @@ mod tests { #[tokio::test] pub async fn test_accept_new_attestations_basic() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let mut root = [0u8; 32]; root[..4].copy_from_slice(b"test"); @@ -3208,10 +3242,10 @@ mod tests { #[tokio::test] pub async fn test_accept_new_attestations_multiple() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let mut checkpoints: Vec = Vec::new(); for i in 0..5 { @@ -3293,10 +3327,10 @@ mod tests { #[tokio::test] pub async fn test_accept_new_attestations_empty() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let latest_known_attestations_provider = { store @@ -3340,10 +3374,10 @@ mod tests { #[tokio::test] pub async fn test_get_proposal_head_basic() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let head = store.get_proposal_head(0).await.unwrap(); @@ -3356,10 +3390,10 @@ mod tests { #[tokio::test] pub async fn test_get_proposal_head_advances_time() { #[cfg(feature = "devnet2")] - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; #[cfg(feature = "devnet3")] - let (mut store, _) = sample_store(10).await; + let mut store = sample_store(10).await; let time_provider = { store.store.lock().await.time_provider() }; let initial_time = time_provider.get().unwrap(); @@ -3375,7 +3409,7 @@ mod tests { #[cfg(feature = "devnet2")] #[tokio::test] pub async fn test_get_proposal_head_processes_attestations() { - let (store, _) = sample_store(10).await; + let store = sample_store(10).await; let root = { let mut root_vec = [0u8; 32]; diff --git a/crates/rpc/lean/src/handlers/checkpoint.rs b/crates/rpc/lean/src/handlers/checkpoint.rs index 841a80277..684faee4f 100644 --- a/crates/rpc/lean/src/handlers/checkpoint.rs +++ b/crates/rpc/lean/src/handlers/checkpoint.rs @@ -26,72 +26,12 @@ pub async fn get_justified_checkpoint( #[cfg(test)] mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; - use ream_consensus_lean::{ - attestation::{AggregatedAttestations, AttestationData}, - block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, - checkpoint::Checkpoint, - utils::generate_default_validators, - }; - use ream_fork_choice_lean::{genesis::setup_genesis, store::Store}; - use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; - use ream_post_quantum_crypto::leansig::signature::Signature; - use ream_storage::db::ReamDB; + use ream_consensus_lean::checkpoint::Checkpoint; + use ream_fork_choice_lean::store::test_utils::sample_store; use ream_sync::rwlock::Writer; - use ssz_types::VariableList; - use tree_hash::TreeHash; use super::get_justified_checkpoint; - async fn sample_store(no_of_validators: usize) -> Store { - set_lean_network_spec(LeanNetworkSpec::ephemery().into()); - let (genesis_block, genesis_state) = setup_genesis( - lean_network_spec().genesis_time, - generate_default_validators(no_of_validators), - ); - - let checkpoint = Checkpoint { - slot: genesis_block.slot, - root: genesis_block.tree_hash_root(), - }; - let signed_genesis_block = SignedBlockWithAttestation { - message: BlockWithAttestation { - proposer_attestation: AggregatedAttestations { - validator_id: genesis_block.proposer_index, - data: AttestationData { - slot: genesis_block.slot, - head: checkpoint, - target: checkpoint, - source: checkpoint, - }, - }, - block: genesis_block, - }, - signature: BlockSignatures { - attestation_signatures: VariableList::default(), - proposer_signature: Signature::blank(), - }, - }; - - let temp_path = std::env::temp_dir().join(format!( - "lean_test_{}_{:?}", - std::process::id(), - std::thread::current().id() - )); - std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); - let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); - let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); - - Store::get_forkchoice_store( - signed_genesis_block, - genesis_state, - lean_db, - Some(0), - #[cfg(feature = "devnet3")] - None, - ) - .expect("Failed to create forkchoice store") - } - #[tokio::test] async fn test_get_justified_checkpoint_returns_json() { let store = sample_store(10).await; diff --git a/crates/rpc/lean/src/handlers/state.rs b/crates/rpc/lean/src/handlers/state.rs index f43ebfa20..2a8a6da0e 100644 --- a/crates/rpc/lean/src/handlers/state.rs +++ b/crates/rpc/lean/src/handlers/state.rs @@ -90,74 +90,13 @@ pub async fn get_state( #[cfg(test)] mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; - use ream_consensus_lean::{ - attestation::{AggregatedAttestations, AttestationData}, - block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, - checkpoint::Checkpoint, - state::LeanState, - utils::generate_default_validators, - }; - use ream_fork_choice_lean::{genesis::setup_genesis, store::Store}; - use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; - use ream_post_quantum_crypto::leansig::signature::Signature; - use ream_storage::db::ReamDB; + use ream_consensus_lean::state::LeanState; + use ream_fork_choice_lean::store::test_utils::sample_store; use ream_sync::rwlock::Writer; use ssz::Decode; - use ssz_types::VariableList; - use tree_hash::TreeHash; use super::get_state; - async fn sample_store(no_of_validators: usize) -> Store { - set_lean_network_spec(LeanNetworkSpec::ephemery().into()); - let (genesis_block, genesis_state) = setup_genesis( - lean_network_spec().genesis_time, - generate_default_validators(no_of_validators), - ); - - let checkpoint = Checkpoint { - slot: genesis_block.slot, - root: genesis_block.tree_hash_root(), - }; - let signed_genesis_block = SignedBlockWithAttestation { - message: BlockWithAttestation { - proposer_attestation: AggregatedAttestations { - validator_id: genesis_block.proposer_index, - data: AttestationData { - slot: genesis_block.slot, - head: checkpoint, - target: checkpoint, - source: checkpoint, - }, - }, - block: genesis_block, - }, - signature: BlockSignatures { - attestation_signatures: VariableList::default(), - proposer_signature: Signature::blank(), - }, - }; - - let temp_path = std::env::temp_dir().join(format!( - "lean_test_{}_{:?}", - std::process::id(), - std::thread::current().id() - )); - std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); - let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); - let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); - - Store::get_forkchoice_store( - signed_genesis_block, - genesis_state, - lean_db, - Some(0), - #[cfg(feature = "devnet3")] - None, - ) - .expect("Failed to create forkchoice store") - } - #[tokio::test] async fn test_get_finalized_state_returns_ssz() { let store = sample_store(10).await; From e0561447a87ee4592f4ff1643f0af234d04fa43e Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 17:57:40 -0700 Subject: [PATCH 2/6] fix: move utils to their own file --- crates/common/fork_choice/lean/src/lib.rs | 1 + crates/common/fork_choice/lean/src/store.rs | 68 +-------------------- crates/common/fork_choice/lean/src/utils.rs | 63 +++++++++++++++++++ crates/rpc/lean/src/handlers/checkpoint.rs | 2 +- crates/rpc/lean/src/handlers/state.rs | 2 +- 5 files changed, 67 insertions(+), 69 deletions(-) create mode 100644 crates/common/fork_choice/lean/src/utils.rs diff --git a/crates/common/fork_choice/lean/src/lib.rs b/crates/common/fork_choice/lean/src/lib.rs index 961c7cf97..db4c00aac 100644 --- a/crates/common/fork_choice/lean/src/lib.rs +++ b/crates/common/fork_choice/lean/src/lib.rs @@ -1,3 +1,4 @@ pub mod constants; pub mod genesis; pub mod store; +pub mod utils; diff --git a/crates/common/fork_choice/lean/src/store.rs b/crates/common/fork_choice/lean/src/store.rs index b7ae1fd19..37df0dc4c 100644 --- a/crates/common/fork_choice/lean/src/store.rs +++ b/crates/common/fork_choice/lean/src/store.rs @@ -1792,72 +1792,6 @@ pub fn compute_subnet_id(validator_id: u64, num_committees: u64) -> u64 { validator_id % num_committees } -pub mod test_utils { - use ream_consensus_lean::{ - attestation::{AggregatedAttestations, AttestationData}, - block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, - checkpoint::Checkpoint, - utils::generate_default_validators, - }; - use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; - use ream_post_quantum_crypto::leansig::signature::Signature; - use ream_storage::db::ReamDB; - use ssz_types::VariableList; - use tree_hash::TreeHash; - - use crate::{genesis::setup_genesis, store::Store}; - - pub async fn sample_store(no_of_validators: usize) -> Store { - set_lean_network_spec(LeanNetworkSpec::ephemery().into()); - let (genesis_block, genesis_state) = setup_genesis( - lean_network_spec().genesis_time, - generate_default_validators(no_of_validators), - ); - - let checkpoint = Checkpoint { - slot: genesis_block.slot, - root: genesis_block.tree_hash_root(), - }; - let signed_genesis_block = SignedBlockWithAttestation { - message: BlockWithAttestation { - proposer_attestation: AggregatedAttestations { - validator_id: genesis_block.proposer_index, - data: AttestationData { - slot: genesis_block.slot, - head: checkpoint, - target: checkpoint, - source: checkpoint, - }, - }, - block: genesis_block, - }, - signature: BlockSignatures { - attestation_signatures: VariableList::default(), - proposer_signature: Signature::blank(), - }, - }; - - let temp_path = std::env::temp_dir().join(format!( - "lean_test_{}_{:?}", - std::process::id(), - std::thread::current().id() - )); - std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); - let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); - let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); - - Store::get_forkchoice_store( - signed_genesis_block, - genesis_state, - lean_db, - Some(0), - #[cfg(feature = "devnet3")] - None, - ) - .expect("Failed to create forkchoice store") - } -} - #[cfg(test)] mod tests { use alloy_primitives::{B256, FixedBytes}; @@ -1897,7 +1831,7 @@ mod tests { #[cfg(feature = "devnet2")] use super::Store; - use super::test_utils::sample_store; + use crate::utils::sample_store; #[cfg(feature = "devnet2")] pub fn db_setup() -> LeanDB { diff --git a/crates/common/fork_choice/lean/src/utils.rs b/crates/common/fork_choice/lean/src/utils.rs new file mode 100644 index 000000000..1371a6f23 --- /dev/null +++ b/crates/common/fork_choice/lean/src/utils.rs @@ -0,0 +1,63 @@ +use ream_consensus_lean::{ + attestation::{AggregatedAttestations, AttestationData}, + block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, + checkpoint::Checkpoint, + utils::generate_default_validators, +}; +use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; +use ream_post_quantum_crypto::leansig::signature::Signature; +use ream_storage::db::ReamDB; +use ssz_types::VariableList; +use tree_hash::TreeHash; + +use crate::{genesis::setup_genesis, store::Store}; + +pub async fn sample_store(no_of_validators: usize) -> Store { + set_lean_network_spec(LeanNetworkSpec::ephemery().into()); + let (genesis_block, genesis_state) = setup_genesis( + lean_network_spec().genesis_time, + generate_default_validators(no_of_validators), + ); + + let checkpoint = Checkpoint { + slot: genesis_block.slot, + root: genesis_block.tree_hash_root(), + }; + let signed_genesis_block = SignedBlockWithAttestation { + message: BlockWithAttestation { + proposer_attestation: AggregatedAttestations { + validator_id: genesis_block.proposer_index, + data: AttestationData { + slot: genesis_block.slot, + head: checkpoint, + target: checkpoint, + source: checkpoint, + }, + }, + block: genesis_block, + }, + signature: BlockSignatures { + attestation_signatures: VariableList::default(), + proposer_signature: Signature::blank(), + }, + }; + + let temp_path = std::env::temp_dir().join(format!( + "lean_test_{}_{:?}", + std::process::id(), + std::thread::current().id() + )); + std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); + let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); + let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); + + Store::get_forkchoice_store( + signed_genesis_block, + genesis_state, + lean_db, + Some(0), + #[cfg(feature = "devnet3")] + None, + ) + .expect("Failed to create forkchoice store") +} diff --git a/crates/rpc/lean/src/handlers/checkpoint.rs b/crates/rpc/lean/src/handlers/checkpoint.rs index 684faee4f..0308ec9eb 100644 --- a/crates/rpc/lean/src/handlers/checkpoint.rs +++ b/crates/rpc/lean/src/handlers/checkpoint.rs @@ -27,7 +27,7 @@ pub async fn get_justified_checkpoint( mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::checkpoint::Checkpoint; - use ream_fork_choice_lean::store::test_utils::sample_store; + use ream_fork_choice_lean::utils::sample_store; use ream_sync::rwlock::Writer; use super::get_justified_checkpoint; diff --git a/crates/rpc/lean/src/handlers/state.rs b/crates/rpc/lean/src/handlers/state.rs index 2a8a6da0e..faa02d328 100644 --- a/crates/rpc/lean/src/handlers/state.rs +++ b/crates/rpc/lean/src/handlers/state.rs @@ -91,7 +91,7 @@ pub async fn get_state( mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::state::LeanState; - use ream_fork_choice_lean::store::test_utils::sample_store; + use ream_fork_choice_lean::utils::sample_store; use ream_sync::rwlock::Writer; use ssz::Decode; From c0bb7d605a998618f7fccf9636e71842751c0d06 Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 18:07:41 -0700 Subject: [PATCH 3/6] fix: make new test_utils crate and use it as dev dependency --- Cargo.lock | 15 ++++++++ Cargo.toml | 2 + crates/common/fork_choice/lean/Cargo.toml | 1 + crates/common/fork_choice/lean/src/lib.rs | 1 - crates/common/fork_choice/lean/src/store.rs | 2 +- crates/common/test_utils/Cargo.toml | 37 +++++++++++++++++++ .../src/utils.rs => test_utils/src/lib.rs} | 3 +- crates/rpc/lean/Cargo.toml | 3 ++ crates/rpc/lean/src/handlers/checkpoint.rs | 2 +- crates/rpc/lean/src/handlers/state.rs | 2 +- 10 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 crates/common/test_utils/Cargo.toml rename crates/common/{fork_choice/lean/src/utils.rs => test_utils/src/lib.rs} (97%) diff --git a/Cargo.lock b/Cargo.lock index 4be200c75..4a348f4e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6171,6 +6171,7 @@ dependencies = [ "ream-post-quantum-crypto", "ream-storage", "ream-sync", + "ream-test-utils", "serde", "serde_json", "serde_yaml", @@ -6541,6 +6542,7 @@ dependencies = [ "ream-rpc-common", "ream-storage", "ream-sync", + "ream-test-utils", "serde_json", "ssz_types", "tokio", @@ -6628,6 +6630,19 @@ dependencies = [ "tree_hash", ] +[[package]] +name = "ream-test-utils" +version = "0.1.0" +dependencies = [ + "ream-consensus-lean", + "ream-fork-choice-lean", + "ream-network-spec", + "ream-post-quantum-crypto", + "ream-storage", + "ssz_types", + "tree_hash", +] + [[package]] name = "ream-validator-beacon" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index bcf5b7ff5..d84c5bf03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "crates/common/polynomial_commitments", "crates/common/sync", "crates/common/sync_committee_pool", + "crates/common/test_utils", "crates/common/validator/beacon", "crates/common/validator/lean", "crates/crypto/bls", @@ -184,6 +185,7 @@ ream-storage = { path = "crates/storage" } ream-sync = { path = "crates/common/sync" } ream-sync-committee-pool = { path = "crates/common/sync_committee_pool" } ream-syncer = { path = "crates/networking/syncer" } +ream-test-utils = { path = "crates/common/test_utils", default-features = false } ream-validator-beacon = { path = "crates/common/validator/beacon" } ream-validator-lean = { path = "crates/common/validator/lean", default-features = false } diff --git a/crates/common/fork_choice/lean/Cargo.toml b/crates/common/fork_choice/lean/Cargo.toml index b1c0f3a2b..e2915bb97 100644 --- a/crates/common/fork_choice/lean/Cargo.toml +++ b/crates/common/fork_choice/lean/Cargo.toml @@ -61,6 +61,7 @@ ream-sync.workspace = true [dev-dependencies] rand.workspace = true +ream-test-utils.workspace = true [lints] workspace = true diff --git a/crates/common/fork_choice/lean/src/lib.rs b/crates/common/fork_choice/lean/src/lib.rs index db4c00aac..961c7cf97 100644 --- a/crates/common/fork_choice/lean/src/lib.rs +++ b/crates/common/fork_choice/lean/src/lib.rs @@ -1,4 +1,3 @@ pub mod constants; pub mod genesis; pub mod store; -pub mod utils; diff --git a/crates/common/fork_choice/lean/src/store.rs b/crates/common/fork_choice/lean/src/store.rs index 37df0dc4c..c68bae6b4 100644 --- a/crates/common/fork_choice/lean/src/store.rs +++ b/crates/common/fork_choice/lean/src/store.rs @@ -1822,6 +1822,7 @@ mod tests { #[cfg(feature = "devnet2")] use ream_storage::db::{ReamDB, lean::LeanDB}; use ream_storage::tables::{field::REDBField, table::REDBTable}; + use ream_test_utils::sample_store; #[cfg(feature = "devnet2")] use ssz_types::VariableList; use ssz_types::{BitList, typenum::U4096}; @@ -1831,7 +1832,6 @@ mod tests { #[cfg(feature = "devnet2")] use super::Store; - use crate::utils::sample_store; #[cfg(feature = "devnet2")] pub fn db_setup() -> LeanDB { diff --git a/crates/common/test_utils/Cargo.toml b/crates/common/test_utils/Cargo.toml new file mode 100644 index 000000000..cbf1306cb --- /dev/null +++ b/crates/common/test_utils/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "ream-test-utils" +authors.workspace = true +edition.workspace = true +keywords.workspace = true +license.workspace = true +readme.workspace = true +repository.workspace = true +rust-version.workspace = true +version.workspace = true + +[features] +default = ["devnet2"] +devnet2 = [ + "ream-consensus-lean/devnet2", + "ream-fork-choice-lean/devnet2", + "ream-storage/devnet2", +] +devnet3 = [ + "ream-consensus-lean/devnet3", + "ream-fork-choice-lean/devnet3", + "ream-storage/devnet3", +] + +[dependencies] +ssz_types.workspace = true +tree_hash.workspace = true + +# ream dependencies +ream-consensus-lean.workspace = true +ream-fork-choice-lean.workspace = true +ream-network-spec.workspace = true +ream-post-quantum-crypto.workspace = true +ream-storage.workspace = true + +[lints] +workspace = true diff --git a/crates/common/fork_choice/lean/src/utils.rs b/crates/common/test_utils/src/lib.rs similarity index 97% rename from crates/common/fork_choice/lean/src/utils.rs rename to crates/common/test_utils/src/lib.rs index 1371a6f23..5632cd0ff 100644 --- a/crates/common/fork_choice/lean/src/utils.rs +++ b/crates/common/test_utils/src/lib.rs @@ -4,14 +4,13 @@ use ream_consensus_lean::{ checkpoint::Checkpoint, utils::generate_default_validators, }; +use ream_fork_choice_lean::{genesis::setup_genesis, store::Store}; use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; use ream_post_quantum_crypto::leansig::signature::Signature; use ream_storage::db::ReamDB; use ssz_types::VariableList; use tree_hash::TreeHash; -use crate::{genesis::setup_genesis, store::Store}; - pub async fn sample_store(no_of_validators: usize) -> Store { set_lean_network_spec(LeanNetworkSpec::ephemery().into()); let (genesis_block, genesis_state) = setup_genesis( diff --git a/crates/rpc/lean/Cargo.toml b/crates/rpc/lean/Cargo.toml index c34e24643..af033b999 100644 --- a/crates/rpc/lean/Cargo.toml +++ b/crates/rpc/lean/Cargo.toml @@ -46,5 +46,8 @@ ream-sync.workspace = true ssz_types.workspace = true tree_hash.workspace = true +[dev-dependencies] +ream-test-utils.workspace = true + [lints] workspace = true diff --git a/crates/rpc/lean/src/handlers/checkpoint.rs b/crates/rpc/lean/src/handlers/checkpoint.rs index 0308ec9eb..bbc9f14ca 100644 --- a/crates/rpc/lean/src/handlers/checkpoint.rs +++ b/crates/rpc/lean/src/handlers/checkpoint.rs @@ -27,8 +27,8 @@ pub async fn get_justified_checkpoint( mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::checkpoint::Checkpoint; - use ream_fork_choice_lean::utils::sample_store; use ream_sync::rwlock::Writer; + use ream_test_utils::sample_store; use super::get_justified_checkpoint; diff --git a/crates/rpc/lean/src/handlers/state.rs b/crates/rpc/lean/src/handlers/state.rs index faa02d328..2c1bd9538 100644 --- a/crates/rpc/lean/src/handlers/state.rs +++ b/crates/rpc/lean/src/handlers/state.rs @@ -91,8 +91,8 @@ pub async fn get_state( mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::state::LeanState; - use ream_fork_choice_lean::utils::sample_store; use ream_sync::rwlock::Writer; + use ream_test_utils::sample_store; use ssz::Decode; use super::get_state; From ee151c4904544092be505e97845fe90b5c366d3d Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 18:12:38 -0700 Subject: [PATCH 4/6] fix: cleanup --- crates/common/fork_choice/lean/src/store.rs | 2 +- crates/common/test_utils/src/lib.rs | 63 +-------------------- crates/common/test_utils/src/store.rs | 62 ++++++++++++++++++++ crates/rpc/lean/src/handlers/checkpoint.rs | 2 +- crates/rpc/lean/src/handlers/state.rs | 2 +- 5 files changed, 66 insertions(+), 65 deletions(-) create mode 100644 crates/common/test_utils/src/store.rs diff --git a/crates/common/fork_choice/lean/src/store.rs b/crates/common/fork_choice/lean/src/store.rs index c68bae6b4..e7966d6bd 100644 --- a/crates/common/fork_choice/lean/src/store.rs +++ b/crates/common/fork_choice/lean/src/store.rs @@ -1822,7 +1822,7 @@ mod tests { #[cfg(feature = "devnet2")] use ream_storage::db::{ReamDB, lean::LeanDB}; use ream_storage::tables::{field::REDBField, table::REDBTable}; - use ream_test_utils::sample_store; + use ream_test_utils::store::sample_store; #[cfg(feature = "devnet2")] use ssz_types::VariableList; use ssz_types::{BitList, typenum::U4096}; diff --git a/crates/common/test_utils/src/lib.rs b/crates/common/test_utils/src/lib.rs index 5632cd0ff..55c88cbf3 100644 --- a/crates/common/test_utils/src/lib.rs +++ b/crates/common/test_utils/src/lib.rs @@ -1,62 +1 @@ -use ream_consensus_lean::{ - attestation::{AggregatedAttestations, AttestationData}, - block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, - checkpoint::Checkpoint, - utils::generate_default_validators, -}; -use ream_fork_choice_lean::{genesis::setup_genesis, store::Store}; -use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; -use ream_post_quantum_crypto::leansig::signature::Signature; -use ream_storage::db::ReamDB; -use ssz_types::VariableList; -use tree_hash::TreeHash; - -pub async fn sample_store(no_of_validators: usize) -> Store { - set_lean_network_spec(LeanNetworkSpec::ephemery().into()); - let (genesis_block, genesis_state) = setup_genesis( - lean_network_spec().genesis_time, - generate_default_validators(no_of_validators), - ); - - let checkpoint = Checkpoint { - slot: genesis_block.slot, - root: genesis_block.tree_hash_root(), - }; - let signed_genesis_block = SignedBlockWithAttestation { - message: BlockWithAttestation { - proposer_attestation: AggregatedAttestations { - validator_id: genesis_block.proposer_index, - data: AttestationData { - slot: genesis_block.slot, - head: checkpoint, - target: checkpoint, - source: checkpoint, - }, - }, - block: genesis_block, - }, - signature: BlockSignatures { - attestation_signatures: VariableList::default(), - proposer_signature: Signature::blank(), - }, - }; - - let temp_path = std::env::temp_dir().join(format!( - "lean_test_{}_{:?}", - std::process::id(), - std::thread::current().id() - )); - std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); - let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); - let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); - - Store::get_forkchoice_store( - signed_genesis_block, - genesis_state, - lean_db, - Some(0), - #[cfg(feature = "devnet3")] - None, - ) - .expect("Failed to create forkchoice store") -} +pub mod store; diff --git a/crates/common/test_utils/src/store.rs b/crates/common/test_utils/src/store.rs new file mode 100644 index 000000000..5632cd0ff --- /dev/null +++ b/crates/common/test_utils/src/store.rs @@ -0,0 +1,62 @@ +use ream_consensus_lean::{ + attestation::{AggregatedAttestations, AttestationData}, + block::{BlockSignatures, BlockWithAttestation, SignedBlockWithAttestation}, + checkpoint::Checkpoint, + utils::generate_default_validators, +}; +use ream_fork_choice_lean::{genesis::setup_genesis, store::Store}; +use ream_network_spec::networks::{LeanNetworkSpec, lean_network_spec, set_lean_network_spec}; +use ream_post_quantum_crypto::leansig::signature::Signature; +use ream_storage::db::ReamDB; +use ssz_types::VariableList; +use tree_hash::TreeHash; + +pub async fn sample_store(no_of_validators: usize) -> Store { + set_lean_network_spec(LeanNetworkSpec::ephemery().into()); + let (genesis_block, genesis_state) = setup_genesis( + lean_network_spec().genesis_time, + generate_default_validators(no_of_validators), + ); + + let checkpoint = Checkpoint { + slot: genesis_block.slot, + root: genesis_block.tree_hash_root(), + }; + let signed_genesis_block = SignedBlockWithAttestation { + message: BlockWithAttestation { + proposer_attestation: AggregatedAttestations { + validator_id: genesis_block.proposer_index, + data: AttestationData { + slot: genesis_block.slot, + head: checkpoint, + target: checkpoint, + source: checkpoint, + }, + }, + block: genesis_block, + }, + signature: BlockSignatures { + attestation_signatures: VariableList::default(), + proposer_signature: Signature::blank(), + }, + }; + + let temp_path = std::env::temp_dir().join(format!( + "lean_test_{}_{:?}", + std::process::id(), + std::thread::current().id() + )); + std::fs::create_dir_all(&temp_path).expect("Failed to create temp directory"); + let ream_db = ReamDB::new(temp_path).expect("Failed to init Ream Database"); + let lean_db = ream_db.init_lean_db().expect("Failed to init lean db"); + + Store::get_forkchoice_store( + signed_genesis_block, + genesis_state, + lean_db, + Some(0), + #[cfg(feature = "devnet3")] + None, + ) + .expect("Failed to create forkchoice store") +} diff --git a/crates/rpc/lean/src/handlers/checkpoint.rs b/crates/rpc/lean/src/handlers/checkpoint.rs index bbc9f14ca..9a24077a2 100644 --- a/crates/rpc/lean/src/handlers/checkpoint.rs +++ b/crates/rpc/lean/src/handlers/checkpoint.rs @@ -28,7 +28,7 @@ mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::checkpoint::Checkpoint; use ream_sync::rwlock::Writer; - use ream_test_utils::sample_store; + use ream_test_utils::store::sample_store; use super::get_justified_checkpoint; diff --git a/crates/rpc/lean/src/handlers/state.rs b/crates/rpc/lean/src/handlers/state.rs index 2c1bd9538..70bf06a5b 100644 --- a/crates/rpc/lean/src/handlers/state.rs +++ b/crates/rpc/lean/src/handlers/state.rs @@ -92,7 +92,7 @@ mod tests { use actix_web::{App, http::StatusCode, test, web::Data}; use ream_consensus_lean::state::LeanState; use ream_sync::rwlock::Writer; - use ream_test_utils::sample_store; + use ream_test_utils::store::sample_store; use ssz::Decode; use super::get_state; From c969d611de3af4c0aafa607e1171d097d8ab6a4e Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 18:18:56 -0700 Subject: [PATCH 5/6] fix: move to testing --- Cargo.toml | 4 ++-- {crates/common => testing}/test_utils/Cargo.toml | 0 {crates/common => testing}/test_utils/src/lib.rs | 0 {crates/common => testing}/test_utils/src/store.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename {crates/common => testing}/test_utils/Cargo.toml (100%) rename {crates/common => testing}/test_utils/src/lib.rs (100%) rename {crates/common => testing}/test_utils/src/store.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index d84c5bf03..6f3592246 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ members = [ "crates/common/polynomial_commitments", "crates/common/sync", "crates/common/sync_committee_pool", - "crates/common/test_utils", + "testing/test_utils", "crates/common/validator/beacon", "crates/common/validator/lean", "crates/crypto/bls", @@ -185,7 +185,7 @@ ream-storage = { path = "crates/storage" } ream-sync = { path = "crates/common/sync" } ream-sync-committee-pool = { path = "crates/common/sync_committee_pool" } ream-syncer = { path = "crates/networking/syncer" } -ream-test-utils = { path = "crates/common/test_utils", default-features = false } +ream-test-utils = { path = "testing/test_utils", default-features = false } ream-validator-beacon = { path = "crates/common/validator/beacon" } ream-validator-lean = { path = "crates/common/validator/lean", default-features = false } diff --git a/crates/common/test_utils/Cargo.toml b/testing/test_utils/Cargo.toml similarity index 100% rename from crates/common/test_utils/Cargo.toml rename to testing/test_utils/Cargo.toml diff --git a/crates/common/test_utils/src/lib.rs b/testing/test_utils/src/lib.rs similarity index 100% rename from crates/common/test_utils/src/lib.rs rename to testing/test_utils/src/lib.rs diff --git a/crates/common/test_utils/src/store.rs b/testing/test_utils/src/store.rs similarity index 100% rename from crates/common/test_utils/src/store.rs rename to testing/test_utils/src/store.rs From b821d90f310a0b1231fa9ff02790578a86b0bb15 Mon Sep 17 00:00:00 2001 From: Shariq Naiyer Date: Sun, 22 Feb 2026 18:20:03 -0700 Subject: [PATCH 6/6] fix: sort --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 6f3592246..540d88084 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ members = [ "crates/common/polynomial_commitments", "crates/common/sync", "crates/common/sync_committee_pool", - "testing/test_utils", "crates/common/validator/beacon", "crates/common/validator/lean", "crates/crypto/bls", @@ -50,6 +49,7 @@ members = [ "testing/ef-tests", "testing/gossip-validation", "testing/lean-spec-tests", + "testing/test_utils", ] resolver = "2" exclude = ["book/cli"]