diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7c4c4c15501..fb0d2bb4b66 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -21,8 +21,8 @@ use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend}; use crate::eth1_finalization_cache::{Eth1FinalizationCache, Eth1FinalizationData}; use crate::events::ServerSentEventHandler; use crate::execution_payload::{ - determine_and_get_execution_payload, get_execution_payload, NotifyExecutionLayer, - PreparePayloadHandle, PreparePayloadHandleV3, + get_execution_payload, NotifyExecutionLayer, + PreparePayloadHandle, }; use crate::fork_choice_signal::{ForkChoiceSignalRx, ForkChoiceSignalTx, ForkChoiceWaitResult}; use crate::head_tracker::HeadTracker; @@ -277,8 +277,7 @@ pub trait BeaconChainTypes: Send + Sync + 'static { type EthSpec: types::EthSpec; } -/// Used internally to split block production into discrete functions. -struct PartialBeaconBlock> { +struct PartialBeaconBlock { state: BeaconState, slot: Slot, proposer_index: u64, @@ -292,25 +291,7 @@ struct PartialBeaconBlock> { deposits: Vec, voluntary_exits: Vec, sync_aggregate: Option>, - prepare_payload_handle: Option>, - bls_to_execution_changes: Vec, -} - -struct PartialBeaconBlockV3 { - state: BeaconState, - slot: Slot, - proposer_index: u64, - parent_root: Hash256, - randao_reveal: Signature, - eth1_data: Eth1Data, - graffiti: Graffiti, - proposer_slashings: Vec, - attester_slashings: Vec>, - attestations: Vec>, - deposits: Vec, - voluntary_exits: Vec, - sync_aggregate: Option>, - prepare_payload_handle: Option>, + prepare_payload_handle: Option>, bls_to_execution_changes: Vec, } @@ -4295,7 +4276,7 @@ impl BeaconChain { .task_executor .spawn_blocking_handle( move || { - chain.complete_partial_beacon_block_v3( + chain.complete_partial_beacon_block( partial_beacon_block, Some(block_contents), verification, @@ -4315,7 +4296,7 @@ impl BeaconChain { .task_executor .spawn_blocking_handle( move || { - chain.complete_partial_beacon_block_v3( + chain.complete_partial_beacon_block( partial_beacon_block, Some(block_contents), verification, @@ -4336,7 +4317,7 @@ impl BeaconChain { .task_executor .spawn_blocking_handle( move || { - chain.complete_partial_beacon_block_v3( + chain.complete_partial_beacon_block( partial_beacon_block, None, verification, @@ -4360,7 +4341,7 @@ impl BeaconChain { randao_reveal: Signature, validator_graffiti: Option, block_production_version: BlockProductionVersion, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { let eth1_chain = self .eth1_chain .as_ref() @@ -4415,7 +4396,7 @@ impl BeaconChain { let prepare_payload_handle = match &state { BeaconState::Base(_) | BeaconState::Altair(_) => None, BeaconState::Merge(_) | BeaconState::Capella(_) => { - let prepare_payload_handle = determine_and_get_execution_payload( + let prepare_payload_handle = get_execution_payload( self.clone(), &state, proposer_index, @@ -4580,7 +4561,7 @@ impl BeaconChain { Some(sync_aggregate) }; - Ok(PartialBeaconBlockV3 { + Ok(PartialBeaconBlock { state, slot, proposer_index, @@ -4599,179 +4580,9 @@ impl BeaconChain { }) } - fn complete_partial_beacon_block_v3>( - &self, - partial_beacon_block: PartialBeaconBlockV3, - block_contents: Option>, - verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { - let PartialBeaconBlockV3 { - mut state, - slot, - proposer_index, - parent_root, - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - // We don't need the prepare payload handle since the `execution_payload` is passed into - // this function. We can assume that the handle has already been consumed in order to - // produce said `execution_payload`. - prepare_payload_handle: _, - bls_to_execution_changes, - } = partial_beacon_block; - - let inner_block = match &state { - BeaconState::Base(_) => BeaconBlock::Base(BeaconBlockBase { - slot, - proposer_index, - parent_root, - state_root: Hash256::zero(), - body: BeaconBlockBodyBase { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings: proposer_slashings.into(), - attester_slashings: attester_slashings.into(), - attestations: attestations.into(), - deposits: deposits.into(), - voluntary_exits: voluntary_exits.into(), - _phantom: PhantomData, - }, - }), - BeaconState::Altair(_) => BeaconBlock::Altair(BeaconBlockAltair { - slot, - proposer_index, - parent_root, - state_root: Hash256::zero(), - body: BeaconBlockBodyAltair { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings: proposer_slashings.into(), - attester_slashings: attester_slashings.into(), - attestations: attestations.into(), - deposits: deposits.into(), - voluntary_exits: voluntary_exits.into(), - sync_aggregate: sync_aggregate - .ok_or(BlockProductionError::MissingSyncAggregate)?, - _phantom: PhantomData, - }, - }), - BeaconState::Merge(_) => BeaconBlock::Merge(BeaconBlockMerge { - slot, - proposer_index, - parent_root, - state_root: Hash256::zero(), - body: BeaconBlockBodyMerge { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings: proposer_slashings.into(), - attester_slashings: attester_slashings.into(), - attestations: attestations.into(), - deposits: deposits.into(), - voluntary_exits: voluntary_exits.into(), - sync_aggregate: sync_aggregate - .ok_or(BlockProductionError::MissingSyncAggregate)?, - execution_payload: block_contents - .ok_or(BlockProductionError::MissingExecutionPayload)? - .to_payload() - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - }, - }), - BeaconState::Capella(_) => BeaconBlock::Capella(BeaconBlockCapella { - slot, - proposer_index, - parent_root, - state_root: Hash256::zero(), - body: BeaconBlockBodyCapella { - randao_reveal, - eth1_data, - graffiti, - proposer_slashings: proposer_slashings.into(), - attester_slashings: attester_slashings.into(), - attestations: attestations.into(), - deposits: deposits.into(), - voluntary_exits: voluntary_exits.into(), - sync_aggregate: sync_aggregate - .ok_or(BlockProductionError::MissingSyncAggregate)?, - execution_payload: block_contents - .ok_or(BlockProductionError::MissingExecutionPayload)? - .to_payload() - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - bls_to_execution_changes: bls_to_execution_changes.into(), - }, - }), - }; - - let block = SignedBeaconBlock::from_block( - inner_block, - // The block is not signed here, that is the task of a validator client. - Signature::empty(), - ); - - let block_size = block.ssz_bytes_len(); - debug!( - self.log, - "Produced block on state"; - "block_size" => block_size, - ); - - metrics::observe(&metrics::BLOCK_SIZE, block_size as f64); - - if block_size > self.config.max_network_size { - return Err(BlockProductionError::BlockTooLarge(block_size)); - } - - let process_timer = metrics::start_timer(&metrics::BLOCK_PRODUCTION_PROCESS_TIMES); - let signature_strategy = match verification { - ProduceBlockVerification::VerifyRandao => BlockSignatureStrategy::VerifyRandao, - ProduceBlockVerification::NoVerification => BlockSignatureStrategy::NoVerification, - }; - // Use a context without block root or proposer index so that both are checked. - let mut ctxt = ConsensusContext::new(block.slot()); - per_block_processing( - &mut state, - &block, - signature_strategy, - StateProcessingStrategy::Accurate, - VerifyBlockRoot::True, - &mut ctxt, - &self.spec, - )?; - drop(process_timer); - - let state_root_timer = metrics::start_timer(&metrics::BLOCK_PRODUCTION_STATE_ROOT_TIMES); - let state_root = state.update_tree_hash_cache()?; - drop(state_root_timer); - - let (mut block, _) = block.deconstruct(); - *block.state_root_mut() = state_root; - - metrics::inc_counter(&metrics::BLOCK_PRODUCTION_SUCCESSES); - - trace!( - self.log, - "Produced beacon block"; - "parent" => ?block.parent_root(), - "attestations" => block.body().attestations().len(), - "slot" => block.slot() - ); - - Ok((block, state)) - } - fn complete_partial_beacon_block>( &self, - partial_beacon_block: PartialBeaconBlock, + partial_beacon_block: PartialBeaconBlock, block_contents: Option>, verification: ProduceBlockVerification, ) -> Result, BlockProductionError> { @@ -4893,7 +4704,6 @@ impl BeaconChain { self.log, "Produced block on state"; "block_size" => block_size, - "slot" => block.slot(), ); metrics::observe(&metrics::BLOCK_SIZE, block_size as f64); diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index d79cec7b749..f3a8d978fca 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -32,7 +32,7 @@ use types::payload::BlockProductionVersion; use types::*; pub type PreparePayloadResultV3 = Result, BlockProductionError>; -pub type PreparePayloadHandleV3 = JoinHandle>>; +pub type PreparePayloadHandle = JoinHandle>>; pub enum PreparePayloadHandleType { Full(JoinHandle>>>), @@ -41,7 +41,6 @@ pub enum PreparePayloadHandleType { pub type PreparePayloadResult = Result, BlockProductionError>; -pub type PreparePayloadHandle = JoinHandle>>; #[derive(PartialEq)] pub enum AllowOptimisticImport { @@ -412,13 +411,13 @@ pub fn validate_execution_payload_for_gossip( /// Equivalent to the `get_execution_payload` function in the Validator Guide: /// /// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal -pub fn determine_and_get_execution_payload( +pub fn get_execution_payload( chain: Arc>, state: &BeaconState, proposer_index: u64, builder_params: BuilderParams, block_production_version: BlockProductionVersion, -) -> Result, BlockProductionError> { +) -> Result, BlockProductionError> { // Compute all required values from the `state` now to avoid needing to pass it into a spawned // task. let spec = &chain.spec; @@ -463,70 +462,6 @@ pub fn determine_and_get_execution_payload( Ok(join_handle) } -/// Gets an execution payload for inclusion in a block. -/// -/// ## Errors -/// -/// Will return an error when using a pre-merge fork `state`. Ensure to only run this function -/// after the merge fork. -/// -/// ## Specification -/// -/// Equivalent to the `get_execution_payload` function in the Validator Guide: -/// -/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal -pub fn get_execution_payload< - T: BeaconChainTypes, - Payload: AbstractExecPayload + 'static, ->( - chain: Arc>, - state: &BeaconState, - proposer_index: u64, - builder_params: BuilderParams, -) -> Result, BlockProductionError> { - // Compute all required values from the `state` now to avoid needing to pass it into a spawned - // task. - let spec = &chain.spec; - let current_epoch = state.current_epoch(); - let is_merge_transition_complete = is_merge_transition_complete(state); - let timestamp = - compute_timestamp_at_slot(state, state.slot(), spec).map_err(BeaconStateError::from)?; - let random = *state.get_randao_mix(current_epoch)?; - let latest_execution_payload_header_block_hash = - state.latest_execution_payload_header()?.block_hash(); - let withdrawals = match state { - &BeaconState::Capella(_) => Some(get_expected_withdrawals(state, spec)?.into()), - &BeaconState::Merge(_) => None, - // These shouldn't happen but they're here to make the pattern irrefutable - &BeaconState::Base(_) | &BeaconState::Altair(_) => None, - }; - - // Spawn a task to obtain the execution payload from the EL via a series of async calls. The - // `join_handle` can be used to await the result of the function. - let join_handle = chain - .task_executor - .clone() - .spawn_handle( - async move { - prepare_execution_payload::( - &chain, - is_merge_transition_complete, - timestamp, - random, - proposer_index, - latest_execution_payload_header_block_hash, - builder_params, - withdrawals, - ) - .await - }, - "get_execution_payload", - ) - .ok_or(BlockProductionError::ShuttingDown)?; - - Ok(join_handle) -} - /// Prepares an execution payload for inclusion in a block. /// /// Will return `Ok(None)` if the merge fork has occurred, but a terminal block has not been found.