diff --git a/beacon_node/beacon_chain/src/block_production/gloas.rs b/beacon_node/beacon_chain/src/block_production/gloas.rs index fedcdda671..306e1c549e 100644 --- a/beacon_node/beacon_chain/src/block_production/gloas.rs +++ b/beacon_node/beacon_chain/src/block_production/gloas.rs @@ -7,6 +7,7 @@ use execution_layer::{BlockProposalContentsType, BuilderParams}; use operation_pool::CompactAttestationRef; use ssz::Encode; use state_processing::common::get_attesting_indices_from_state; +use state_processing::envelope_processing::{VerifyStateRoot, process_execution_payload_envelope}; use state_processing::epoch_cache::initialize_epoch_cache; use state_processing::per_block_processing::verify_attestation_for_block_inclusion; use state_processing::{ @@ -24,7 +25,8 @@ use types::{ BuilderIndex, Deposit, Eth1Data, EthSpec, ExecutionPayloadBid, ExecutionPayloadEnvelope, ExecutionPayloadGloas, ExecutionRequests, FullPayload, Graffiti, Hash256, PayloadAttestation, ProposerSlashing, RelativeEpoch, SignedBeaconBlock, SignedBlsToExecutionChange, - SignedExecutionPayloadBid, SignedVoluntaryExit, Slot, SyncAggregate, + SignedExecutionPayloadBid, SignedExecutionPayloadEnvelope, SignedVoluntaryExit, Slot, + SyncAggregate, }; use crate::execution_payload::get_execution_payload; @@ -60,7 +62,6 @@ pub struct ExecutionPayloadData { pub execution_requests: ExecutionRequests, pub builder_index: BuilderIndex, pub slot: Slot, - pub state_root: Hash256, } impl BeaconChain { @@ -580,14 +581,32 @@ impl BeaconChain { builder_index: payload_data.builder_index, beacon_block_root, slot: payload_data.slot, - state_root: payload_data.state_root, + state_root: Hash256::ZERO, }; + let mut signed_envelope = SignedExecutionPayloadEnvelope { + message: execution_payload_envelope, + signature: Signature::empty(), + }; + + // TODO(gloas) add better error variant + process_execution_payload_envelope( + &mut state, + None, + &signed_envelope, + VerifySignatures::False, + VerifyStateRoot::False, + &self.spec, + ) + .map_err(|_| BlockProductionError::GloasNotImplemented)?; + + signed_envelope.message.state_root = state.update_tree_hash_cache()?; + // Cache the envelope for later retrieval by the validator for signing and publishing. let envelope_slot = payload_data.slot; self.pending_payload_envelopes .write() - .insert(envelope_slot, execution_payload_envelope); + .insert(envelope_slot, signed_envelope.message); debug!( %beacon_block_root, @@ -710,7 +729,6 @@ impl BeaconChain { } }; - // TODO(gloas) this is just a dummy error variant for now let execution_payload_gloas = execution_payload .as_gloas() @@ -741,7 +759,6 @@ impl BeaconChain { execution_requests, builder_index, slot: produce_at_slot, - state_root, }; // TODO(gloas) this is only local building diff --git a/consensus/state_processing/src/envelope_processing.rs b/consensus/state_processing/src/envelope_processing.rs index d46728dbbc..2076f0f836 100644 --- a/consensus/state_processing/src/envelope_processing.rs +++ b/consensus/state_processing/src/envelope_processing.rs @@ -20,6 +20,23 @@ macro_rules! envelope_verify { }; } +/// The strategy to be used when validating the payloads state root. +#[cfg_attr(feature = "arbitrary-fuzz", derive(Arbitrary))] +#[derive(PartialEq, Clone, Copy)] +pub enum VerifyStateRoot { + /// Validate state root. + True, + /// Do not validate state root. Use with caution. + /// This should only be used when first constructing the payload envelope. + False, +} + +impl VerifyStateRoot { + pub fn is_true(self) -> bool { + self == VerifyStateRoot::True + } +} + #[derive(Debug, Clone)] pub enum EnvelopeProcessingError { /// Bad Signature @@ -111,6 +128,7 @@ pub fn process_execution_payload_envelope( parent_state_root: Option, signed_envelope: &SignedExecutionPayloadEnvelope, verify_signatures: VerifySignatures, + verify_state_root: VerifyStateRoot, spec: &ChainSpec, ) -> Result<(), EnvelopeProcessingError> { if verify_signatures.is_true() { @@ -264,15 +282,17 @@ pub fn process_execution_payload_envelope( .map_err(EnvelopeProcessingError::BitFieldError)?; *state.latest_block_hash_mut()? = payload.block_hash; - // Verify the state root - let state_root = state.canonical_root()?; - envelope_verify!( - envelope.state_root == state_root, - EnvelopeProcessingError::InvalidStateRoot { - state: state_root, - envelope: envelope.state_root, - } - ); + if verify_state_root.is_true() { + // Verify the state root + let state_root = state.canonical_root()?; + envelope_verify!( + envelope.state_root == state_root, + EnvelopeProcessingError::InvalidStateRoot { + state: state_root, + envelope: envelope.state_root, + } + ); + } Ok(()) } diff --git a/testing/ef_tests/src/cases/operations.rs b/testing/ef_tests/src/cases/operations.rs index ef998a94ba..8605800b79 100644 --- a/testing/ef_tests/src/cases/operations.rs +++ b/testing/ef_tests/src/cases/operations.rs @@ -5,6 +5,7 @@ use crate::decode::{ssz_decode_file, ssz_decode_file_with, ssz_decode_state, yam use serde::Deserialize; use ssz::Decode; use state_processing::common::update_progressive_balances_cache::initialize_progressive_balances_cache; +use state_processing::envelope_processing::VerifyStateRoot; use state_processing::epoch_cache::initialize_epoch_cache; use state_processing::per_block_processing::process_operations::{ process_consolidation_requests, process_deposit_requests_post_gloas, @@ -452,7 +453,14 @@ impl Operation for SignedExecutionPayloadEnvelope { .as_ref() .is_some_and(|e| e.execution_valid); if valid { - process_execution_payload_envelope(state, None, self, VerifySignatures::True, spec) + process_execution_payload_envelope( + state, + None, + self, + VerifySignatures::True, + VerifyStateRoot::True, + spec, + ) } else { Err(EnvelopeProcessingError::ExecutionInvalid) }