Skip to content

Commit

Permalink
refactor: use generics for consensus test specs testing to reduce cod…
Browse files Browse the repository at this point in the history
…e duplication (#1621)
  • Loading branch information
KolbyML authored Jan 13, 2025
1 parent 5dd8514 commit 4323283
Show file tree
Hide file tree
Showing 223 changed files with 553 additions and 346,630 deletions.
7 changes: 5 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,10 @@ jobs:
- setup-and-restore-sccache-cache
- run:
name: Test Trin workspace
command: cargo test --workspace -- --nocapture
command: make test
- run:
name: Test Consensus spec tests
command: make ef-tests
- save-sccache-cache
# 'cargo check' performs all the compilation without actually building the crate, so it is quicker for the same guarantee
check-workspace-crates:
Expand All @@ -232,7 +235,7 @@ jobs:
# parallelism level should be set to the amount of simulators we have or greater
# The reason for this is the CI code currently only supports 1 input at a time
# if we have a parallelism level of 5 and 6 sims one test runner will get 2 test sims and fail
parallelism: 18
parallelism: 19
steps:
- checkout
- run:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
.python-version
.DS_Store
*rusty-tags.vi

# Ignore downloaded consensus specs test data
testing/ef-tests/mainnet*
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"trin-metrics",
"portal-bridge",
"rpc",
"testing/ef-tests",
"trin-beacon",
"trin-evm",
"trin-execution",
Expand Down Expand Up @@ -46,6 +47,8 @@ directories = "3.0"
discv5 = { version = "0.4.1", features = ["serde"] }
env_logger = "0.9.0"
eth_trie = "0.5.0"
ethereum_hashing = "0.7.0"
ethereum_serde_utils = "0.7.0"
ethereum_ssz = "0.7.1"
ethereum_ssz_derive = "0.7.1"
futures = "0.3.23"
Expand Down
47 changes: 45 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ PROFILE ?= release
CARGO_INSTALL_EXTRA_FLAGS ?=

.PHONY: lint
lint: # Run clippy and rustfmt
lint: ## Run clippy and rustfmt
cargo +nightly fmt --all
cargo clippy --all --all-targets --all-features --no-deps -- --deny warnings

.PHONY: lint-unstable
lint-unstable: #run clippy, rustfmt and rustc lints with unstable features. expect errors, which cannot be resolved, so the user must step through and evaluate each one manually.
lint-unstable: ## run clippy, rustfmt and rustc lints with unstable features. expect errors, which cannot be resolved, so the user must step through and evaluate each one manually.
cargo +nightly fmt --all
cargo clippy --all --all-targets --all-features --no-deps -- -Wclippy::cargo
RUSTFLAGS="-W unused_crate_dependencies" cargo build
Expand Down Expand Up @@ -97,6 +97,49 @@ build-release-tarballs: ## Create a series of `.tar.gz` files in the BIN_DIR dir
$(MAKE) build-x86_64-pc-windows-gnu
$(call tarball_release_binary,"x86_64-pc-windows-gnu","trin.exe","")

##@ Tests

EF_TESTS_TARGET = mainnet.tar.gz
EF_TESTS_DIR = ./testing/ef-tests/mainnet
LATEST_RELEASE_URL = https://api.github.com/repos/ethereum/consensus-spec-tests/releases/latest

download_test_data:
@if [ -d $(EF_TESTS_DIR) ]; then \
echo "$(EF_TESTS_DIR) already downloaded. Skipping download."; \
else \
echo "Fetching the latest release URL for $(EF_TESTS_TARGET)..."; \
curl -s $(LATEST_RELEASE_URL) \
| grep "browser_download_url.*$(EF_TESTS_TARGET)" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi -; \
echo "$(EF_TESTS_TARGET) downloaded successfully."; \
fi

extract_test_data: download_test_data
@if [ -d $(EF_TESTS_DIR) ]; then \
echo "$(EF_TESTS_DIR) already exists. Skipping extraction."; \
else \
echo "Extracting $(EF_TESTS_TARGET) into $(EF_TESTS_DIR)..."; \
mkdir -p $(EF_TESTS_DIR); \
tar -xzf $(EF_TESTS_TARGET) -C $(EF_TESTS_DIR); \
rm -f $(EF_TESTS_TARGET); \
echo "Extraction complete."; \
fi

.PHONY: ef-tests
ef-tests: extract_test_data ## Runs Ethereum Foundation tests.
@echo "Running tests..."
@cargo test -p ef-tests --features ef-tests
@echo "Tests complete."

.PHONY: test
test: ## Runs workspace tests.
cargo test --workspace -- --nocapture

.PHONY: test-full
test-full: test ef-tests ## Runs all tests.

##@ Other

.PHONY: clean
Expand Down
4 changes: 2 additions & 2 deletions ethportal-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ c-kzg = "1.0.0"
const_format = {version = "0.2.0", features = ["rust_1_64"]}
discv5.workspace = true
eth_trie.workspace = true
ethereum_hashing = "0.7.0"
ethereum_serde_utils = "0.7.0"
ethereum_hashing.workspace = true
ethereum_serde_utils.workspace = true
ethereum_ssz.workspace = true
ethereum_ssz_derive.workspace = true
hex.workspace = true
Expand Down
179 changes: 0 additions & 179 deletions ethportal-api/src/types/consensus/beacon_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,182 +187,3 @@ impl SignedBeaconBlock {
}
}
}

