From 6b897d9d23204a87414baeae1fbf63cf88dcd068 Mon Sep 17 00:00:00 2001 From: Kayden Moroz Liebl Date: Sun, 28 Dec 2025 21:34:09 -0800 Subject: [PATCH] feat: runs devnet 2 in tests for ci and make --- .github/workflows/core-rust.yml | 15 ++++ Makefile | 10 ++- bin/ream/src/main.rs | 10 +-- .../common/consensus/lean/src/attestation.rs | 11 +-- crates/common/consensus/lean/src/block.rs | 19 +---- crates/common/consensus/lean/src/state.rs | 10 ++- crates/common/fork_choice/lean/src/store.rs | 70 +++---------------- testing/lean-spec-tests/Cargo.toml | 4 +- 8 files changed, 48 insertions(+), 101 deletions(-) diff --git a/.github/workflows/core-rust.yml b/.github/workflows/core-rust.yml index eb698e3db..ee48fe5b8 100644 --- a/.github/workflows/core-rust.yml +++ b/.github/workflows/core-rust.yml @@ -47,6 +47,7 @@ jobs: run: | cargo clippy --all --all-targets --no-deps -- --deny warnings # clippy for ream, default features cargo clippy --package ream-bls --all-targets --features "supranational" --no-deps -- --deny warnings # clippy for ream-bls, supranational feature + make clippy-devnet2 cargo-sort: runs-on: ubuntu-latest @@ -93,6 +94,20 @@ jobs: - name: Test run: cargo test --release --workspace -- --nocapture + test-devnet2: + runs-on: ubuntu-latest + needs: [format, cargo-clippy] + + steps: + - uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Test Devnet 2 + run: make test-devnet2 + ef-tests: runs-on: ubuntu-latest needs: [format, cargo-clippy] diff --git a/Makefile b/Makefile index 415622ebf..487c52624 100644 --- a/Makefile +++ b/Makefile @@ -40,9 +40,13 @@ install: # Build and install the Ream binary under `~/.cargo/bin`. ##@ Testing and Linting .PHONY: test -test: # Run all tests. +test: # Run all tests (defaults to devnet1). cargo test --workspace -- --nocapture +.PHONY: test-devnet2 +test-devnet2: # Run all tests for for Devnet 2. + cargo test --workspace --no-default-features --features "devnet2" -- --nocapture + .PHONY: fmt fmt: # Run `rustfmt` on the entire workspace and enfore closure variables on `map_err` to be `err` cargo +nightly fmt --all @@ -73,6 +77,10 @@ clippy: # Run `clippy` on the entire workspace. cargo clippy --all --all-targets --features "$(FEATURES)" --no-deps -- --deny warnings cargo clippy --package ream-bls --all-targets --features "supranational" --no-deps -- --deny warnings +.PHONY: clippy-devnet2 +clippy-devnet2: # Run `clippy` for Devnet 2. + cargo clippy --workspace --all-targets --no-default-features --features "devnet2" --no-deps -- --deny warnings + .PHONY: sort sort: # Run `cargo sort` on the entire workspace. cargo sort --grouped --workspace diff --git a/bin/ream/src/main.rs b/bin/ream/src/main.rs index 07a34d64f..523ff28c1 100644 --- a/bin/ream/src/main.rs +++ b/bin/ream/src/main.rs @@ -710,11 +710,9 @@ mod tests { use clap::Parser; use ream::cli::{Cli, Commands}; use ream_executor::ReamExecutor; - use ream_storage::{ - db::ReamDB, - dir::setup_data_dir, - tables::{field::REDBField, table::REDBTable}, - }; + #[cfg(feature = "devnet1")] + use ream_storage::tables::{field::REDBField, table::REDBTable}; + use ream_storage::{db::ReamDB, dir::setup_data_dir}; use tokio::time::{sleep, timeout}; use crate::{APP_NAME, run_lean_node}; @@ -758,7 +756,9 @@ mod tests { handle.abort(); } + /// TODO: Get finalization working for devnet2 #[tokio::test(flavor = "multi_thread", worker_threads = 4)] + #[cfg(feature = "devnet1")] async fn test_lean_node_finalizes() { let cli = Cli::parse_from([ "ream", diff --git a/crates/common/consensus/lean/src/attestation.rs b/crates/common/consensus/lean/src/attestation.rs index d8f533ac1..12c5963e5 100644 --- a/crates/common/consensus/lean/src/attestation.rs +++ b/crates/common/consensus/lean/src/attestation.rs @@ -107,6 +107,7 @@ pub struct SignedAggregatedAttestation { } #[cfg(test)] +#[cfg(feature = "devnet1")] mod tests { use alloy_primitives::hex; use ssz::{Decode, Encode}; @@ -117,7 +118,6 @@ mod tests { #[test] fn test_encode_decode_signed_attestation_roundtrip() -> anyhow::Result<()> { let signed_attestation = SignedAttestation { - #[cfg(feature = "devnet1")] message: Attestation { validator_id: 0, data: AttestationData { @@ -127,15 +127,6 @@ mod tests { source: Checkpoint::default(), }, }, - #[cfg(feature = "devnet2")] - message: AttestationData { - slot: 1, - head: Checkpoint::default(), - target: Checkpoint::default(), - source: Checkpoint::default(), - }, - #[cfg(feature = "devnet2")] - validator_id: 0, signature: Signature { inner: FixedBytes::default(), }, diff --git a/crates/common/consensus/lean/src/block.rs b/crates/common/consensus/lean/src/block.rs index d2fdf0406..e84b0ddc1 100644 --- a/crates/common/consensus/lean/src/block.rs +++ b/crates/common/consensus/lean/src/block.rs @@ -220,8 +220,8 @@ pub struct BlockWithSignatures { } #[cfg(test)] +#[cfg(feature = "devnet1")] mod tests { - use alloy_primitives::hex; use ssz::{Decode, Encode}; @@ -241,7 +241,6 @@ mod tests { attestations: Default::default(), }, }, - #[cfg(feature = "devnet1")] proposer_attestation: Attestation { validator_id: 0, data: AttestationData { @@ -251,24 +250,8 @@ mod tests { source: Checkpoint::default(), }, }, - #[cfg(feature = "devnet2")] - proposer_attestation: AggregatedAttestations { - validator_id: 0, - data: AttestationData { - slot: 0, - head: Checkpoint::default(), - target: Checkpoint::default(), - source: Checkpoint::default(), - }, - }, }, - #[cfg(feature = "devnet1")] signature: VariableList::default(), - #[cfg(feature = "devnet2")] - signature: BlockSignatures { - attestation_signatures: VariableList::default(), - proposer_signature: Signature::blank(), - }, }; let encode = signed_block_with_attestation.as_ssz_bytes(); diff --git a/crates/common/consensus/lean/src/state.rs b/crates/common/consensus/lean/src/state.rs index 2c2f51e30..a6ffd692c 100644 --- a/crates/common/consensus/lean/src/state.rs +++ b/crates/common/consensus/lean/src/state.rs @@ -448,12 +448,10 @@ impl LeanState { #[cfg(feature = "devnet2")] for (validator_id, signed) in attestation.aggregation_bits.iter().enumerate() { - if signed { - if !justifications.get(validator_id).unwrap_or(false) { - justifications.set(validator_id, true).map_err(|err| { - anyhow!("Failed to set validator {validator_id}: {err:?}") - })?; - } + if signed && !justifications.get(validator_id).unwrap_or(false) { + justifications.set(validator_id, true).map_err(|err| { + anyhow!("Failed to set validator {validator_id}: {err:?}") + })?; } } diff --git a/crates/common/fork_choice/lean/src/store.rs b/crates/common/fork_choice/lean/src/store.rs index cb131534e..c9dd9080e 100644 --- a/crates/common/fork_choice/lean/src/store.rs +++ b/crates/common/fork_choice/lean/src/store.rs @@ -908,6 +908,10 @@ mod tests { use alloy_primitives::{B256, FixedBytes}; #[cfg(feature = "devnet1")] use ream_consensus_lean::attestation::Attestation; + #[cfg(feature = "devnet1")] + use ream_consensus_lean::block::{BlockBody, BlockHeader}; + #[cfg(feature = "devnet1")] + use ream_consensus_lean::config::Config; #[cfg(feature = "devnet2")] use ream_consensus_lean::{ attestation::{AggregatedAttestation, AggregatedAttestations}, @@ -915,12 +919,8 @@ mod tests { }; use ream_consensus_lean::{ attestation::{AttestationData, SignedAttestation}, - block::{ - Block, BlockBody, BlockHeader, BlockWithAttestation, BlockWithSignatures, - SignedBlockWithAttestation, - }, + block::{Block, BlockWithAttestation, BlockWithSignatures, SignedBlockWithAttestation}, checkpoint::Checkpoint, - config::Config, state::LeanState, utils::generate_default_validators, validator::is_proposer, @@ -1014,6 +1014,7 @@ mod tests { /// Test basic block production by authorized proposer. #[tokio::test] + #[cfg(feature = "devnet1")] async fn test_produce_block_basic() { let (mut store, mut genesis_state) = sample_store(10).await; @@ -1187,6 +1188,7 @@ mod tests { /// Test that produced block's state is consistent with block content #[tokio::test] + #[cfg(feature = "devnet1")] pub async fn test_produce_block_state_consistency() { let (mut store, _) = sample_store(10).await; @@ -1203,7 +1205,6 @@ mod tests { let head_block = block_provider.get(head).unwrap().unwrap(); let attestation = SignedAttestation { - #[cfg(feature = "devnet1")] message: Attestation { validator_id: 7, data: AttestationData { @@ -1216,19 +1217,7 @@ mod tests { source: store.get_attestation_target().await.unwrap(), }, }, - #[cfg(feature = "devnet2")] - message: AttestationData { - slot: head_block.message.block.slot, - head: Checkpoint { - root: head, - slot: head_block.message.block.slot, - }, - target: latest_justified_provider.get().unwrap(), - source: store.get_attestation_target().await.unwrap(), - }, signature: Signature::blank(), - #[cfg(feature = "devnet2")] - validator_id: 7, }; latest_known_attestations.insert(7, attestation).unwrap(); @@ -1456,6 +1445,7 @@ mod tests { /// Test producing a block then creating attestation for it. #[tokio::test] + #[cfg(feature = "devnet1")] pub async fn test_block_production_then_attestation() { let (mut store, _) = sample_store(10).await; @@ -1479,42 +1469,22 @@ mod tests { store.update_head().await.unwrap(); - #[cfg(feature = "devnet1")] let attestation = Attestation { validator_id: 7, data: store.produce_attestation_data(2).await.unwrap(), }; - #[cfg(feature = "devnet2")] - let mut aggregation_bits = BitList::::with_capacity(32).unwrap(); - #[cfg(feature = "devnet2")] - aggregation_bits.set(0, true).unwrap(); - - #[cfg(feature = "devnet2")] - let attestation = AggregatedAttestation { - aggregation_bits, - message: store.produce_attestation_data(2).await.unwrap(), - }; - - #[cfg(feature = "devnet1")] assert_eq!(attestation.validator_id, 7); - #[cfg(feature = "devnet2")] - assert_eq!(attestation.aggregation_bits, attestation.aggregation_bits); assert_eq!(attestation.slot(), 2); - #[cfg(feature = "devnet1")] assert_eq!( attestation.data.source, latest_justified_provider.get().unwrap() ); - #[cfg(feature = "devnet2")] - assert_eq!( - attestation.message.source, - latest_justified_provider.get().unwrap() - ); } /// Test producing a block then creating attestation for it. #[tokio::test] + #[cfg(feature = "devnet1")] pub async fn test_multiple_validators_coordination() { let (mut store, _) = sample_store(10).await; @@ -1543,17 +1513,11 @@ mod tests { let mut attestations = Vec::new(); for i in 2..6 { - #[cfg(feature = "devnet1")] let attestation = Attestation { validator_id: i, data: store.produce_attestation_data(2).await.unwrap(), }; - #[cfg(feature = "devnet2")] - let attestation = AggregatedAttestations { - validator_id: i, - data: store.produce_attestation_data(2).await.unwrap(), - }; attestations.push(attestation); } @@ -1602,6 +1566,7 @@ mod tests { /// Test edge cases in validator operations. #[tokio::test] + #[cfg(feature = "devnet1")] pub async fn test_validator_edge_cases() { let (mut store, _) = sample_store(10).await; @@ -1620,31 +1585,18 @@ mod tests { .await .unwrap(); - #[cfg(feature = "devnet1")] let attestation = Attestation { validator_id: 9, data: store.produce_attestation_data(10).await.unwrap(), }; - #[cfg(feature = "devnet2")] - let mut aggregation_bits = BitList::::with_capacity(32).unwrap(); - #[cfg(feature = "devnet2")] - aggregation_bits.set(0, true).unwrap(); - - #[cfg(feature = "devnet2")] - let attestation = AggregatedAttestation { - aggregation_bits, - message: store.produce_attestation_data(10).await.unwrap(), - }; - #[cfg(feature = "devnet1")] assert_eq!(attestation.validator_id, 9); - #[cfg(feature = "devnet2")] - assert_eq!(attestation.aggregation_bits, attestation.aggregation_bits); assert_eq!(attestation.slot(), 10); } /// Test validator operations with minimal store state. #[tokio::test] + #[cfg(feature = "devnet1")] pub async fn test_validator_operations_empty_store() { let empty_checkpoint = Checkpoint { slot: 0, diff --git a/testing/lean-spec-tests/Cargo.toml b/testing/lean-spec-tests/Cargo.toml index 2bccda44e..025fe1370 100644 --- a/testing/lean-spec-tests/Cargo.toml +++ b/testing/lean-spec-tests/Cargo.toml @@ -12,8 +12,8 @@ version.workspace = true [features] lean-spec-tests = [] default = ["devnet1"] -devnet1 = [] -devnet2 = [] +devnet1 = ["ream-consensus-lean/devnet1", "ream-fork-choice-lean/devnet1"] +devnet2 = ["ream-consensus-lean/devnet2", "ream-fork-choice-lean/devnet2"] [dependencies] alloy-primitives.workspace = true