Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/core-rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand Down
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions bin/ream/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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",
Expand Down
11 changes: 1 addition & 10 deletions crates/common/consensus/lean/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub struct SignedAggregatedAttestation {
}

#[cfg(test)]
#[cfg(feature = "devnet1")]
mod tests {
use alloy_primitives::hex;
use ssz::{Decode, Encode};
Expand All @@ -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 {
Expand All @@ -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(),
},
Expand Down
19 changes: 1 addition & 18 deletions crates/common/consensus/lean/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ pub struct BlockWithSignatures {
}

#[cfg(test)]
#[cfg(feature = "devnet1")]
mod tests {

use alloy_primitives::hex;
use ssz::{Decode, Encode};

Expand All @@ -241,7 +241,6 @@ mod tests {
attestations: Default::default(),
},
},
#[cfg(feature = "devnet1")]
proposer_attestation: Attestation {
validator_id: 0,
data: AttestationData {
Expand All @@ -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();
Expand Down
10 changes: 4 additions & 6 deletions crates/common/consensus/lean/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:?}")
})?;
}
}

Expand Down
70 changes: 11 additions & 59 deletions crates/common/fork_choice/lean/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,19 +908,19 @@ 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},
block::BlockSignatures,
};
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,
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -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();

Expand Down Expand Up @@ -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;

Expand All @@ -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::<U4096>::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;

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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;

Expand All @@ -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::<U4096>::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,
Expand Down
4 changes: 2 additions & 2 deletions testing/lean-spec-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down