#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod test {
use std::str::FromStr;

use ::ssz::Encode;
use rstest::rstest;
use serde_json::Value;

use super::*;
use crate::consensus::fork::ForkName;

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn serde_signed_beacon_block_bellatrix(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/bellatrix/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockBellatrix = serde_json::from_value(value.clone()).unwrap();
let serialized = serde_json::to_value(content).unwrap();
assert_eq!(serialized, value);
}

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn ssz_signed_beacon_block_bellatrix(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/bellatrix/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockBellatrix = serde_json::from_value(value).unwrap();

let compressed = std::fs::read(format!(
"../test_assets/beacon/bellatrix/SignedBeaconBlock/ssz_random/{case}/serialized.ssz_snappy"
))
.expect("cannot find test asset");
let mut decoder = snap::raw::Decoder::new();
let expected = decoder.decompress_vec(&compressed).unwrap();
SignedBeaconBlock::from_ssz_bytes(&expected, ForkName::Bellatrix).unwrap();
assert_eq!(content.as_ssz_bytes(), expected);
}

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn serde_signed_beacon_block_capella(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/capella/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockCapella = serde_json::from_value(value.clone()).unwrap();
let serialized = serde_json::to_value(content).unwrap();
assert_eq!(serialized, value);
}

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn ssz_signed_beacon_block_capella(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/capella/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockCapella = serde_json::from_value(value).unwrap();

let compressed = std::fs::read(format!(
"../test_assets/beacon/capella/SignedBeaconBlock/ssz_random/{case}/serialized.ssz_snappy"))
.expect("cannot find test asset");
let mut decoder = snap::raw::Decoder::new();
let expected = decoder.decompress_vec(&compressed).unwrap();
SignedBeaconBlock::from_ssz_bytes(&expected, ForkName::Capella).unwrap();
assert_eq!(content.as_ssz_bytes(), expected);
}

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn serde_signed_beacon_block_deneb(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/deneb/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockDeneb = serde_json::from_value(value.clone()).unwrap();
let serialized = serde_json::to_value(content).unwrap();
assert_eq!(serialized, value);
}

#[rstest]
#[case("case_0")]
#[case("case_1")]
fn ssz_signed_beacon_block_deneb(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/deneb/SignedBeaconBlock/ssz_random/{case}/value.yaml"
))
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: SignedBeaconBlockDeneb = serde_json::from_value(value).unwrap();

let compressed = std::fs::read(format!(
"../test_assets/beacon/deneb/SignedBeaconBlock/ssz_random/{case}/serialized.ssz_snappy"
))
.expect("cannot find test asset");
let mut decoder = snap::raw::Decoder::new();
let expected = decoder.decompress_vec(&compressed).unwrap();
SignedBeaconBlock::from_ssz_bytes(&expected, ForkName::Deneb).unwrap();
assert_eq!(content.as_ssz_bytes(), expected);
}

#[rstest]
#[case("10232841")]
fn json_signed_beacon_block_deneb(#[case] case: &str) {
let value = std::fs::read_to_string(format!(
"../test_assets/beacon/deneb/SignedBeaconBlock/json/{case}.json"
))
.expect("cannot find test asset");
let value: Value = serde_json::from_str(&value).unwrap();
let _: SignedBeaconBlockDeneb = serde_json::from_value(value["data"].clone()).unwrap();
}

#[test]
fn serde_beacon_block_bellatrix() {
let value = std::fs::read_to_string(
"../test_assets/beacon/bellatrix/BeaconBlock/ssz_random/case_0/value.yaml",
)
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: BeaconBlockBellatrix = serde_json::from_value(value.clone()).unwrap();
let serialized = serde_json::to_value(content).unwrap();
assert_eq!(serialized, value);
}

#[test]
fn ssz_beacon_block_bellatrix() {
let value = std::fs::read_to_string(
"../test_assets/beacon/bellatrix/BeaconBlock/ssz_random/case_0/value.yaml",
)
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: BeaconBlockBellatrix = serde_json::from_value(value).unwrap();

let compressed = std::fs::read(
"../test_assets/beacon/bellatrix/BeaconBlock/ssz_random/case_0/serialized.ssz_snappy",
)
.expect("cannot find test asset");
let mut decoder = snap::raw::Decoder::new();
let expected = decoder.decompress_vec(&compressed).unwrap();
BeaconBlock::from_ssz_bytes(&expected, ForkName::Bellatrix).unwrap();
assert_eq!(content.as_ssz_bytes(), expected);
}

#[test]
fn beacon_block_body_root_proof() {
let value = std::fs::read_to_string(
"../test_assets/beacon/bellatrix/BeaconBlock/ssz_random/case_0/value.yaml",
)
.expect("cannot find test asset");
let value: Value = serde_yaml::from_str(&value).unwrap();
let content: BeaconBlockBellatrix = serde_json::from_value(value).unwrap();
let expected_proof = [
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b",
"0x32b5f53d4b2729823f200eeb36bcf8a78fc1da2d60fef6df87a64a351fce46e7",
]
.map(|x| B256::from_str(x).unwrap());
let proof = content.build_body_root_proof();

assert_eq!(proof.len(), 3);
assert_eq!(proof, expected_proof.to_vec());
}
}
Loading

0 comments on commit 4323283

Please sign in to comment.