From 102df5b8dd283f6cfc46cc1dd72c8cc6d2cb3fe4 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 15 Apr 2025 13:05:53 -0700 Subject: [PATCH 1/9] Add test coverage for fulu and a small bugfix --- beacon_node/http_api/src/publish_blocks.rs | 36 ++++--- .../tests/broadcast_validation_tests.rs | 100 +++++++++++++++--- 2 files changed, 103 insertions(+), 33 deletions(-) diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index 3d152f88527..f74fe19c5a2 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -228,23 +228,25 @@ pub async fn publish_block>( .into_iter() .flatten() .filter(|data_column| sampling_columns_indices.contains(&data_column.index())) - .collect(); - - // Importing the columns could trigger block import and network publication in the case - // where the block was already seen on gossip. - if let Err(e) = - Box::pin(chain.process_gossip_data_columns(sampling_columns, publish_fn)).await - { - let msg = format!("Invalid data column: {e}"); - return if let BroadcastValidation::Gossip = validation_level { - Err(warp_utils::reject::broadcast_without_import(msg)) - } else { - error!( - reason = &msg, - "Invalid data column during block publication" - ); - Err(warp_utils::reject::custom_bad_request(msg)) - }; + .collect::>(); + + if !sampling_columns.is_empty() { + // Importing the columns could trigger block import and network publication in the case + // where the block was already seen on gossip. + if let Err(e) = + Box::pin(chain.process_gossip_data_columns(sampling_columns, publish_fn)).await + { + let msg = format!("Invalid data column: {e}"); + return if let BroadcastValidation::Gossip = validation_level { + Err(warp_utils::reject::broadcast_without_import(msg)) + } else { + error!( + reason = &msg, + "Invalid data column during block publication" + ); + Err(warp_utils::reject::custom_bad_request(msg)) + }; + } } } diff --git a/beacon_node/http_api/tests/broadcast_validation_tests.rs b/beacon_node/http_api/tests/broadcast_validation_tests.rs index cd590580be4..e0af3cabcab 100644 --- a/beacon_node/http_api/tests/broadcast_validation_tests.rs +++ b/beacon_node/http_api/tests/broadcast_validation_tests.rs @@ -4,6 +4,7 @@ use beacon_chain::{ }; use eth2::reqwest::StatusCode; use eth2::types::{BroadcastValidation, PublishBlockRequest}; +use futures::future::join_all; use http_api::test_utils::InteractiveTester; use http_api::{publish_blinded_block, publish_block, reconstruct_block, Config, ProvenancedBlock}; use std::collections::HashSet; @@ -1362,17 +1363,30 @@ pub async fn blinded_equivocation_full_pass() { .block_is_known_to_fork_choice(&block.canonical_root())); } -/// This test checks that an HTTP POST request with the block & blobs succeeds with a 200 response -/// even if the block has already been seen on gossip without any blobs. +/// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response +/// even if the block has already been seen on gossip without any blobs/columns. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn block_seen_on_gossip_without_blobs() { +pub async fn test_block_seen_on_gossip_without_blobs_or_columns() { + let deneb_enabled_forks = ForkName::list_all() + .into_iter() + .filter(|f| f.deneb_enabled()) + .collect::>(); + + let futures = deneb_enabled_forks + .into_iter() + .map(|fork| block_seen_on_gossip_without_blobs_or_columns(fork)); + + join_all(futures).await; +} + +pub async fn block_seen_on_gossip_without_blobs_or_columns(fork_name: ForkName) { let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); + let spec = fork_name.make_genesis_spec(E::default_spec()); let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. @@ -1424,17 +1438,30 @@ pub async fn block_seen_on_gossip_without_blobs() { .block_is_known_to_fork_choice(&block.canonical_root())); } -/// This test checks that an HTTP POST request with the block & blobs succeeds with a 200 response -/// even if the block has already been seen on gossip without all blobs. +/// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response +/// even if the block has already been seen on gossip without all blobs/columns. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn block_seen_on_gossip_with_some_blobs() { +pub async fn test_block_seen_on_gossip_with_some_blobs_or_columns() { + let deneb_enabled_forks = ForkName::list_all() + .into_iter() + .filter(|f| f.deneb_enabled()) + .collect::>(); + + let futures = deneb_enabled_forks + .into_iter() + .map(|fork| block_seen_on_gossip_with_some_blobs_or_columns(fork)); + + join_all(futures).await; +} + +pub async fn block_seen_on_gossip_with_some_blobs_or_columns(fork_name: ForkName) { let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); + let spec = fork_name.make_genesis_spec(E::default_spec()); let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. @@ -1504,17 +1531,30 @@ pub async fn block_seen_on_gossip_with_some_blobs() { .block_is_known_to_fork_choice(&block.canonical_root())); } -/// This test checks that an HTTP POST request with the block & blobs succeeds with a 200 response -/// even if the blobs have already been seen on gossip. +/// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response +/// even if the blobs/columns have already been seen on gossip. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn blobs_seen_on_gossip_without_block() { +pub async fn test_blobs_or_columns_seen_on_gossip_without_block() { + let deneb_enabled_forks = ForkName::list_all() + .into_iter() + .filter(|f| f.deneb_enabled()) + .collect::>(); + + let futures = deneb_enabled_forks + .into_iter() + .map(|fork| blobs_or_columns_seen_on_gossip_without_block(fork)); + + join_all(futures).await; +} + +pub async fn blobs_or_columns_seen_on_gossip_without_block(fork_name: ForkName) { + let spec = fork_name.make_genesis_spec(E::default_spec()); let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. @@ -1573,14 +1613,29 @@ pub async fn blobs_seen_on_gossip_without_block() { /// This test checks that an HTTP POST request with the block succeeds with a 200 response /// if just the blobs have already been seen on gossip. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn blobs_seen_on_gossip_without_block_and_no_http_blobs() { +pub async fn test_blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns() { + let deneb_enabled_forks = ForkName::list_all() + .into_iter() + .filter(|f| f.deneb_enabled()) + .collect::>(); + + let futures = deneb_enabled_forks.into_iter().map(|fork| { + blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns(fork) + }); + + join_all(futures).await; +} + +async fn blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns( + fork_name: ForkName, +) { let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); + let spec = fork_name.make_genesis_spec(E::default_spec()); let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. @@ -1641,7 +1696,20 @@ pub async fn blobs_seen_on_gossip_without_block_and_no_http_blobs() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn slashable_blobs_seen_on_gossip_cause_failure() { +pub async fn test_slashable_blobs_or_columns_seen_on_gossip_cause_failure() { + let deneb_enabled_forks = ForkName::list_all() + .into_iter() + .filter(|f| f.deneb_enabled()) + .collect::>(); + + let futures = deneb_enabled_forks + .into_iter() + .map(|fork| slashable_blobs_or_columns_seen_on_gossip_cause_failure(fork)); + + join_all(futures).await; +} + +async fn slashable_blobs_or_columns_seen_on_gossip_cause_failure(fork_name: ForkName) { let validation_level: Option = Some(BroadcastValidation::ConsensusAndEquivocation); @@ -1649,7 +1717,7 @@ pub async fn slashable_blobs_seen_on_gossip_cause_failure() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); + let spec = fork_name.make_genesis_spec(E::default_spec()); let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. From 093ab14c317eef6ff8a25f74259c3e7820dc8ea3 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 15 Apr 2025 13:28:09 -0700 Subject: [PATCH 2/9] linting --- .../http_api/tests/broadcast_validation_tests.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/beacon_node/http_api/tests/broadcast_validation_tests.rs b/beacon_node/http_api/tests/broadcast_validation_tests.rs index e0af3cabcab..5dd4ca58502 100644 --- a/beacon_node/http_api/tests/broadcast_validation_tests.rs +++ b/beacon_node/http_api/tests/broadcast_validation_tests.rs @@ -1374,7 +1374,7 @@ pub async fn test_block_seen_on_gossip_without_blobs_or_columns() { let futures = deneb_enabled_forks .into_iter() - .map(|fork| block_seen_on_gossip_without_blobs_or_columns(fork)); + .map(block_seen_on_gossip_without_blobs_or_columns); join_all(futures).await; } @@ -1449,7 +1449,7 @@ pub async fn test_block_seen_on_gossip_with_some_blobs_or_columns() { let futures = deneb_enabled_forks .into_iter() - .map(|fork| block_seen_on_gossip_with_some_blobs_or_columns(fork)); + .map(block_seen_on_gossip_with_some_blobs_or_columns); join_all(futures).await; } @@ -1542,7 +1542,7 @@ pub async fn test_blobs_or_columns_seen_on_gossip_without_block() { let futures = deneb_enabled_forks .into_iter() - .map(|fork| blobs_or_columns_seen_on_gossip_without_block(fork)); + .map(blobs_or_columns_seen_on_gossip_without_block); join_all(futures).await; } @@ -1619,9 +1619,9 @@ pub async fn test_blobs_or_columns_seen_on_gossip_without_block_and_no_http_blob .filter(|f| f.deneb_enabled()) .collect::>(); - let futures = deneb_enabled_forks.into_iter().map(|fork| { - blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns(fork) - }); + let futures = deneb_enabled_forks + .into_iter() + .map(blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns); join_all(futures).await; } @@ -1704,7 +1704,7 @@ pub async fn test_slashable_blobs_or_columns_seen_on_gossip_cause_failure() { let futures = deneb_enabled_forks .into_iter() - .map(|fork| slashable_blobs_or_columns_seen_on_gossip_cause_failure(fork)); + .map(slashable_blobs_or_columns_seen_on_gossip_cause_failure); join_all(futures).await; } From e19333e985ebbd5d86fbeb715e1b6ccddab313a0 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 22 Apr 2025 17:49:25 -0700 Subject: [PATCH 3/9] run http_api tests for fork variants --- Makefile | 11 ++ .../tests/broadcast_validation_tests.rs | 124 ++++++------------ 2 files changed, 52 insertions(+), 83 deletions(-) diff --git a/Makefile b/Makefile index f621f38a63e..07afa85d3a6 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,9 @@ PROFILE ?= release # they run for different forks. FORKS=phase0 altair bellatrix capella deneb electra fulu +# List of all recent hard forks. This list is used to set env variables for http_api tests +RECENT_FORKS=deneb electra fulu + # Extra flags for Cargo CARGO_INSTALL_EXTRA_FLAGS?= @@ -101,6 +104,7 @@ build-release-tarballs: test-release: cargo test --workspace --release --features "$(TEST_FEATURES)" \ --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network + -- exclude http_api # Runs the full workspace tests in **release**, without downloading any additional # test vectors, using nextest. @@ -148,6 +152,13 @@ test-beacon-chain: $(patsubst %,test-beacon-chain-%,$(FORKS)) test-beacon-chain-%: env FORK_NAME=$* cargo nextest run --release --features "fork_from_env,slasher/lmdb,$(TEST_FEATURES)" -p beacon_chain +# Run the tests in the `beacon_chain` crate for all known forks. +test-http-api: $(patsubst %,test-beacon-chain-%,$(RECENT_FORKS)) + +test-http-api-%: + env FORK_NAME=$* cargo nextest run --release --features "fork_from_env,slasher/lmdb,$(TEST_FEATURES)" -p http_api + + # Run the tests in the `operation_pool` crate for all known forks. test-op-pool: $(patsubst %,test-op-pool-%,$(FORKS)) diff --git a/beacon_node/http_api/tests/broadcast_validation_tests.rs b/beacon_node/http_api/tests/broadcast_validation_tests.rs index 5dd4ca58502..0d5a3f1a097 100644 --- a/beacon_node/http_api/tests/broadcast_validation_tests.rs +++ b/beacon_node/http_api/tests/broadcast_validation_tests.rs @@ -1,10 +1,10 @@ +use beacon_chain::test_utils::test_spec; use beacon_chain::{ test_utils::{AttestationStrategy, BlockStrategy}, GossipVerifiedBlock, IntoGossipVerifiedBlock, }; use eth2::reqwest::StatusCode; use eth2::types::{BroadcastValidation, PublishBlockRequest}; -use futures::future::join_all; use http_api::test_utils::InteractiveTester; use http_api::{publish_blinded_block, publish_block, reconstruct_block, Config, ProvenancedBlock}; use std::collections::HashSet; @@ -1366,28 +1366,20 @@ pub async fn blinded_equivocation_full_pass() { /// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response /// even if the block has already been seen on gossip without any blobs/columns. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn test_block_seen_on_gossip_without_blobs_or_columns() { - let deneb_enabled_forks = ForkName::list_all() - .into_iter() - .filter(|f| f.deneb_enabled()) - .collect::>(); - - let futures = deneb_enabled_forks - .into_iter() - .map(block_seen_on_gossip_without_blobs_or_columns); - - join_all(futures).await; -} - -pub async fn block_seen_on_gossip_without_blobs_or_columns(fork_name: ForkName) { +pub async fn block_seen_on_gossip_without_blobs_or_columns() { + let spec = test_spec::(); let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = fork_name.make_genesis_spec(E::default_spec()); - let tester = InteractiveTester::::new(Some(spec), validator_count).await; + let tester = InteractiveTester::::new(Some(spec.clone()), validator_count).await; + let state = tester.harness.get_current_state(); + let fork_name = state.fork_name(&spec).unwrap(); + if !fork_name.deneb_enabled() { + return; + } // Create some chain depth. tester.harness.advance_slot(); @@ -1441,28 +1433,20 @@ pub async fn block_seen_on_gossip_without_blobs_or_columns(fork_name: ForkName) /// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response /// even if the block has already been seen on gossip without all blobs/columns. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn test_block_seen_on_gossip_with_some_blobs_or_columns() { - let deneb_enabled_forks = ForkName::list_all() - .into_iter() - .filter(|f| f.deneb_enabled()) - .collect::>(); - - let futures = deneb_enabled_forks - .into_iter() - .map(block_seen_on_gossip_with_some_blobs_or_columns); - - join_all(futures).await; -} - -pub async fn block_seen_on_gossip_with_some_blobs_or_columns(fork_name: ForkName) { +pub async fn block_seen_on_gossip_with_some_blobs_or_columns() { + let spec = test_spec::(); let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = fork_name.make_genesis_spec(E::default_spec()); - let tester = InteractiveTester::::new(Some(spec), validator_count).await; + let tester = InteractiveTester::::new(Some(spec.clone()), validator_count).await; + let state = tester.harness.get_current_state(); + let fork_name = state.fork_name(&spec).unwrap(); + if !fork_name.deneb_enabled() { + return; + } // Create some chain depth. tester.harness.advance_slot(); @@ -1534,28 +1518,20 @@ pub async fn block_seen_on_gossip_with_some_blobs_or_columns(fork_name: ForkName /// This test checks that an HTTP POST request with the block & blobs/columns succeeds with a 200 response /// even if the blobs/columns have already been seen on gossip. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn test_blobs_or_columns_seen_on_gossip_without_block() { - let deneb_enabled_forks = ForkName::list_all() - .into_iter() - .filter(|f| f.deneb_enabled()) - .collect::>(); - - let futures = deneb_enabled_forks - .into_iter() - .map(blobs_or_columns_seen_on_gossip_without_block); - - join_all(futures).await; -} - -pub async fn blobs_or_columns_seen_on_gossip_without_block(fork_name: ForkName) { - let spec = fork_name.make_genesis_spec(E::default_spec()); +pub async fn blobs_or_columns_seen_on_gossip_without_block() { + let spec = test_spec::(); let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(Some(spec), validator_count).await; + let tester = InteractiveTester::::new(Some(spec.clone()), validator_count).await; + let state = tester.harness.get_current_state(); + let fork_name = state.fork_name(&spec).unwrap(); + if !fork_name.deneb_enabled() { + return; + } // Create some chain depth. tester.harness.advance_slot(); @@ -1613,30 +1589,20 @@ pub async fn blobs_or_columns_seen_on_gossip_without_block(fork_name: ForkName) /// This test checks that an HTTP POST request with the block succeeds with a 200 response /// if just the blobs have already been seen on gossip. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn test_blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns() { - let deneb_enabled_forks = ForkName::list_all() - .into_iter() - .filter(|f| f.deneb_enabled()) - .collect::>(); - - let futures = deneb_enabled_forks - .into_iter() - .map(blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns); - - join_all(futures).await; -} - -async fn blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns( - fork_name: ForkName, -) { +async fn blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_columns() { + let spec = test_spec::(); let validation_level: Option = Some(BroadcastValidation::Gossip); // Validator count needs to be at least 32 or proposer boost gets set to 0 when computing // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = fork_name.make_genesis_spec(E::default_spec()); - let tester = InteractiveTester::::new(Some(spec), validator_count).await; + let tester = InteractiveTester::::new(Some(spec.clone()), validator_count).await; + let state = tester.harness.get_current_state(); + let fork_name = state.fork_name(&spec).unwrap(); + if !fork_name.deneb_enabled() { + return; + } // Create some chain depth. tester.harness.advance_slot(); @@ -1696,20 +1662,7 @@ async fn blobs_or_columns_seen_on_gossip_without_block_and_no_http_blobs_or_colu } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -pub async fn test_slashable_blobs_or_columns_seen_on_gossip_cause_failure() { - let deneb_enabled_forks = ForkName::list_all() - .into_iter() - .filter(|f| f.deneb_enabled()) - .collect::>(); - - let futures = deneb_enabled_forks - .into_iter() - .map(slashable_blobs_or_columns_seen_on_gossip_cause_failure); - - join_all(futures).await; -} - -async fn slashable_blobs_or_columns_seen_on_gossip_cause_failure(fork_name: ForkName) { +async fn slashable_blobs_or_columns_seen_on_gossip_cause_failure() { let validation_level: Option = Some(BroadcastValidation::ConsensusAndEquivocation); @@ -1717,8 +1670,13 @@ async fn slashable_blobs_or_columns_seen_on_gossip_cause_failure(fork_name: Fork // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = fork_name.make_genesis_spec(E::default_spec()); - let tester = InteractiveTester::::new(Some(spec), validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec.clone()), validator_count).await; + let state = tester.harness.get_current_state(); + let fork_name = state.fork_name(&spec).unwrap(); + if !fork_name.deneb_enabled() { + return; + } // Create some chain depth. tester.harness.advance_slot(); From 999a1c0332c58cf42af931700be0fa5e72b9174f Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 22 Apr 2025 17:49:37 -0700 Subject: [PATCH 4/9] add test to ci --- .github/workflows/test-suite.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 817fd9524df..1972fa7b9aa 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -159,6 +159,28 @@ jobs: - name: Show cache stats if: env.SELF_HOSTED_RUNNERS == 'true' run: sccache --show-stats + http-api-tests: + name: http-api-tests + needs: [check-labels] + if: needs.check-labels.outputs.skip_ci != 'true' + # Use self-hosted runners only on the sigp repo. + runs-on: ${{ github.repository == 'sigp/lighthouse' && fromJson('["self-hosted", "linux", "CI", "large"]') || 'ubuntu-latest' }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + - name: Get latest version of stable Rust + if: env.SELF_HOSTED_RUNNERS == 'false' + uses: moonrepo/setup-rust@v1 + with: + channel: stable + cache-target: release + bins: cargo-nextest + - name: Run http_api tests for all recent forks + run: make test-http-api + - name: Show cache stats + if: env.SELF_HOSTED_RUNNERS == 'true' + run: sccache --show-stats op-pool-tests: name: op-pool-tests needs: [check-labels] From 2bb0eae40b61281dccde75b1e0897421803c93b2 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 22 Apr 2025 18:21:29 -0700 Subject: [PATCH 5/9] all broadcast validation tests have test variants --- .../tests/broadcast_validation_tests.rs | 74 ++++++++++++------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/beacon_node/http_api/tests/broadcast_validation_tests.rs b/beacon_node/http_api/tests/broadcast_validation_tests.rs index 0d5a3f1a097..32447e5885d 100644 --- a/beacon_node/http_api/tests/broadcast_validation_tests.rs +++ b/beacon_node/http_api/tests/broadcast_validation_tests.rs @@ -53,7 +53,8 @@ pub async fn gossip_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -103,7 +104,8 @@ pub async fn gossip_partial_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -149,7 +151,8 @@ pub async fn gossip_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -239,7 +242,8 @@ pub async fn consensus_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -288,7 +292,8 @@ pub async fn consensus_gossip() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -334,7 +339,8 @@ pub async fn consensus_partial_pass_only_consensus() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -405,7 +411,8 @@ pub async fn consensus_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -451,7 +458,8 @@ pub async fn equivocation_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -501,7 +509,8 @@ pub async fn equivocation_consensus_early_equivocation() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -575,7 +584,8 @@ pub async fn equivocation_gossip() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -625,7 +635,8 @@ pub async fn equivocation_consensus_late_equivocation() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -701,7 +712,8 @@ pub async fn equivocation_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -746,7 +758,8 @@ pub async fn blinded_gossip_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -795,7 +808,8 @@ pub async fn blinded_gossip_partial_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -841,7 +855,8 @@ pub async fn blinded_gossip_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -882,7 +897,8 @@ pub async fn blinded_gossip_full_pass_ssz() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -924,7 +940,8 @@ pub async fn blinded_consensus_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -973,7 +990,8 @@ pub async fn blinded_consensus_gossip() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1019,7 +1037,8 @@ pub async fn blinded_consensus_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1062,7 +1081,8 @@ pub async fn blinded_equivocation_invalid() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1112,7 +1132,8 @@ pub async fn blinded_equivocation_consensus_early_equivocation() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1182,7 +1203,8 @@ pub async fn blinded_equivocation_gossip() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1235,7 +1257,8 @@ pub async fn blinded_equivocation_consensus_late_equivocation() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1331,7 +1354,8 @@ pub async fn blinded_equivocation_full_pass() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let tester = InteractiveTester::::new(None, validator_count).await; + let spec = test_spec::(); + let tester = InteractiveTester::::new(Some(spec), validator_count).await; // Create some chain depth. tester.harness.advance_slot(); @@ -1743,7 +1767,7 @@ pub async fn duplicate_block_status_code() { // `validator_count // 32`. let validator_count = 64; let num_initial: u64 = 31; - let spec = ForkName::latest_stable().make_genesis_spec(E::default_spec()); + let spec = test_spec::(); let duplicate_block_status_code = StatusCode::IM_A_TEAPOT; let tester = InteractiveTester::::new_with_initializer_and_mutator( Some(spec), From 2c0370d0a7320590b38e6ed3b25a1af26d85ae6b Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 22 Apr 2025 18:40:27 -0700 Subject: [PATCH 6/9] update makefile --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 07afa85d3a6..043cc030b6f 100644 --- a/Makefile +++ b/Makefile @@ -104,25 +104,26 @@ build-release-tarballs: test-release: cargo test --workspace --release --features "$(TEST_FEATURES)" \ --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network - -- exclude http_api + --exclude http_api # Runs the full workspace tests in **release**, without downloading any additional # test vectors, using nextest. nextest-release: cargo nextest run --workspace --release --features "$(TEST_FEATURES)" \ --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network + --exclude http_api # Runs the full workspace tests in **debug**, without downloading any additional test # vectors. test-debug: cargo test --workspace --features "$(TEST_FEATURES)" \ - --exclude ef_tests --exclude beacon_chain --exclude network + --exclude ef_tests --exclude beacon_chain --exclude network --exclude http_api # Runs the full workspace tests in **debug**, without downloading any additional test # vectors, using nextest. nextest-debug: cargo nextest run --workspace --features "$(TEST_FEATURES)" \ - --exclude ef_tests --exclude beacon_chain --exclude network + --exclude ef_tests --exclude beacon_chain --exclude network --exclude http_api # Runs cargo-fmt (linter). cargo-fmt: From cb9cdfa29b54f2bd800714bb6d0f702f74cce971 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 14 May 2025 11:41:02 -0700 Subject: [PATCH 7/9] update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 043cc030b6f..ab67be5563a 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,7 @@ test-release: # test vectors, using nextest. nextest-release: cargo nextest run --workspace --release --features "$(TEST_FEATURES)" \ - --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network + --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network --exclude http_api # Runs the full workspace tests in **debug**, without downloading any additional test From d2f16a448fa28306da334601072b004982946314 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 14 May 2025 12:28:48 -0700 Subject: [PATCH 8/9] fix makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ab67be5563a..d3dd0b0062a 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,7 @@ test-release: # test vectors, using nextest. nextest-release: cargo nextest run --workspace --release --features "$(TEST_FEATURES)" \ - --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network + --exclude ef_tests --exclude beacon_chain --exclude slasher --exclude network \ --exclude http_api # Runs the full workspace tests in **debug**, without downloading any additional test From 54d177a47f394275ae1fbc996d2b59ae1cb1a522 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 20 May 2025 10:03:41 -0700 Subject: [PATCH 9/9] add test success check --- .github/workflows/test-suite.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 751656a78f6..e7c95e88299 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -497,6 +497,7 @@ jobs: 'op-pool-tests', 'network-tests', 'slasher-tests', + 'http-api-tests', 'debug-tests-ubuntu', 'state-transition-vectors-ubuntu', 'ef-tests-ubuntu',