diff --git a/.github/forbidden-files.txt b/.github/forbidden-files.txt index 1c5e9acab9..eca611585b 100644 --- a/.github/forbidden-files.txt +++ b/.github/forbidden-files.txt @@ -9,6 +9,7 @@ beacon_node/beacon_chain/src/block_reward.rs beacon_node/http_api/src/attestation_performance.rs beacon_node/http_api/src/block_packing_efficiency.rs beacon_node/http_api/src/block_rewards.rs +beacon_node/http_api/src/beacon/execution_payload_envelope.rs common/eth2/src/lighthouse/attestation_performance.rs common/eth2/src/lighthouse/block_packing_efficiency.rs common/eth2/src/lighthouse/block_rewards.rs diff --git a/Cargo.lock b/Cargo.lock index b88b949957..d4a531d26d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2475,7 +2475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" dependencies = [ "data-encoding", - "syn 1.0.109", + "syn 2.0.117", ] [[package]] diff --git a/beacon_node/beacon_chain/src/block_production/gloas.rs b/beacon_node/beacon_chain/src/block_production/gloas.rs index 34571df7a9..f84ad65e12 100644 --- a/beacon_node/beacon_chain/src/block_production/gloas.rs +++ b/beacon_node/beacon_chain/src/block_production/gloas.rs @@ -31,11 +31,10 @@ use types::{ Address, Attestation, AttestationElectra, AttesterSlashing, AttesterSlashingElectra, BeaconBlock, BeaconBlockBodyGloas, BeaconBlockGloas, BeaconState, BeaconStateError, BuilderIndex, ChainSpec, Deposit, Eth1Data, EthSpec, ExecutionBlockHash, ExecutionPayloadBid, - ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequests, ExecutionRequestsGloas, - FullPayload, Graffiti, Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, - SignedBeaconBlock, SignedBlsToExecutionChange, SignedExecutionPayloadBid, - SignedExecutionPayloadEnvelope, SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal, - Withdrawals, + ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequestsGloas, FullPayload, Graffiti, + Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, SignedBeaconBlock, + SignedBlsToExecutionChange, SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope, + SignedVoluntaryExit, Slot, SyncAggregate, Withdrawal, Withdrawals, }; use crate::pending_payload_envelopes::PendingEnvelopeData; @@ -810,11 +809,6 @@ impl BeaconChain { should_override_builder, } = block_proposal_contents; - // The EL get_payload response carries the standard (Electra-shaped) requests; lift them - // into the Gloas variant carried by the envelope and committed to by the bid. - // TODO(gloas): plumb builder deposit/exit requests from the EL. - let execution_requests = to_gloas_execution_requests(execution_requests); - // TODO(gloas) since we are defaulting to local building, execution payment is 0 // execution payment should only be set to > 0 for trusted building. let bid = ExecutionPayloadBid:: { @@ -1113,26 +1107,6 @@ where /// processing. EL-triggered withdrawal-full-exit requests (EIP-7002) and cross-pubkey /// consolidation requests (EIP-7251) call `initiate_validator_exit`, setting the target's /// `exit_epoch`. A voluntary exit for the same validator would then fail with `AlreadyExited`. -/// Lift a fork-agnostic `ExecutionRequests` (as received from the EL) into the Gloas variant. -/// -/// The standard request types are carried over; the Gloas-only builder deposit/exit lists are -/// left empty. -/// TODO(gloas): plumb builder deposit/exit requests from the EL. -fn to_gloas_execution_requests( - requests: ExecutionRequests, -) -> ExecutionRequestsGloas { - match requests { - ExecutionRequests::Gloas(requests) => requests, - other => ExecutionRequestsGloas { - deposits: other.deposits().clone(), - withdrawals: other.withdrawals().clone(), - consolidations: other.consolidations().clone(), - builder_deposits: <_>::default(), - builder_exits: <_>::default(), - }, - } -} - fn filter_voluntary_exits_for_parent_execution_requests( voluntary_exits: &mut Vec, parent_execution_requests: &ExecutionRequestsGloas, diff --git a/beacon_node/beacon_chain/src/payload_bid_verification/tests.rs b/beacon_node/beacon_chain/src/payload_bid_verification/tests.rs index c0ef3ce86c..d198b56d1b 100644 --- a/beacon_node/beacon_chain/src/payload_bid_verification/tests.rs +++ b/beacon_node/beacon_chain/src/payload_bid_verification/tests.rs @@ -1,5 +1,5 @@ +use std::assert_matches; use std::sync::Arc; - use std::time::Duration; use bls::{Keypair, PublicKeyBytes, Signature}; @@ -195,6 +195,40 @@ impl TestContext { } } + fn expected_prev_randao(&self) -> Hash256 { + let current_slot = self.slot_clock.now().expect("should read slot clock"); + let head = self.canonical_head.cached_head(); + *head + .snapshot + .beacon_state + .get_randao_mix(current_slot.epoch(E::slots_per_epoch())) + .expect("should read current epoch randao mix") + } + + fn make_signed_bid( + &self, + slot: Slot, + builder_index: u64, + fee_recipient: Address, + gas_limit: u64, + value: u64, + parent_block_root: Hash256, + ) -> Arc> { + Arc::new(SignedExecutionPayloadBid { + message: ExecutionPayloadBid { + slot, + builder_index, + fee_recipient, + gas_limit, + value, + parent_block_root, + prev_randao: self.expected_prev_randao(), + ..ExecutionPayloadBid::default() + }, + signature: Signature::empty(), + }) + } + fn insert_non_canonical_block(&self) -> Hash256 { let shuffling_id = AttestationShufflingId { shuffling_epoch: Epoch::new(0), @@ -237,28 +271,6 @@ impl TestContext { } } -fn make_signed_bid( - slot: Slot, - builder_index: u64, - fee_recipient: Address, - gas_limit: u64, - value: u64, - parent_block_root: Hash256, -) -> Arc> { - Arc::new(SignedExecutionPayloadBid { - message: ExecutionPayloadBid { - slot, - builder_index, - fee_recipient, - gas_limit, - value, - parent_block_root, - ..ExecutionPayloadBid::default() - }, - signature: Signature::empty(), - }) -} - fn make_signed_preferences( proposal_slot: Slot, validator_index: u64, @@ -309,7 +321,7 @@ fn no_proposer_preferences_for_slot() { } let ctx = TestContext::new(); let gossip = ctx.gossip_ctx(); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( Slot::new(0), 0, Address::ZERO, @@ -335,7 +347,7 @@ fn builder_already_seen_for_slot() { let slot = Slot::new(1); seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); - let bid = make_signed_bid(slot, 42, Address::ZERO, 30_000_000, 100, Hash256::ZERO); + let bid = ctx.make_signed_bid(slot, 42, Address::ZERO, 30_000_000, 100, Hash256::ZERO); let verified = GossipVerifiedPayloadBid { signed_bid: bid.clone(), }; @@ -362,11 +374,11 @@ fn bid_value_below_cached() { seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); let high_bid = GossipVerifiedPayloadBid { - signed_bid: make_signed_bid(slot, 99, Address::ZERO, 30_000_000, 500, Hash256::ZERO), + signed_bid: ctx.make_signed_bid(slot, 99, Address::ZERO, 30_000_000, 500, Hash256::ZERO), }; ctx.bid_cache.insert_highest_bid(high_bid); - let low_bid = make_signed_bid(slot, 1, Address::ZERO, 30_000_000, 100, Hash256::ZERO); + let low_bid = ctx.make_signed_bid(slot, 1, Address::ZERO, 30_000_000, 100, Hash256::ZERO); let result = GossipVerifiedPayloadBid::new(low_bid, &gossip); assert!(matches!( result, @@ -384,7 +396,7 @@ fn invalid_bid_slot() { let slot = Slot::new(5); seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -393,10 +405,7 @@ fn invalid_bid_slot() { ctx.genesis_block_root, ); let result = GossipVerifiedPayloadBid::new(bid, &gossip); - assert!(matches!( - result, - Err(PayloadBidError::InvalidBidSlot { .. }) - )); + assert_matches!(result, Err(PayloadBidError::InvalidBidSlot { .. })); } #[test] @@ -409,7 +418,7 @@ fn fee_recipient_mismatch() { let slot = Slot::new(1); seed_preferences(&ctx, slot, Address::repeat_byte(0xaa), 30_000_000); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -431,7 +440,7 @@ fn gas_limit_mismatch() { let slot = Slot::new(1); seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -459,6 +468,7 @@ fn execution_payment_nonzero() { gas_limit: 30_000_000, execution_payment: 42, parent_block_root: ctx.genesis_block_root, + prev_randao: ctx.expected_prev_randao(), ..ExecutionPayloadBid::default() }, signature: Signature::empty(), @@ -481,7 +491,7 @@ fn unknown_builder_index() { seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); // Use a builder_index that doesn't exist in the registry. - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 9999, Address::ZERO, @@ -508,7 +518,7 @@ fn inactive_builder() { let slot = Slot::new(1); seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, ctx.inactive_builder_index, Address::ZERO, @@ -534,7 +544,7 @@ fn builder_cant_cover_bid() { seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); // Builder index 0 exists but bid value far exceeds their balance. - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -561,7 +571,7 @@ fn parent_block_root_unknown() { // Parent block root not in fork choice. let unknown_root = Hash256::repeat_byte(0xff); - let bid = make_signed_bid(slot, 0, Address::ZERO, 30_000_000, 0, unknown_root); + let bid = ctx.make_signed_bid(slot, 0, Address::ZERO, 30_000_000, 0, unknown_root); let result = GossipVerifiedPayloadBid::new(bid, &gossip); assert!(result.is_err(), "expected error, got Ok"); let err = result.unwrap_err(); @@ -584,7 +594,7 @@ fn parent_block_root_not_canonical() { seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); let fork_root = ctx.insert_non_canonical_block(); - let bid = make_signed_bid(slot, 0, Address::ZERO, 30_000_000, 0, fork_root); + let bid = ctx.make_signed_bid(slot, 0, Address::ZERO, 30_000_000, 0, fork_root); let result = GossipVerifiedPayloadBid::new(bid, &gossip); assert!(result.is_err(), "expected error, got Ok"); let err = result.unwrap_err(); @@ -606,7 +616,7 @@ fn bid_slot_not_after_parent() { let slot = Slot::new(0); seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -649,6 +659,7 @@ fn invalid_blob_kzg_commitments() { gas_limit: 30_000_000, value: 0, parent_block_root: ctx.genesis_block_root, + prev_randao: ctx.expected_prev_randao(), blob_kzg_commitments: VariableList::new(commitments).unwrap(), ..ExecutionPayloadBid::default() }, @@ -672,7 +683,7 @@ fn bad_signature() { seed_preferences(&ctx, slot, Address::ZERO, 30_000_000); // All checks pass but signature is empty/invalid. - let bid = make_signed_bid( + let bid = ctx.make_signed_bid( slot, 0, Address::ZERO, @@ -707,6 +718,7 @@ fn valid_bid() { gas_limit: 30_000_000, value: 0, parent_block_root: ctx.genesis_block_root, + prev_randao: ctx.expected_prev_randao(), ..ExecutionPayloadBid::default() }); let result = GossipVerifiedPayloadBid::new(bid, &gossip); @@ -734,6 +746,7 @@ fn two_builders_coexist_in_cache() { gas_limit: 30_000_000, value: 0, parent_block_root: ctx.genesis_block_root, + prev_randao: ctx.expected_prev_randao(), ..ExecutionPayloadBid::default() }); let result_0 = GossipVerifiedPayloadBid::new(bid_0, &gossip); @@ -751,6 +764,7 @@ fn two_builders_coexist_in_cache() { gas_limit: 30_000_000, value: 1, parent_block_root: ctx.genesis_block_root, + prev_randao: ctx.expected_prev_randao(), ..ExecutionPayloadBid::default() }); let result_1 = GossipVerifiedPayloadBid::new(bid_1, &gossip); @@ -784,7 +798,7 @@ fn bid_equal_to_cached_value_rejected() { // Seed a cached bid with value 100. let high_bid = GossipVerifiedPayloadBid { - signed_bid: make_signed_bid( + signed_bid: ctx.make_signed_bid( slot, 99, Address::ZERO, @@ -796,7 +810,7 @@ fn bid_equal_to_cached_value_rejected() { ctx.bid_cache.insert_highest_bid(high_bid); // Submit a bid with exactly the same value — should be rejected. - let equal_bid = make_signed_bid( + let equal_bid = ctx.make_signed_bid( slot, 1, Address::ZERO, diff --git a/beacon_node/execution_layer/src/engine_api.rs b/beacon_node/execution_layer/src/engine_api.rs index 079a82ff98..9f32bfdfeb 100644 --- a/beacon_node/execution_layer/src/engine_api.rs +++ b/beacon_node/execution_layer/src/engine_api.rs @@ -341,8 +341,13 @@ pub struct GetPayloadResponse { pub blobs_bundle: BlobsBundle, #[superstruct(only(Deneb, Electra, Fulu, Gloas), partial_getter(copy))] pub should_override_builder: bool, - #[superstruct(only(Electra, Fulu, Gloas))] - pub requests: ExecutionRequests, + #[superstruct( + only(Electra, Fulu), + partial_getter(rename = "execution_requests_electra") + )] + pub requests: types::ExecutionRequestsElectra, + #[superstruct(only(Gloas), partial_getter(rename = "execution_requests_gloas"))] + pub requests: types::ExecutionRequestsGloas, } impl GetPayloadResponse { @@ -407,19 +412,19 @@ impl From> ExecutionPayload::Electra(inner.execution_payload), inner.block_value, Some(inner.blobs_bundle), - Some(inner.requests), + Some(ExecutionRequests::Electra(inner.requests)), ), GetPayloadResponse::Fulu(inner) => ( ExecutionPayload::Fulu(inner.execution_payload), inner.block_value, Some(inner.blobs_bundle), - Some(inner.requests), + Some(ExecutionRequests::Electra(inner.requests)), ), GetPayloadResponse::Gloas(inner) => ( ExecutionPayload::Gloas(inner.execution_payload), inner.block_value, Some(inner.blobs_bundle), - Some(inner.requests), + Some(ExecutionRequests::Gloas(inner.requests)), ), } } diff --git a/beacon_node/execution_layer/src/engine_api/json_structures.rs b/beacon_node/execution_layer/src/engine_api/json_structures.rs index 453e4d11be..4071245166 100644 --- a/beacon_node/execution_layer/src/engine_api/json_structures.rs +++ b/beacon_node/execution_layer/src/engine_api/json_structures.rs @@ -474,6 +474,7 @@ pub enum RequestsError { InvalidOrdering, InvalidPrefix(u8), DecodeError(String), + VariantMismatch, } /// Format of `ExecutionRequests` received over the engine api. @@ -606,6 +607,28 @@ impl TryFrom for ExecutionRequests { } } +impl TryFrom for ExecutionRequestsElectra { + type Error = RequestsError; + + fn try_from(value: JsonExecutionRequests) -> Result { + match ExecutionRequests::::try_from(value)? { + ExecutionRequests::Electra(requests) => Ok(requests), + ExecutionRequests::Gloas(_) => Err(RequestsError::VariantMismatch), + } + } +} + +impl TryFrom for ExecutionRequestsGloas { + type Error = RequestsError; + + fn try_from(value: JsonExecutionRequests) -> Result { + match ExecutionRequests::::try_from(value)? { + ExecutionRequests::Gloas(requests) => Ok(requests), + ExecutionRequests::Electra(_) => Err(RequestsError::VariantMismatch), + } + } +} + #[superstruct( variants(Bellatrix, Capella, Deneb, Electra, Fulu, Gloas), variant_attributes( diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index a392d21e2e..b255e1b75d 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -43,7 +43,6 @@ use tokio::{ use tokio_stream::wrappers::WatchStream; use tracing::{Instrument, debug, debug_span, error, info, instrument, warn}; use tree_hash::TreeHash; -use types::ExecutionPayloadGloas; use types::builder::BuilderBid; use types::execution::BlockProductionVersion; use types::kzg_ext::KzgCommitments; @@ -56,6 +55,7 @@ use types::{ ExecutionPayloadCapella, ExecutionPayloadElectra, ExecutionPayloadFulu, FullPayload, ProposerPreparationData, Slot, }; +use types::{ExecutionPayloadGloas, ExecutionRequestsGloas}; mod block_hash; mod engine_api; @@ -206,7 +206,7 @@ pub struct BlockProposalContentsGloas { pub payload_value: Uint256, pub blob_kzg_commitments: KzgCommitments, pub blobs_and_proofs: (BlobsList, KzgProofs), - pub execution_requests: ExecutionRequests, + pub execution_requests: ExecutionRequestsGloas, pub should_override_builder: bool, } diff --git a/beacon_node/network/src/sync/block_sidecar_coupling.rs b/beacon_node/network/src/sync/block_sidecar_coupling.rs index b64ae4a4c5..93c0699ded 100644 --- a/beacon_node/network/src/sync/block_sidecar_coupling.rs +++ b/beacon_node/network/src/sync/block_sidecar_coupling.rs @@ -594,15 +594,113 @@ mod tests { } } - /// The custody-column coupling tests below build Fulu data-column sidecars directly, which is - /// incompatible with a Gloas genesis (Gloas columns have a different structure). Skip them when - /// `FORK_NAME` schedules Gloas at genesis. TODO(gloas): port the harness to build Gloas columns. - fn skip_under_gloas() -> bool { + /// Returns true when `FORK_NAME` schedules Gloas at genesis. Used to make the custody-column + /// coupling tests fork-aware: under Gloas the columns are coupled into the payload envelope, so + /// these tests build Gloas blocks/columns/envelopes and complete the payloads request. + fn is_gloas_env() -> bool { test_spec::() .fork_name_at_epoch(Epoch::new(0)) .gloas_enabled() } + /// The fork to build blocks/columns for in the custody-column coupling tests. Under a Gloas + /// genesis we must build Gloas columns (and matching envelopes); otherwise we use Fulu. + fn custody_test_fork() -> ForkName { + if is_gloas_env() { + ForkName::Gloas + } else { + ForkName::Fulu + } + } + + /// A spec with custody-column (PeerDAS) coupling enabled at genesis, matching the env fork. + /// Under a Gloas env this enables Gloas at genesis (so envelopes are coupled); otherwise it + /// enables Fulu at genesis. + fn custody_test_spec() -> ChainSpec { + let mut spec = test_spec::(); + spec.deneb_fork_epoch = Some(Epoch::new(0)); + spec.fulu_fork_epoch = Some(Epoch::new(0)); + if is_gloas_env() { + spec.gloas_fork_epoch = Some(Epoch::new(0)); + } + spec + } + + /// A block, its data columns, and (under Gloas) its matching payload envelope. + type BlockColumnsEnvelope = ( + Arc>, + DataColumnSidecarList, + Option>>, + ); + + /// Builds `count` blocks with their data columns, plus a matching payload envelope under Gloas. + /// Under Fulu the envelope is `None`. + fn make_blocks_and_columns( + count: usize, + num_blobs: NumBlobs, + spec: &ChainSpec, + ) -> Vec { + let fork = custody_test_fork(); + let mut u = types::test_utils::test_unstructured(); + (0..count) + .map(|_| { + // `NumBlobs` isn't `Clone`, so rebuild a fresh value for each block. + let num_blobs = match &num_blobs { + NumBlobs::Random => NumBlobs::Random, + NumBlobs::Number(n) => NumBlobs::Number(*n), + NumBlobs::None => NumBlobs::None, + }; + let (block, data_columns) = + generate_rand_block_and_data_columns::(fork, num_blobs, &mut u, spec) + .unwrap(); + let block = Arc::new(block); + let envelope = is_gloas_env().then(|| matching_envelope(&block)); + (block, data_columns, envelope) + }) + .collect() + } + + /// Under Gloas, completes the payloads request with the envelopes from `blocks`. Under Fulu this + /// is a no-op (there is no payloads request). Pass the subset of blocks whose envelopes should + /// be supplied. + fn add_envelopes_if_gloas( + info: &mut RangeBlockComponentsRequest, + payloads_req_id: Option, + blocks: &[BlockColumnsEnvelope], + ) { + if let Some(payloads_req_id) = payloads_req_id { + info.add_payload_envelopes( + payloads_req_id, + blocks + .iter() + .filter_map(|(_, _, envelope)| envelope.clone()) + .collect(), + ) + .unwrap(); + } + } + + /// Asserts the coupled `responses` carry the expected data. Pre-Gloas only the count is checked; + /// under Gloas each block must additionally wrap an envelope holding `expected_columns` columns. + fn assert_custody_columns_coupled( + responses: &[RangeSyncBlock], + expected_blocks: usize, + expected_columns: usize, + ) { + assert_eq!(responses.len(), expected_blocks); + if is_gloas_env() { + for response in responses { + match response { + RangeSyncBlock::Gloas { + envelope: Some(envelope), + .. + } => assert_eq!(envelope.columns.len(), expected_columns), + other => panic!("expected Gloas block with envelope, got {other:?}"), + } + } + } + } + fn blocks_id(parent_request_id: ComponentsByRangeRequestId) -> BlocksByRangeRequestId { BlocksByRangeRequestId { id: 1, @@ -798,38 +896,33 @@ mod tests { #[test] fn no_blobs_into_responses() { - // This exercises the pre-Gloas blobs/no-data coupling path. Gloas coupling is covered - // by the dedicated `setup_gloas_coupling` tests below. - if skip_under_gloas() { - return; - } - let spec = Arc::new(test_spec::()); - - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..4) - .map(|_| { - generate_rand_block_and_blobs::( - spec.fork_name_at_epoch(Epoch::new(0)), - NumBlobs::None, - &mut u, - ) - .unwrap() - .0 - .into() - }) - .collect::>>>(); - - let blocks_req_id = blocks_id(components_id()); - let mut info = - RangeBlockComponentsRequest::::new(blocks_req_id, None, None, None, Span::none()); - - // Send blocks and complete terminate response - info.add_blocks(blocks_req_id, blocks).unwrap(); - + // Coupling of blocks that carry no data. Pre-Gloas there is simply no data request; under + // Gloas each block still couples to its (empty-column) payload envelope, so the envelope + // request is driven too. + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); + let blocks = make_blocks_and_columns(4, NumBlobs::None, &spec); - // Assert response is finished and RpcBlocks can be constructed - info.responses(da_checker, spec).unwrap().unwrap(); + let components_id = components_id(); + let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); + let mut info = RangeBlockComponentsRequest::::new( + blocks_req_id, + None, + is_gloas_env().then(|| (vec![], vec![])), + payloads_req_id, + Span::none(), + ); + + info.add_blocks( + blocks_req_id, + blocks.iter().map(|(block, _, _)| block.clone()).collect(), + ) + .unwrap(); + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); + + let responses = info.responses(da_checker, spec).unwrap().unwrap(); + assert_custody_columns_coupled(&responses, blocks.len(), 0); } #[test] @@ -875,33 +968,17 @@ mod tests { #[test] fn rpc_block_with_custody_columns() { - if skip_under_gloas() { - return; - } - let mut spec = test_spec::(); - spec.deneb_fork_epoch = Some(Epoch::new(0)); - spec.fulu_fork_epoch = Some(Epoch::new(0)); - let spec = Arc::new(spec); + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); let expects_custody_columns = da_checker .custody_context() .sampling_columns_for_epoch(Epoch::new(0), &spec) .to_vec(); - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..4) - .map(|_| { - generate_rand_block_and_data_columns::( - ForkName::Fulu, - NumBlobs::Number(1), - &mut u, - &spec, - ) - .unwrap() - }) - .collect::>(); + let blocks = make_blocks_and_columns(4, NumBlobs::Number(1), &spec); let components_id = components_id(); let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); let columns_req_id = expects_custody_columns .iter() .enumerate() @@ -919,13 +996,13 @@ mod tests { blocks_req_id, None, Some((columns_req_id.clone(), expects_custody_columns.clone())), - None, + payloads_req_id, Span::none(), ); // Send blocks and complete terminate response info.add_blocks( blocks_req_id, - blocks.iter().map(|b| b.0.clone().into()).collect(), + blocks.iter().map(|(block, _, _)| block.clone()).collect(), ) .unwrap(); // Assert response is not finished @@ -938,7 +1015,12 @@ mod tests { *req, blocks .iter() - .flat_map(|b| b.1.iter().filter(|d| *d.index() == column_index).cloned()) + .flat_map(|(_, columns, _)| { + columns + .iter() + .filter(|d| *d.index() == column_index) + .cloned() + }) .collect(), ) .unwrap(); @@ -951,19 +1033,18 @@ mod tests { } } + // Under Gloas the columns are coupled into the payload envelope; supply the envelopes so + // the request can complete. + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); + // All completed construct response - info.responses(da_checker, spec).unwrap().unwrap(); + let responses = info.responses(da_checker, spec).unwrap().unwrap(); + assert_custody_columns_coupled(&responses, blocks.len(), expects_custody_columns.len()); } #[test] fn rpc_block_with_custody_columns_batched() { - if skip_under_gloas() { - return; - } - let mut spec = test_spec::(); - spec.deneb_fork_epoch = Some(Epoch::new(0)); - spec.fulu_fork_epoch = Some(Epoch::new(0)); - let spec = Arc::new(spec); + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); let expected_sampling_columns = da_checker .custody_context() @@ -981,6 +1062,7 @@ mod tests { let components_id = components_id(); let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); let columns_req_id = batched_column_requests .iter() .enumerate() @@ -999,27 +1081,16 @@ mod tests { blocks_req_id, None, Some((columns_req_id.clone(), expected_sampling_columns.clone())), - None, + payloads_req_id, Span::none(), ); - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..4) - .map(|_| { - generate_rand_block_and_data_columns::( - ForkName::Fulu, - NumBlobs::Number(1), - &mut u, - &spec, - ) - .unwrap() - }) - .collect::>(); + let blocks = make_blocks_and_columns(4, NumBlobs::Number(1), &spec); // Send blocks and complete terminate response info.add_blocks( blocks_req_id, - blocks.iter().map(|b| b.0.clone().into()).collect(), + blocks.iter().map(|(block, _, _)| block.clone()).collect(), ) .unwrap(); // Assert response is not finished @@ -1032,8 +1103,9 @@ mod tests { *req, blocks .iter() - .flat_map(|b| { - b.1.iter() + .flat_map(|(_, columns, _)| { + columns + .iter() .filter(|d| column_indices.contains(d.index())) .cloned() }) @@ -1049,8 +1121,13 @@ mod tests { } } + // Under Gloas the columns are coupled into the payload envelope; supply the envelopes so + // the request can complete. + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); + // All completed construct response - info.responses(da_checker, spec).unwrap().unwrap(); + let responses = info.responses(da_checker, spec).unwrap().unwrap(); + assert_custody_columns_coupled(&responses, blocks.len(), expected_sampling_columns.len()); } #[test] @@ -1164,31 +1241,18 @@ mod tests { #[test] fn missing_custody_columns_from_faulty_peers() { - if skip_under_gloas() { - return; - } // GIVEN: A request expecting sampling columns from multiple peers - let spec = Arc::new(test_spec::()); + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); let expected_sampling_columns = da_checker .custody_context() .sampling_columns_for_epoch(Epoch::new(0), &spec) .to_vec(); - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..2) - .map(|_| { - generate_rand_block_and_data_columns::( - ForkName::Fulu, - NumBlobs::Number(1), - &mut u, - &spec, - ) - .unwrap() - }) - .collect::>(); + let blocks = make_blocks_and_columns(2, NumBlobs::Number(1), &spec); let components_id = components_id(); let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); let columns_req_id = expected_sampling_columns .iter() .enumerate() @@ -1206,16 +1270,19 @@ mod tests { blocks_req_id, None, Some((columns_req_id.clone(), expected_sampling_columns.clone())), - None, + payloads_req_id, Span::none(), ); // AND: All blocks are received successfully info.add_blocks( blocks_req_id, - blocks.iter().map(|b| b.0.clone().into()).collect(), + blocks.iter().map(|(block, _, _)| block.clone()).collect(), ) .unwrap(); + // Under Gloas the payloads request must be completed for `responses` to proceed; the + // faulty-peer detection happens before the envelope wrap and is fork-independent. + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); // AND: Only the first 2 sampling columns are received successfully for (i, &column_index) in expected_sampling_columns.iter().take(2).enumerate() { @@ -1224,7 +1291,12 @@ mod tests { *req, blocks .iter() - .flat_map(|b| b.1.iter().filter(|d| *d.index() == column_index).cloned()) + .flat_map(|(_, columns, _)| { + columns + .iter() + .filter(|d| *d.index() == column_index) + .cloned() + }) .collect(), ) .unwrap(); @@ -1263,34 +1335,18 @@ mod tests { #[test] fn retry_logic_after_peer_failures() { - if skip_under_gloas() { - return; - } // GIVEN: A request expecting sampling columns where some peers initially fail - let mut spec = test_spec::(); - spec.deneb_fork_epoch = Some(Epoch::new(0)); - spec.fulu_fork_epoch = Some(Epoch::new(0)); - let spec = Arc::new(spec); + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); let expected_sampling_columns = da_checker .custody_context() .sampling_columns_for_epoch(Epoch::new(0), &spec) .to_vec(); - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..2) - .map(|_| { - generate_rand_block_and_data_columns::( - ForkName::Fulu, - NumBlobs::Number(1), - &mut u, - &spec, - ) - .unwrap() - }) - .collect::>(); + let blocks = make_blocks_and_columns(2, NumBlobs::Number(1), &spec); let components_id = components_id(); let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); let columns_req_id = expected_sampling_columns .iter() .enumerate() @@ -1308,16 +1364,18 @@ mod tests { blocks_req_id, None, Some((columns_req_id.clone(), expected_sampling_columns.clone())), - None, + payloads_req_id, Span::none(), ); // AND: All blocks are received info.add_blocks( blocks_req_id, - blocks.iter().map(|b| b.0.clone().into()).collect(), + blocks.iter().map(|(block, _, _)| block.clone()).collect(), ) .unwrap(); + // Under Gloas the payloads request must be completed for `responses` to proceed. + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); // AND: Only partial sampling columns are received (first column but not others) let (req0, _) = columns_req_id.first().unwrap(); @@ -1325,8 +1383,9 @@ mod tests { *req0, blocks .iter() - .flat_map(|b| { - b.1.iter() + .flat_map(|(_, columns, _)| { + columns + .iter() .filter(|d| *d.index() == expected_sampling_columns[0]) .cloned() }) @@ -1363,8 +1422,9 @@ mod tests { new_columns_req_id, blocks .iter() - .flat_map(|b| { - b.1.iter() + .flat_map(|(_, columns, _)| { + columns + .iter() .filter(|d| failed_column_indices.contains(d.index())) .cloned() }) @@ -1383,34 +1443,18 @@ mod tests { #[test] fn max_retries_exceeded_behavior() { - if skip_under_gloas() { - return; - } // GIVEN: A request where peers consistently fail to provide required columns - let mut spec = test_spec::(); - spec.deneb_fork_epoch = Some(Epoch::new(0)); - spec.fulu_fork_epoch = Some(Epoch::new(0)); - let spec = Arc::new(spec); + let spec = Arc::new(custody_test_spec()); let da_checker = Arc::new(test_da_checker(spec.clone(), NodeCustodyType::Fullnode)); let expected_sampling_columns = da_checker .custody_context() .sampling_columns_for_epoch(Epoch::new(0), &spec) .to_vec(); - let mut u = types::test_utils::test_unstructured(); - let blocks = (0..1) - .map(|_| { - generate_rand_block_and_data_columns::( - ForkName::Fulu, - NumBlobs::Number(1), - &mut u, - &spec, - ) - .unwrap() - }) - .collect::>(); + let blocks = make_blocks_and_columns(1, NumBlobs::Number(1), &spec); let components_id = components_id(); let blocks_req_id = blocks_id(components_id); + let payloads_req_id = is_gloas_env().then(|| payloads_id(components_id)); let columns_req_id = expected_sampling_columns .iter() .enumerate() @@ -1428,16 +1472,18 @@ mod tests { blocks_req_id, None, Some((columns_req_id.clone(), expected_sampling_columns.clone())), - None, + payloads_req_id, Span::none(), ); // AND: All blocks are received info.add_blocks( blocks_req_id, - blocks.iter().map(|b| b.0.clone().into()).collect(), + blocks.iter().map(|(block, _, _)| block.clone()).collect(), ) .unwrap(); + // Under Gloas the payloads request must be completed for `responses` to proceed. + add_envelopes_if_gloas(&mut info, payloads_req_id, &blocks); // AND: Only the first sampling column is provided successfully let (req0, _) = columns_req_id.first().unwrap(); @@ -1445,8 +1491,9 @@ mod tests { *req0, blocks .iter() - .flat_map(|b| { - b.1.iter() + .flat_map(|(_, columns, _)| { + columns + .iter() .filter(|d| *d.index() == expected_sampling_columns[0]) .cloned() }) diff --git a/beacon_node/network/src/sync/tests/lookups.rs b/beacon_node/network/src/sync/tests/lookups.rs index 621824c7d2..deaf421e39 100644 --- a/beacon_node/network/src/sync/tests/lookups.rs +++ b/beacon_node/network/src/sync/tests/lookups.rs @@ -45,6 +45,17 @@ use types::{ const D: Duration = Duration::new(0, 0); +/// Extract the Gloas payload envelope (if any) carried by a stored `RangeSyncBlock`. +fn envelope_of(block: &RangeSyncBlock) -> Option>> { + match block { + RangeSyncBlock::Gloas { + envelope: Some(envelope), + .. + } => Some(envelope.envelope().clone()), + _ => None, + } +} + /// Gloas genesis needs enough validators to populate `proposer_lookahead`. const TEST_RIG_VALIDATOR_COUNT: usize = 8; @@ -331,7 +342,6 @@ impl TestRig { fork_name, network_blocks_by_root: <_>::default(), network_blocks_by_slot: <_>::default(), - network_envelopes_by_root: <_>::default(), penalties: <_>::default(), seen_lookups: <_>::default(), requests: <_>::default(), @@ -669,7 +679,10 @@ impl TestRig { if self.complete_strategy.hold_envelope_for_block == Some(block_root) { return; } - let envelope = self.network_envelopes_by_root.get(&block_root).cloned(); + let envelope = self + .network_blocks_by_root + .get(&block_root) + .and_then(envelope_of); self.send_rpc_envelope_response(req_id, peer_id, envelope); } @@ -843,7 +856,7 @@ impl TestRig { if self.complete_strategy.hold_envelope_for_block == Some(block_root) { return None; } - self.network_envelopes_by_root.get(&block_root).cloned() + envelope_of(block) }) .collect::>(); self.send_rpc_envelopes_response(req_id, peer_id, &envelopes); @@ -1057,13 +1070,7 @@ impl TestRig { .await; let block = external_harness.get_full_block(&block_root); let block_slot = block.slot(); - self.insert_external_block( - block, - external_harness - .chain - .get_payload_envelope(&block_root) - .unwrap(), - ); + self.insert_external_block(block); blocks.push((block_slot, block_root)); } @@ -1171,8 +1178,7 @@ impl TestRig { // Cache every block through the single `get_full_block` + `insert_external_block2` path. for root in [g_root, a_root, c_root, b_root] { let block = external_harness.get_full_block(&root); - let envelope = external_harness.chain.get_payload_envelope(&root).unwrap(); - self.insert_external_block(block, envelope); + self.insert_external_block(block); } self.harness.set_current_slot(child_slot); @@ -1200,21 +1206,12 @@ impl TestRig { Some((r, fork)) } - fn insert_external_block( - &mut self, - block: RangeSyncBlock, - envelope: Option>, - ) { + fn insert_external_block(&mut self, block: RangeSyncBlock) { let block_root = block.canonical_root(); let block_slot = block.slot(); self.network_blocks_by_root .insert(block_root, block.clone()); self.network_blocks_by_slot.insert(block_slot, block); - // Cache Gloas envelopes for lookup RPCs. - if let Some(envelope) = envelope { - self.network_envelopes_by_root - .insert(block_root, envelope.into()); - } self.log(&format!( "Produced block {block_root:?} slot {block_slot} in external harness", )); @@ -1300,9 +1297,9 @@ impl TestRig { let range_sync_block = if block.fork_name_unchecked().gloas_enabled() { // Gloas carries data columns in the payload envelope, not in `block_data`. let envelope = self - .network_envelopes_by_root + .network_blocks_by_root .get(&block_root) - .cloned() + .and_then(envelope_of) .map(|envelope| AvailableEnvelope::new(envelope, columns.unwrap_or_default())); RangeSyncBlock::new_gloas(block, envelope).unwrap() } else { @@ -1370,6 +1367,8 @@ impl TestRig { .unwrap_or_else(|| panic!("No block at slot {slot}")) .clone(); let block_root = rpc_block.canonical_root(); + let block_state_root = rpc_block.as_block().state_root(); + let envelope = envelope_of(&rpc_block); self.harness .chain .process_block( @@ -1381,6 +1380,18 @@ impl TestRig { ) .await .unwrap(); + // Gloas: import the payload envelope so the block counts as full for its children. + if let Some(envelope) = envelope { + let state = self + .harness + .chain + .get_state(&block_state_root, Some(Slot::new(slot)), false) + .expect("should load state") + .expect("state should exist"); + self.harness + .process_envelope(block_root, (*envelope).clone(), &state, block_state_root) + .await; + } } self.harness.chain.recompute_head_at_current_slot().await; } @@ -1495,6 +1506,17 @@ impl TestRig { panic!("Some downscore events: {:?}", self.penalties); } } + + fn assert_no_block_requests(&self) { + assert_eq!( + self.requests + .iter() + .filter(|(request, _)| matches!(request, RequestType::BlocksByRoot(_))) + .collect::>(), + Vec::<&(RequestType, AppRequestId)>::new(), + "There should be no block requests" + ); + } fn assert_failed_lookup_sync(&mut self) { assert!(self.created_lookups() > 0, "no created lookups"); assert_eq!(self.completed_lookups(), 0, "some completed lookups"); @@ -1623,6 +1645,10 @@ impl TestRig { genesis_fork().fulu_enabled().then(Self::default) } + fn new_after_gloas() -> Option { + genesis_fork().gloas_enabled().then(Self::default) + } + pub fn new_fulu_peer_test(fulu_test_type: FuluTestType) -> Option { genesis_fork().fulu_enabled().then(|| { Self::new(TestRigConfig { @@ -2129,7 +2155,8 @@ async fn happy_path_unknown_data_parent(depth: usize) { let Some(mut r) = TestRig::new_after_fulu() else { return; }; - // No unknown-parent data-column trigger post-Gloas. + // Fulu-only: the `UnknownDataColumnParent` trigger doesn't exist post-Gloas (columns ride in + // the payload envelope, not as standalone data columns). if r.is_after_gloas() { return; } @@ -2359,10 +2386,6 @@ async fn test_single_block_lookup_ignored_response() { /// Assert that if the beacon processor returns DuplicateFullyImported, the lookup completes successfully async fn test_single_block_lookup_duplicate_response() { let mut r = TestRig::default(); - // The mock only covers block processing; Gloas also needs real envelope/column results. - if r.is_after_gloas() { - return; - } r.build_chain_and_trigger_last_block(1).await; // Send a DuplicateFullyImported response, the lookup should complete successfully r.simulate( @@ -2427,10 +2450,6 @@ async fn lookups_form_chain() { /// Assert that if a lookup chain (by appending ancestors) is too long we drop it async fn test_parent_lookup_too_deep_grow_ancestor_one() { let mut r = TestRig::default(); - // TODO(gloas): range sync does not fetch payload envelopes yet. - if r.is_after_gloas() { - return; - } r.build_chain(PARENT_DEPTH_TOLERANCE + 1).await; r.trigger_with_last_block(); r.simulate(SimulateConfig::happy_path()).await; @@ -2575,13 +2594,13 @@ async fn test_same_chain_race_condition() { } #[tokio::test] -/// Assert that if the lookup's block is in the da_checker we don't download it again -async fn block_in_da_checker_skips_download() { - // Only post-Fulu, as the block needs custody columns to remain in the da_checker +/// Assert that if the lookup's block is in the da_checker we don't download it again (pre-Gloas). +async fn block_in_da_checker_skips_download_fulu() { + // Only post-Fulu, as the block needs custody columns to remain in the da_checker. let Some(mut r) = TestRig::new_after_fulu() else { return; }; - // TODO(gloas): the helper does not populate the envelope missing-component path yet. + // Pre-Gloas only; the Gloas equivalent is `block_in_da_checker_skips_download_gloas`. if r.is_after_gloas() { return; } @@ -2594,14 +2613,28 @@ async fn block_in_da_checker_skips_download() { r.trigger_with_block_at_slot(1); r.simulate(SimulateConfig::happy_path()).await; r.assert_successful_lookup_sync(); - assert_eq!( - r.requests - .iter() - .filter(|(request, _)| matches!(request, RequestType::BlocksByRoot(_))) - .collect::>(), - Vec::<&(RequestType, AppRequestId)>::new(), - "There should be no block requests" - ); + r.assert_no_block_requests(); +} + +#[tokio::test] +/// Assert that if the lookup's block is in the da_checker we don't download it again (Gloas). +async fn block_in_da_checker_skips_download_gloas() { + let Some(mut r) = TestRig::new_after_gloas() else { + return; + }; + // A Gloas block carries no inline DA, so a lone block never sits in the da_checker awaiting + // components: only a FULL *child* proves the block published a payload and supplies the peers + // that serve its columns/envelope. Build a parent + FULL child, insert the PARENT into the + // da_checker, then trigger via the child (which is provided by the trigger, not downloaded). + // The parent lookup must then skip the parent's block download. + r.build_chain(2).await; + let parent = r.block_at_slot(1); + let child = r.block_at_slot(2); + r.import_block_to_da_checker(parent).await; + r.trigger_unknown_parent_blocks_from_all_peers(&[child]); + r.simulate(SimulateConfig::happy_path()).await; + r.assert_successful_lookup_sync(); + r.assert_no_block_requests(); } macro_rules! fulu_peer_matrix_tests { diff --git a/beacon_node/network/src/sync/tests/mod.rs b/beacon_node/network/src/sync/tests/mod.rs index 2f318bfb9a..4e185cc081 100644 --- a/beacon_node/network/src/sync/tests/mod.rs +++ b/beacon_node/network/src/sync/tests/mod.rs @@ -21,7 +21,7 @@ use tokio::sync::mpsc; use tracing_subscriber::fmt::MakeWriter; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -use types::{ForkName, Hash256, MinimalEthSpec as E, SignedExecutionPayloadEnvelope, Slot}; +use types::{ForkName, Hash256, MinimalEthSpec as E, Slot}; mod lookups; mod range; @@ -77,10 +77,6 @@ struct TestRig { /// Blocks that will be used in the test but may not be known to `harness` yet. network_blocks_by_root: HashMap>, network_blocks_by_slot: HashMap>, - /// Gloas execution payload envelopes keyed by block root, populated during `build_chain` - /// from the external harness store. The rig serves these when a lookup issues a - /// `PayloadEnvelopesByRoot` request. - network_envelopes_by_root: HashMap>>, penalties: Vec, /// All seen lookups through the test run seen_lookups: HashMap, diff --git a/beacon_node/network/src/sync/tests/range.rs b/beacon_node/network/src/sync/tests/range.rs index e6890cf242..1499ae5016 100644 --- a/beacon_node/network/src/sync/tests/range.rs +++ b/beacon_node/network/src/sync/tests/range.rs @@ -34,13 +34,6 @@ use types::{Epoch, EthSpec, Hash256, MinimalEthSpec as E, Slot}; const SLOTS_PER_EPOCH: usize = 8; impl TestRig { - /// Range sync doesn't yet ingest Gloas blocks in these tests: the range harness doesn't serve - /// payload envelopes, so a Gloas block never becomes fully available and sync can't complete. - /// Skip the affected completion tests under a Gloas genesis. TODO(gloas): support range sync. - fn skip_range_sync_under_gloas(&self) -> bool { - self.fork_name.gloas_enabled() - } - fn add_head_peer(&mut self) -> PeerId { let local_info = self.local_info(); self.add_supernode_peer(SyncInfo { @@ -267,9 +260,6 @@ impl TestRig { #[tokio::test] async fn head_sync_completes() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_head_sync().await; r.simulate(SimulateConfig::happy_path()).await; r.assert_head_sync_completed(); @@ -281,9 +271,6 @@ async fn head_sync_completes() { #[tokio::test] async fn finalized_to_head_transition() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_and_head_sync().await; r.simulate(SimulateConfig::happy_path()).await; r.assert_range_sync_completed(); @@ -295,9 +282,6 @@ async fn finalized_to_head_transition() { #[tokio::test] async fn finalized_sync_completes() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync().await; r.simulate(SimulateConfig::happy_path()).await; r.assert_range_sync_completed(); @@ -309,9 +293,6 @@ async fn finalized_sync_completes() { #[tokio::test] async fn batch_rpc_error_retries() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync().await; r.simulate(SimulateConfig::happy_path().return_rpc_error(RPCError::UnsupportedProtocol)) .await; @@ -380,9 +361,6 @@ async fn batch_peer_returns_partial_columns_then_succeeds() { #[tokio::test] async fn batch_non_faulty_failure_retries() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync().await; r.simulate(SimulateConfig::happy_path().with_range_non_faulty_failures(1)) .await; @@ -394,9 +372,6 @@ async fn batch_non_faulty_failure_retries() { #[tokio::test] async fn batch_faulty_failure_redownloads() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync().await; r.simulate(SimulateConfig::happy_path().with_range_faulty_failures(1)) .await; @@ -453,9 +428,6 @@ async fn late_response_for_removed_chain() { #[tokio::test] async fn ee_offline_then_online_resumes_sync() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync().await; r.simulate(SimulateConfig::happy_path().with_ee_offline_for_n_range_responses(2)) .await; @@ -468,9 +440,6 @@ async fn ee_offline_then_online_resumes_sync() { #[tokio::test] async fn finalized_sync_with_local_head_partial() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } r.setup_finalized_sync_with_local_head(3).await; r.simulate(SimulateConfig::happy_path()).await; r.assert_range_sync_completed(); @@ -481,9 +450,6 @@ async fn finalized_sync_with_local_head_partial() { #[tokio::test] async fn finalized_sync_with_local_head_near_target() { let mut r = TestRig::default(); - if r.skip_range_sync_under_gloas() { - return; - } let target_epochs = 5; let local_slots = (target_epochs * SLOTS_PER_EPOCH) - 1; // all blocks except last r.build_chain(target_epochs * SLOTS_PER_EPOCH).await; @@ -502,7 +468,7 @@ async fn finalized_sync_with_local_head_near_target() { #[tokio::test] async fn not_enough_custody_peers_then_peers_arrive() { let mut r = TestRig::default(); - if !r.fork_name.fulu_enabled() || r.skip_range_sync_under_gloas() { + if !r.fork_name.fulu_enabled() { return; } let remote_info = r.setup_finalized_sync_insufficient_peers().await; @@ -529,7 +495,7 @@ async fn not_enough_custody_peers_then_peers_arrive() { #[tokio::test] async fn finalized_sync_not_enough_custody_peers_resume_after_peer_cgc_update() { let mut r = TestRig::default(); - if !r.fork_name.fulu_enabled() || r.skip_range_sync_under_gloas() { + if !r.fork_name.fulu_enabled() { return; } diff --git a/testing/execution_engine_integration/src/geth.rs b/testing/execution_engine_integration/src/geth.rs index 4b62e68e94..a676cb1a4c 100644 --- a/testing/execution_engine_integration/src/geth.rs +++ b/testing/execution_engine_integration/src/geth.rs @@ -108,7 +108,6 @@ impl GenericExecutionEngine for GethEngine { .arg(http_auth_port.to_string()) .arg("--port") .arg(network_port.to_string()) - .arg("--allow-insecure-unlock") .arg("--authrpc.jwtsecret") .arg(jwt_secret_path.as_path().to_str().unwrap()) // This flag is required to help Geth perform reliably when feeding it blocks