From 2cf2dec525cb286b58ee0ac6ddf672574bcdb2a7 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 14 Aug 2023 20:36:34 +0300 Subject: [PATCH 01/62] block v3 endpoint init --- beacon_node/beacon_chain/src/beacon_chain.rs | 409 ++++++++++++++++++ .../beacon_chain/src/execution_payload.rs | 177 +++++++- beacon_node/execution_layer/src/lib.rs | 353 ++++++++++++++- 3 files changed, 937 insertions(+), 2 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 25964ed2165..4070676e7b3 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -273,6 +273,11 @@ pub trait BeaconChainTypes: Send + Sync + 'static { type EthSpec: types::EthSpec; } +pub enum PartialBeaconBlockType { + Full(PartialBeaconBlock>), + Blinded(PartialBeaconBlock>), +} + /// Used internally to split block production into discrete functions. struct PartialBeaconBlock> { state: BeaconState, @@ -430,6 +435,11 @@ pub struct BeaconChain { pub genesis_backfill_slot: Slot, } +pub enum BeaconBlockAndStateResponse { + Full((BeaconBlock>, BeaconState)), + Blinded((BeaconBlock>, BeaconState)), +} + type BeaconBlockAndState = (BeaconBlock, BeaconState); impl FinalizationAndCanonicity { @@ -3628,6 +3638,41 @@ impl BeaconChain { .await } + pub async fn determine_and_produce_block_with_verification( + self: &Arc, + randao_reveal: Signature, + slot: Slot, + validator_graffiti: Option, + verification: ProduceBlockVerification, + ) -> Result, BlockProductionError> { + // Part 1/2 (blocking) + // + // Load the parent state from disk. + let chain = self.clone(); + let (state, state_root_opt) = self + .task_executor + .spawn_blocking_handle( + move || chain.load_state_for_block_production(slot), + "produce_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)??; + + // Part 2/2 (async, with some blocking components) + // + // Produce the block upon the state + self.determine_and_produce_block_on_state( + state, + state_root_opt, + slot, + randao_reveal, + validator_graffiti, + verification, + ) + .await + } + /// Same as `produce_block` but allowing for configuration of RANDAO-verification. pub async fn produce_block_with_verification< Payload: AbstractExecPayload + 'static, @@ -4215,6 +4260,127 @@ impl BeaconChain { }) } + /// Produce a block for some `slot` upon the given `state`. + /// + /// Typically the `self.produce_block()` function should be used, instead of calling this + /// function directly. This function is useful for purposefully creating forks or blocks at + /// non-current slots. + /// + /// If required, the given state will be advanced to the given `produce_at_slot`, then a block + /// will be produced at that slot height. + /// + /// The provided `state_root_opt` should only ever be set to `Some` if the contained value is + /// equal to the root of `state`. Providing this value will serve as an optimization to avoid + /// performing a tree hash in some scenarios. + pub async fn determine_and_produce_block_on_state( + self: &Arc, + state: BeaconState, + state_root_opt: Option, + produce_at_slot: Slot, + randao_reveal: Signature, + validator_graffiti: Option, + verification: ProduceBlockVerification, + ) -> Result, BlockProductionError> { + // Part 1/3 (blocking) + // + // Perform the state advance and block-packing functions. + let chain = self.clone(); + let mut partial_beacon_block_type = self + .task_executor + .spawn_blocking_handle( + move || { + chain.determine_and_produce_partial_beacon_block( + state, + state_root_opt, + produce_at_slot, + randao_reveal, + validator_graffiti, + ) + }, + "produce_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)??; + + match partial_beacon_block_type { + PartialBeaconBlockType::Full(partial_beacon_block) => { + // Part 2/3 (async) + // + // Wait for the execution layer to return an execution payload (if one is required). + let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); + let block_contents = if let Some(prepare_payload_handle) = prepare_payload_handle { + Some( + prepare_payload_handle + .await + .map_err(BlockProductionError::TokioJoin)? + .ok_or(BlockProductionError::ShuttingDown)??, + ) + } else { + None + }; + + // Part 3/3 (blocking) + // + // Perform the final steps of combining all the parts and computing the state root. + let chain = self.clone(); + self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block( + partial_beacon_block, + block_contents, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)?; + Ok(()) + } + PartialBeaconBlockType::Blinded(partial_beacon_block) => { + // Part 2/3 (async) + // + // Wait for the execution layer to return an execution payload (if one is required). + let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); + let block_contents = if let Some(prepare_payload_handle) = prepare_payload_handle { + Some( + prepare_payload_handle + .await + .map_err(BlockProductionError::TokioJoin)? + .ok_or(BlockProductionError::ShuttingDown)??, + ) + } else { + None + }; + + // Part 3/3 (blocking) + // + // Perform the final steps of combining all the parts and computing the state root. + let chain = self.clone(); + let x = self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block( + partial_beacon_block, + block_contents, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)?; + Ok(()) + } + }; + + Ok(()) + } + /// Produce a block for some `slot` upon the given `state`. /// /// Typically the `self.produce_block()` function should be used, instead of calling this @@ -4293,6 +4459,249 @@ impl BeaconChain { .map_err(BlockProductionError::TokioJoin)? } + fn determine_and_produce_partial_beacon_block( + self: &Arc, + mut state: BeaconState, + state_root_opt: Option, + produce_at_slot: Slot, + randao_reveal: Signature, + validator_graffiti: Option, + ) -> Result, BlockProductionError> { + let eth1_chain = self + .eth1_chain + .as_ref() + .ok_or(BlockProductionError::NoEth1ChainConnection)?; + + // It is invalid to try to produce a block using a state from a future slot. + if state.slot() > produce_at_slot { + return Err(BlockProductionError::StateSlotTooHigh { + produce_at_slot, + state_slot: state.slot(), + }); + } + + let slot_timer = metrics::start_timer(&metrics::BLOCK_PRODUCTION_SLOT_PROCESS_TIMES); + + // Ensure the state has performed a complete transition into the required slot. + complete_state_advance(&mut state, state_root_opt, produce_at_slot, &self.spec)?; + + drop(slot_timer); + + state.build_committee_cache(RelativeEpoch::Current, &self.spec)?; + + let parent_root = if state.slot() > 0 { + *state + .get_block_root(state.slot() - 1) + .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)? + } else { + state.latest_block_header().canonical_root() + }; + + let proposer_index = state.get_beacon_proposer_index(state.slot(), &self.spec)? as u64; + + let pubkey = state + .validators() + .get(proposer_index as usize) + .map(|v| v.pubkey) + .ok_or(BlockProductionError::BeaconChain( + BeaconChainError::ValidatorIndexUnknown(proposer_index as usize), + ))?; + + let builder_params = BuilderParams { + pubkey, + slot: state.slot(), + chain_health: self + .is_healthy(&parent_root) + .map_err(BlockProductionError::BeaconChain)?, + }; + + // If required, start the process of loading an execution payload from the EL early. This + // allows it to run concurrently with things like attestation packing. + let prepare_payload_handle = match &state { + BeaconState::Base(_) | BeaconState::Altair(_) => None, + BeaconState::Merge(_) | BeaconState::Capella(_) => { + let prepare_payload_handle = + get_execution_payload(self.clone(), &state, proposer_index, builder_params)?; + Some(prepare_payload_handle) + } + }; + + let (mut proposer_slashings, mut attester_slashings, mut voluntary_exits) = + self.op_pool.get_slashings_and_exits(&state, &self.spec); + + let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; + let deposits = eth1_chain.deposits_for_block_inclusion(&state, ð1_data, &self.spec)?; + + let bls_to_execution_changes = self + .op_pool + .get_bls_to_execution_changes(&state, &self.spec); + + // Iterate through the naive aggregation pool and ensure all the attestations from there + // are included in the operation pool. + let unagg_import_timer = + metrics::start_timer(&metrics::BLOCK_PRODUCTION_UNAGGREGATED_TIMES); + for attestation in self.naive_aggregation_pool.read().iter() { + let import = |attestation: &Attestation| { + let attesting_indices = get_attesting_indices_from_state(&state, attestation)?; + self.op_pool + .insert_attestation(attestation.clone(), attesting_indices) + }; + if let Err(e) = import(attestation) { + // Don't stop block production if there's an error, just create a log. + error!( + self.log, + "Attestation did not transfer to op pool"; + "reason" => ?e + ); + } + } + drop(unagg_import_timer); + + // Override the beacon node's graffiti with graffiti from the validator, if present. + let graffiti = match validator_graffiti { + Some(graffiti) => graffiti, + None => self.graffiti, + }; + + let attestation_packing_timer = + metrics::start_timer(&metrics::BLOCK_PRODUCTION_ATTESTATION_TIMES); + + let mut prev_filter_cache = HashMap::new(); + let prev_attestation_filter = |att: &AttestationRef| { + self.filter_op_pool_attestation(&mut prev_filter_cache, att, &state) + }; + let mut curr_filter_cache = HashMap::new(); + let curr_attestation_filter = |att: &AttestationRef| { + self.filter_op_pool_attestation(&mut curr_filter_cache, att, &state) + }; + + let mut attestations = self + .op_pool + .get_attestations( + &state, + prev_attestation_filter, + curr_attestation_filter, + &self.spec, + ) + .map_err(BlockProductionError::OpPoolError)?; + drop(attestation_packing_timer); + + // If paranoid mode is enabled re-check the signatures of every included message. + // This will be a lot slower but guards against bugs in block production and can be + // quickly rolled out without a release. + if self.config.paranoid_block_proposal { + let mut tmp_ctxt = ConsensusContext::new(state.slot()); + attestations.retain(|att| { + verify_attestation_for_block_inclusion( + &state, + att, + &mut tmp_ctxt, + VerifySignatures::True, + &self.spec, + ) + .map_err(|e| { + warn!( + self.log, + "Attempted to include an invalid attestation"; + "err" => ?e, + "block_slot" => state.slot(), + "attestation" => ?att + ); + }) + .is_ok() + }); + + proposer_slashings.retain(|slashing| { + slashing + .clone() + .validate(&state, &self.spec) + .map_err(|e| { + warn!( + self.log, + "Attempted to include an invalid proposer slashing"; + "err" => ?e, + "block_slot" => state.slot(), + "slashing" => ?slashing + ); + }) + .is_ok() + }); + + attester_slashings.retain(|slashing| { + slashing + .clone() + .validate(&state, &self.spec) + .map_err(|e| { + warn!( + self.log, + "Attempted to include an invalid attester slashing"; + "err" => ?e, + "block_slot" => state.slot(), + "slashing" => ?slashing + ); + }) + .is_ok() + }); + + voluntary_exits.retain(|exit| { + exit.clone() + .validate(&state, &self.spec) + .map_err(|e| { + warn!( + self.log, + "Attempted to include an invalid proposer slashing"; + "err" => ?e, + "block_slot" => state.slot(), + "exit" => ?exit + ); + }) + .is_ok() + }); + } + + let slot = state.slot(); + + let sync_aggregate = if matches!(&state, BeaconState::Base(_)) { + None + } else { + let sync_aggregate = self + .op_pool + .get_sync_aggregate(&state) + .map_err(BlockProductionError::OpPoolError)? + .unwrap_or_else(|| { + warn!( + self.log, + "Producing block with no sync contributions"; + "slot" => state.slot(), + ); + SyncAggregate::new() + }); + Some(sync_aggregate) + }; + + match prepare_payload_handle { + + } + + Ok(PartialBeaconBlock { + state, + slot, + proposer_index, + parent_root, + randao_reveal, + eth1_data, + graffiti, + proposer_slashings, + attester_slashings, + attestations, + deposits, + voluntary_exits, + sync_aggregate, + prepare_payload_handle, + bls_to_execution_changes, + }) + } + fn produce_partial_beacon_block + 'static>( self: &Arc, mut state: BeaconState, diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 1ac7229cc6d..4c8603a9107 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -12,7 +12,7 @@ use crate::{ BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, BlockProductionError, ExecutionPayloadError, }; -use execution_layer::{BlockProposalContents, BuilderParams, PayloadAttributes, PayloadStatus}; +use execution_layer::{BlockProposalContents, BuilderParams, PayloadAttributes, PayloadStatus, BlockProposalContentsType}; use fork_choice::{InvalidationOperation, PayloadVerificationStatus}; use proto_array::{Block as ProtoBlock, ExecutionStatus}; use slog::{debug, warn}; @@ -26,6 +26,11 @@ use tokio::task::JoinHandle; use tree_hash::TreeHash; use types::*; +pub enum PreparePayloadResultTypes { + Full(PreparePayloadResult>), + Blinded(PreparePayloadResult) +} + pub type PreparePayloadResult = Result, BlockProductionError>; pub type PreparePayloadHandle = JoinHandle>>; @@ -387,6 +392,70 @@ pub fn validate_execution_payload_for_gossip( Ok(()) } + +/// 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 determine_and_get_execution_payload< + T: BeaconChainTypes, +>( + 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) +} + /// Gets an execution payload for inclusion in a block. /// /// ## Errors @@ -556,3 +625,109 @@ where Ok(block_contents) } + + +/// 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. +/// +/// ## 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 `prepare_execution_payload` function in the Validator Guide: +/// +/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal +#[allow(clippy::too_many_arguments)] +pub async fn determine_and_prepare_execution_payload( + chain: &Arc>, + is_merge_transition_complete: bool, + timestamp: u64, + random: Hash256, + proposer_index: u64, + latest_execution_payload_header_block_hash: ExecutionBlockHash, + builder_params: BuilderParams, + withdrawals: Option>, +) -> Result, BlockProductionError> +where + T: BeaconChainTypes, +{ + let current_epoch = builder_params.slot.epoch(T::EthSpec::slots_per_epoch()); + let spec = &chain.spec; + let fork = spec.fork_name_at_slot::(builder_params.slot); + let execution_layer = chain + .execution_layer + .as_ref() + .ok_or(BlockProductionError::ExecutionLayerMissing)?; + + let parent_hash = if !is_merge_transition_complete { + let is_terminal_block_hash_set = spec.terminal_block_hash != ExecutionBlockHash::zero(); + let is_activation_epoch_reached = + current_epoch >= spec.terminal_block_hash_activation_epoch; + + if is_terminal_block_hash_set && !is_activation_epoch_reached { + // Use the "empty" payload if there's a terminal block hash, but we haven't reached the + // terminal block epoch yet. + return BlockProposalContentsType::Full::default_at_fork(fork).map_err(Into::into); + } + + let terminal_pow_block_hash = execution_layer + .get_terminal_pow_block_hash(spec, timestamp) + .await + .map_err(BlockProductionError::TerminalPoWBlockLookupFailed)?; + + if let Some(terminal_pow_block_hash) = terminal_pow_block_hash { + terminal_pow_block_hash + } else { + // If the merge transition hasn't occurred yet and the EL hasn't found the terminal + // block, return an "empty" payload. + return BlockProposalContentsType::Full::default_at_fork(fork).map_err(Into::into); + } + } else { + latest_execution_payload_header_block_hash + }; + + // Try to obtain the fork choice update parameters from the cached head. + // + // Use a blocking task to interact with the `canonical_head` lock otherwise we risk blocking the + // core `tokio` executor. + let inner_chain = chain.clone(); + let forkchoice_update_params = chain + .spawn_blocking_handle( + move || { + inner_chain + .canonical_head + .cached_head() + .forkchoice_update_parameters() + }, + "prepare_execution_payload_forkchoice_update_params", + ) + .await + .map_err(BlockProductionError::BeaconChain)?; + + let suggested_fee_recipient = execution_layer + .get_suggested_fee_recipient(proposer_index) + .await; + let payload_attributes = + PayloadAttributes::new(timestamp, random, suggested_fee_recipient, withdrawals); + + // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. + // + // This future is not executed here, it's up to the caller to await it. + let block_contents = execution_layer + .get_payload::( + parent_hash, + &payload_attributes, + forkchoice_update_params, + builder_params, + fork, + &chain.spec, + ) + .await + .map_err(BlockProductionError::GetPayloadFailed)?; + + Ok(block_contents) +} diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 579bebdacba..3ca757cff4f 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -38,7 +38,7 @@ use tokio::{ }; use tokio_stream::wrappers::WatchStream; use tree_hash::TreeHash; -use types::{AbstractExecPayload, BeaconStateError, ExecPayload}; +use types::{AbstractExecPayload, BeaconStateError, ExecPayload, FullPayload}; use types::{ BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionPayloadCapella, ExecutionPayloadMerge, ForkVersionedResponse, ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, @@ -118,6 +118,11 @@ impl From for Error { } } +pub enum BlockProposalContentsType { + Full(BlockProposalContents>), + Blinded(BlockProposalContents>) +} + pub enum BlockProposalContents> { Payload { payload: Payload, @@ -629,6 +634,90 @@ impl ExecutionLayer { } } + /// Maps to the `engine_getPayload` JSON-RPC call. + /// + /// However, it will attempt to call `self.prepare_payload` if it cannot find an existing + /// payload id for the given parameters. + /// + /// ## Fallback Behavior + /// + /// The result will be returned from the first node that returns successfully. No more nodes + /// will be contacted. + pub async fn determine_and_get_payload( + &self, + parent_hash: ExecutionBlockHash, + payload_attributes: &PayloadAttributes, + forkchoice_update_params: ForkchoiceUpdateParameters, + builder_params: BuilderParams, + current_fork: ForkName, + spec: &ChainSpec, + ) -> Result, Error> { + let payload_result = match Payload::block_type() { + BlockType::Blinded => { + let _timer = metrics::start_timer_vec( + &metrics::EXECUTION_LAYER_REQUEST_TIMES, + &[metrics::GET_BLINDED_PAYLOAD], + ); + self.get_blinded_payload( + parent_hash, + payload_attributes, + forkchoice_update_params, + builder_params, + current_fork, + spec, + ) + .await + } + BlockType::Full => { + let _timer = metrics::start_timer_vec( + &metrics::EXECUTION_LAYER_REQUEST_TIMES, + &[metrics::GET_PAYLOAD], + ); + self.get_full_payload( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await + .map(ProvenancedPayload::Local) + } + }; + + // Track some metrics and return the result. + match payload_result { + Ok(ProvenancedPayload::Local(block_proposal_contents)) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::SUCCESS], + ); + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, + &[metrics::LOCAL], + ); + Ok(block_proposal_contents) + } + Ok(ProvenancedPayload::Builder(block_proposal_contents)) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::SUCCESS], + ); + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, + &[metrics::BUILDER], + ); + Ok(block_proposal_contents) + } + Err(e) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::FAILURE], + ); + Err(e) + } + } + } + /// Maps to the `engine_getPayload` JSON-RPC call. /// /// However, it will attempt to call `self.prepare_payload` if it cannot find an existing @@ -713,6 +802,268 @@ impl ExecutionLayer { } } + async fn determine_and_fetch_payload( + &self, + parent_hash: ExecutionBlockHash, + payload_attributes: &PayloadAttributes, + forkchoice_update_params: ForkchoiceUpdateParameters, + builder_params: BuilderParams, + current_fork: ForkName, + spec: &ChainSpec, + ) -> Result>, Error> { + if let Some(builder) = self.builder() { + let slot = builder_params.slot; + let pubkey = builder_params.pubkey; + + match builder_params.chain_health { + ChainHealth::Healthy => { + info!( + self.log(), + "Requesting blinded header from connected builder"; + "slot" => ?slot, + "pubkey" => ?pubkey, + "parent_hash" => ?parent_hash, + ); + + // Wait for the builder *and* local EL to produce a payload (or return an error). + let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( + timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { + builder + .get_builder_header::(slot, parent_hash, &pubkey) + .await + }), + timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { + self.get_full_payload_caching::( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await + }) + ); + + info!( + self.log(), + "Requested blinded execution payload"; + "relay_fee_recipient" => match &relay_result { + Ok(Some(r)) => format!("{:?}", r.data.message.header.fee_recipient()), + Ok(None) => "empty response".to_string(), + Err(_) => "request failed".to_string(), + }, + "relay_response_ms" => relay_duration.as_millis(), + "local_fee_recipient" => match &local_result { + Ok(proposal_contents) => format!("{:?}", proposal_contents.payload().fee_recipient()), + Err(_) => "request failed".to_string() + }, + "local_response_ms" => local_duration.as_millis(), + "parent_hash" => ?parent_hash, + ); + + return match (relay_result, local_result) { + (Err(e), Ok(local)) => { + warn!( + self.log(), + "Builder error when requesting payload"; + "info" => "falling back to local execution client", + "relay_error" => ?e, + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(local)) + } + (Ok(None), Ok(local)) => { + info!( + self.log(), + "Builder did not return a payload"; + "info" => "falling back to local execution client", + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(local)) + } + (Ok(Some(relay)), Ok(local)) => { + let header = &relay.data.message.header; + + info!( + self.log(), + "Received local and builder payloads"; + "relay_block_hash" => ?header.block_hash(), + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + + let relay_value = relay.data.message.value; + let local_value = *local.block_value(); + if !self.inner.always_prefer_builder_payload { + if local_value >= relay_value { + info!( + self.log(), + "Local block is more profitable than relay block"; + "local_block_value" => %local_value, + "relay_value" => %relay_value + ); + return Ok(ProvenancedPayload::Local(local)); + } else { + info!( + self.log(), + "Relay block is more profitable than local block"; + "local_block_value" => %local_value, + "relay_value" => %relay_value + ); + } + } + + match verify_builder_bid( + &relay, + parent_hash, + payload_attributes, + Some(local.payload().block_number()), + self.inner.builder_profit_threshold, + current_fork, + spec, + ) { + Ok(()) => Ok(ProvenancedPayload::Builder( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + )), + Err(reason) if !reason.payload_invalid() => { + info!( + self.log(), + "Builder payload ignored"; + "info" => "using local payload", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(local)) + } + Err(reason) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, + &[reason.as_ref().as_ref()], + ); + warn!( + self.log(), + "Builder returned invalid payload"; + "info" => "using local payload", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(local)) + } + } + } + (Ok(Some(relay)), Err(local_error)) => { + let header = &relay.data.message.header; + + info!( + self.log(), + "Received builder payload with local error"; + "relay_block_hash" => ?header.block_hash(), + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + match verify_builder_bid( + &relay, + parent_hash, + payload_attributes, + None, + self.inner.builder_profit_threshold, + current_fork, + spec, + ) { + Ok(()) => Ok(ProvenancedPayload::Builder( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + )), + // If the payload is valid then use it. The local EE failed + // to produce a payload so we have no alternative. + Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + )), + Err(reason) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, + &[reason.as_ref().as_ref()], + ); + crit!( + self.log(), + "Builder returned invalid payload"; + "info" => "no local payload either - unable to propose block", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Err(Error::CannotProduceHeader) + } + } + } + (Err(relay_error), Err(local_error)) => { + crit!( + self.log(), + "Unable to produce execution payload"; + "info" => "the local EL and builder both failed - unable to propose block", + "relay_error" => ?relay_error, + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + Err(Error::CannotProduceHeader) + } + (Ok(None), Err(local_error)) => { + crit!( + self.log(), + "Unable to produce execution payload"; + "info" => "the local EL failed and the builder returned nothing - \ + the block proposal will be missed", + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + Err(Error::CannotProduceHeader) + } + }; + } + ChainHealth::Unhealthy(condition) => info!( + self.log(), + "Chain is unhealthy, using local payload"; + "info" => "this helps protect the network. the --builder-fallback flags \ + can adjust the expected health conditions.", + "failed_condition" => ?condition + ), + // Intentional no-op, so we never attempt builder API proposals pre-merge. + ChainHealth::PreMerge => (), + ChainHealth::Optimistic => info!( + self.log(), + "Chain is optimistic; can't build payload"; + "info" => "the local execution engine is syncing and the builder network \ + cannot safely be used - unable to propose block" + ), + } + } + self.get_full_payload_caching( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await + .map(ProvenancedPayload::Local) + } + async fn get_blinded_payload>( &self, parent_hash: ExecutionBlockHash, From cd36be539a23ee3f2a4422386bcbf0bc564bcf2c Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 15 Aug 2023 00:44:11 +0300 Subject: [PATCH 02/62] block v3 flow --- beacon_node/beacon_chain/src/beacon_chain.rs | 177 ++++++------ beacon_node/beacon_chain/src/errors.rs | 1 + .../beacon_chain/src/execution_payload.rs | 40 ++- beacon_node/execution_layer/src/lib.rs | 262 +++++++++++++----- 4 files changed, 316 insertions(+), 164 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 4070676e7b3..a2fd6882734 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -20,7 +20,10 @@ use crate::errors::{BeaconChainError as Error, BlockProductionError}; use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend}; use crate::eth1_finalization_cache::{Eth1FinalizationCache, Eth1FinalizationData}; use crate::events::ServerSentEventHandler; -use crate::execution_payload::{get_execution_payload, NotifyExecutionLayer, PreparePayloadHandle}; +use crate::execution_payload::{ + determine_and_get_execution_payload, get_execution_payload, NotifyExecutionLayer, + PreparePayloadHandle, PreparePayloadHandleV3, +}; use crate::fork_choice_signal::{ForkChoiceSignalRx, ForkChoiceSignalTx, ForkChoiceWaitResult}; use crate::head_tracker::HeadTracker; use crate::historical_blocks::HistoricalBlockError; @@ -297,6 +300,24 @@ struct PartialBeaconBlock> { 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>, + bls_to_execution_changes: Vec, +} + pub type BeaconForkChoice = ForkChoice< BeaconForkChoiceStore< ::EthSpec, @@ -438,6 +459,7 @@ pub struct BeaconChain { pub enum BeaconBlockAndStateResponse { Full((BeaconBlock>, BeaconState)), Blinded((BeaconBlock>, BeaconState)), + BeaconBlockError() } type BeaconBlockAndState = (BeaconBlock, BeaconState); @@ -4285,7 +4307,7 @@ impl BeaconChain { // // Perform the state advance and block-packing functions. let chain = self.clone(); - let mut partial_beacon_block_type = self + let mut partial_beacon_block = self .task_executor .spawn_blocking_handle( move || { @@ -4303,82 +4325,71 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)??; - match partial_beacon_block_type { - PartialBeaconBlockType::Full(partial_beacon_block) => { - // Part 2/3 (async) - // - // Wait for the execution layer to return an execution payload (if one is required). - let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); - let block_contents = if let Some(prepare_payload_handle) = prepare_payload_handle { - Some( - prepare_payload_handle - .await - .map_err(BlockProductionError::TokioJoin)? - .ok_or(BlockProductionError::ShuttingDown)??, - ) - } else { - None - }; - - // Part 3/3 (blocking) - // - // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - self.task_executor - .spawn_blocking_handle( - move || { - chain.complete_partial_beacon_block( - partial_beacon_block, - block_contents, - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)?; - Ok(()) - } - PartialBeaconBlockType::Blinded(partial_beacon_block) => { - // Part 2/3 (async) - // - // Wait for the execution layer to return an execution payload (if one is required). - let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); - let block_contents = if let Some(prepare_payload_handle) = prepare_payload_handle { - Some( - prepare_payload_handle - .await - .map_err(BlockProductionError::TokioJoin)? - .ok_or(BlockProductionError::ShuttingDown)??, - ) - } else { - None - }; - - // Part 3/3 (blocking) - // - // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - let x = self.task_executor - .spawn_blocking_handle( - move || { - chain.complete_partial_beacon_block( - partial_beacon_block, - block_contents, - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? + // Part 2/3 (async) + // + // Wait for the execution layer to return an execution payload (if one is required). + let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); + let block_contents_type = if let Some(prepare_payload_handle) = prepare_payload_handle { + Some( + prepare_payload_handle .await - .map_err(BlockProductionError::TokioJoin)?; - Ok(()) - } + .map_err(BlockProductionError::TokioJoin)? + .ok_or(BlockProductionError::ShuttingDown)??, + ) + } else { + None }; - Ok(()) + if let Some(block_contents) = block_contents_type { + match block_contents { + execution_layer::BlockProposalContentsType::Full(block_contents) => { + // Part 3/3 (blocking) + // + // Perform the final steps of combining all the parts and computing the state root. + let chain = self.clone(); + let result = self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block( + partial_beacon_block, + Some(block_contents), + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)?; + + return Ok(BeaconBlockAndStateResponse::Full(result?)) + } + execution_layer::BlockProposalContentsType::Blinded(block_contents) => { + // Part 3/3 (blocking) + // + // Perform the final steps of combining all the parts and computing the state root. + let chain = self.clone(); + let result = self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block( + partial_beacon_block, + Some(block_contents), + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)?; + + return Ok(BeaconBlockAndStateResponse::Blinded(result?)) + } + } + } else { + Err(BlockProductionError::FailedToFetchBlock) + } } /// Produce a block for some `slot` upon the given `state`. @@ -4466,7 +4477,7 @@ impl BeaconChain { produce_at_slot: Slot, randao_reveal: Signature, validator_graffiti: Option, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { let eth1_chain = self .eth1_chain .as_ref() @@ -4520,8 +4531,12 @@ impl BeaconChain { let prepare_payload_handle = match &state { BeaconState::Base(_) | BeaconState::Altair(_) => None, BeaconState::Merge(_) | BeaconState::Capella(_) => { - let prepare_payload_handle = - get_execution_payload(self.clone(), &state, proposer_index, builder_params)?; + let prepare_payload_handle = determine_and_get_execution_payload( + self.clone(), + &state, + proposer_index, + builder_params, + )?; Some(prepare_payload_handle) } }; @@ -4679,11 +4694,7 @@ impl BeaconChain { Some(sync_aggregate) }; - match prepare_payload_handle { - - } - - Ok(PartialBeaconBlock { + Ok(PartialBeaconBlockV3 { state, slot, proposer_index, diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 87141311505..94afd6ad159 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -273,6 +273,7 @@ pub enum BlockProductionError { TokioJoin(tokio::task::JoinError), BeaconChain(BeaconChainError), InvalidPayloadFork, + FailedToFetchBlock } easy_from_to!(BlockProcessingError, BlockProductionError); diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 4c8603a9107..167f1208229 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -12,7 +12,10 @@ use crate::{ BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, BlockProductionError, ExecutionPayloadError, }; -use execution_layer::{BlockProposalContents, BuilderParams, PayloadAttributes, PayloadStatus, BlockProposalContentsType}; +use execution_layer::{ + BlockProposalContents, BlockProposalContentsType, BuilderParams, PayloadAttributes, + PayloadStatus, +}; use fork_choice::{InvalidationOperation, PayloadVerificationStatus}; use proto_array::{Block as ProtoBlock, ExecutionStatus}; use slog::{debug, warn}; @@ -21,15 +24,14 @@ use state_processing::per_block_processing::{ compute_timestamp_at_slot, get_expected_withdrawals, is_execution_enabled, is_merge_transition_complete, partially_verify_execution_payload, }; +use std::marker::PhantomData; use std::sync::Arc; use tokio::task::JoinHandle; use tree_hash::TreeHash; use types::*; -pub enum PreparePayloadResultTypes { - Full(PreparePayloadResult>), - Blinded(PreparePayloadResult) -} +pub type PreparePayloadResultV3 = Result, BlockProductionError>; +pub type PreparePayloadHandleV3 = JoinHandle>>; pub type PreparePayloadResult = Result, BlockProductionError>; @@ -392,7 +394,6 @@ pub fn validate_execution_payload_for_gossip( Ok(()) } - /// Gets an execution payload for inclusion in a block. /// /// ## Errors @@ -405,14 +406,12 @@ 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< - T: BeaconChainTypes, ->( +pub fn determine_and_get_execution_payload( chain: Arc>, state: &BeaconState, proposer_index: u64, builder_params: BuilderParams, -) -> 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; @@ -437,7 +436,7 @@ pub fn determine_and_get_execution_payload< .clone() .spawn_handle( async move { - prepare_execution_payload::( + determine_and_prepare_execution_payload::( &chain, is_merge_transition_complete, timestamp, @@ -626,7 +625,6 @@ where Ok(block_contents) } - /// 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. @@ -671,7 +669,13 @@ where if is_terminal_block_hash_set && !is_activation_epoch_reached { // Use the "empty" payload if there's a terminal block hash, but we haven't reached the // terminal block epoch yet. - return BlockProposalContentsType::Full::default_at_fork(fork).map_err(Into::into); + return Ok(BlockProposalContentsType::Full( + BlockProposalContents::Payload { + payload: FullPayload::default_at_fork(fork)?, + block_value: Uint256::zero(), + _phantom: PhantomData, + }, + )); } let terminal_pow_block_hash = execution_layer @@ -684,7 +688,13 @@ where } else { // If the merge transition hasn't occurred yet and the EL hasn't found the terminal // block, return an "empty" payload. - return BlockProposalContentsType::Full::default_at_fork(fork).map_err(Into::into); + return Ok(BlockProposalContentsType::Full( + BlockProposalContents::Payload { + payload: FullPayload::default_at_fork(fork)?, + block_value: Uint256::zero(), + _phantom: PhantomData, + }, + )); } } else { latest_execution_payload_header_block_hash @@ -718,7 +728,7 @@ where // // This future is not executed here, it's up to the caller to await it. let block_contents = execution_layer - .get_payload::( + .determine_and_get_payload( parent_hash, &payload_attributes, forkchoice_update_params, diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 3ca757cff4f..7269747fb8f 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -120,7 +120,7 @@ impl From for Error { pub enum BlockProposalContentsType { Full(BlockProposalContents>), - Blinded(BlockProposalContents>) + Blinded(BlockProposalContents>), } pub enum BlockProposalContents> { @@ -652,41 +652,34 @@ impl ExecutionLayer { current_fork: ForkName, spec: &ChainSpec, ) -> Result, Error> { - let payload_result = match Payload::block_type() { - BlockType::Blinded => { - let _timer = metrics::start_timer_vec( - &metrics::EXECUTION_LAYER_REQUEST_TIMES, - &[metrics::GET_BLINDED_PAYLOAD], - ); - self.get_blinded_payload( - parent_hash, - payload_attributes, - forkchoice_update_params, - builder_params, - current_fork, - spec, - ) - .await - } - BlockType::Full => { - let _timer = metrics::start_timer_vec( - &metrics::EXECUTION_LAYER_REQUEST_TIMES, - &[metrics::GET_PAYLOAD], + let payload_result_type = match self + .determine_and_fetch_payload( + parent_hash, + payload_attributes, + forkchoice_update_params, + builder_params, + current_fork, + spec, + ) + .await + { + Ok(payload) => payload, + Err(e) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::FAILURE], ); - self.get_full_payload( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await - .map(ProvenancedPayload::Local) + return Err(e); } }; - // Track some metrics and return the result. - match payload_result { - Ok(ProvenancedPayload::Local(block_proposal_contents)) => { + let block_proposal_content_type = match payload_result_type { + ProvenancedPayload::Local(local_payload) => local_payload, + ProvenancedPayload::Builder(builder_payload) => builder_payload, + }; + + match block_proposal_content_type { + BlockProposalContentsType::Full(block_proposal_contents) => { metrics::inc_counter_vec( &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, &[metrics::SUCCESS], @@ -695,9 +688,9 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, &[metrics::LOCAL], ); - Ok(block_proposal_contents) + return Ok(BlockProposalContentsType::Full(block_proposal_contents)); } - Ok(ProvenancedPayload::Builder(block_proposal_contents)) => { + BlockProposalContentsType::Blinded(block_proposal_contents) => { metrics::inc_counter_vec( &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, &[metrics::SUCCESS], @@ -706,14 +699,7 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, &[metrics::BUILDER], ); - Ok(block_proposal_contents) - } - Err(e) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, - &[metrics::FAILURE], - ); - Err(e) + return Ok(BlockProposalContentsType::Blinded(block_proposal_contents)); } } } @@ -810,7 +796,7 @@ impl ExecutionLayer { builder_params: BuilderParams, current_fork: ForkName, spec: &ChainSpec, - ) -> Result>, Error> { + ) -> Result>, Error> { if let Some(builder) = self.builder() { let slot = builder_params.slot; let pubkey = builder_params.pubkey; @@ -829,11 +815,15 @@ impl ExecutionLayer { let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { builder - .get_builder_header::(slot, parent_hash, &pubkey) + .get_builder_header::>( + slot, + parent_hash, + &pubkey, + ) .await }), timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { - self.get_full_payload_caching::( + self.get_full_payload_caching::>( parent_hash, payload_attributes, forkchoice_update_params, @@ -870,7 +860,9 @@ impl ExecutionLayer { "local_block_hash" => ?local.payload().block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(local)) + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full( + local, + ))) } (Ok(None), Ok(local)) => { info!( @@ -880,7 +872,9 @@ impl ExecutionLayer { "local_block_hash" => ?local.payload().block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(local)) + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full( + local, + ))) } (Ok(Some(relay)), Ok(local)) => { let header = &relay.data.message.header; @@ -903,7 +897,9 @@ impl ExecutionLayer { "local_block_value" => %local_value, "relay_value" => %relay_value ); - return Ok(ProvenancedPayload::Local(local)); + return Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Full(local), + )); } else { info!( self.log(), @@ -924,11 +920,13 @@ impl ExecutionLayer { spec, ) { Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), Err(reason) if !reason.payload_invalid() => { info!( @@ -939,7 +937,9 @@ impl ExecutionLayer { "relay_block_hash" => ?header.block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(local)) + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full( + local, + ))) } Err(reason) => { metrics::inc_counter_vec( @@ -954,7 +954,9 @@ impl ExecutionLayer { "relay_block_hash" => ?header.block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(local)) + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Full( + local, + ))) } } } @@ -979,20 +981,24 @@ impl ExecutionLayer { spec, ) { Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), // If the payload is valid then use it. The local EE failed // to produce a payload so we have no alternative. Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), Err(reason) => { metrics::inc_counter_vec( @@ -1054,7 +1060,7 @@ impl ExecutionLayer { ), } } - self.get_full_payload_caching( + self.get_full_payload_caching_v3( parent_hash, payload_attributes, forkchoice_update_params, @@ -1344,6 +1350,24 @@ impl ExecutionLayer { .await } + /// Get a full payload and cache its result in the execution layer's payload cache. + async fn get_full_payload_caching_v3( + &self, + parent_hash: ExecutionBlockHash, + payload_attributes: &PayloadAttributes, + forkchoice_update_params: ForkchoiceUpdateParameters, + current_fork: ForkName, + ) -> Result, Error> { + self.get_full_payload_with_v3( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + Self::cache_payload, + ) + .await + } + /// Get a full payload and cache its result in the execution layer's payload cache. async fn get_full_payload_caching>( &self, @@ -1362,6 +1386,112 @@ impl ExecutionLayer { .await } + async fn get_full_payload_with_v3( + &self, + parent_hash: ExecutionBlockHash, + payload_attributes: &PayloadAttributes, + forkchoice_update_params: ForkchoiceUpdateParameters, + current_fork: ForkName, + f: fn(&ExecutionLayer, ExecutionPayloadRef) -> Option>, + ) -> Result, Error> { + self.engine() + .request(move |engine| async move { + let payload_id = if let Some(id) = engine + .get_payload_id(&parent_hash, payload_attributes) + .await + { + // The payload id has been cached for this engine. + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_PRE_PREPARED_PAYLOAD_ID, + &[metrics::HIT], + ); + id + } else { + // The payload id has *not* been cached. Trigger an artificial + // fork choice update to retrieve a payload ID. + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_PRE_PREPARED_PAYLOAD_ID, + &[metrics::MISS], + ); + let fork_choice_state = ForkchoiceState { + head_block_hash: parent_hash, + safe_block_hash: forkchoice_update_params + .justified_hash + .unwrap_or_else(ExecutionBlockHash::zero), + finalized_block_hash: forkchoice_update_params + .finalized_hash + .unwrap_or_else(ExecutionBlockHash::zero), + }; + + let response = engine + .notify_forkchoice_updated( + fork_choice_state, + Some(payload_attributes.clone()), + self.log(), + ) + .await?; + + match response.payload_id { + Some(payload_id) => payload_id, + None => { + error!( + self.log(), + "Exec engine unable to produce payload"; + "msg" => "No payload ID, the engine is likely syncing. \ + This has the potential to cause a missed block proposal.", + "status" => ?response.payload_status + ); + return Err(ApiError::PayloadIdUnavailable); + } + } + }; + + let payload_fut = async { + debug!( + self.log(), + "Issuing engine_getPayload"; + "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(), + "prev_randao" => ?payload_attributes.prev_randao(), + "timestamp" => payload_attributes.timestamp(), + "parent_hash" => ?parent_hash, + ); + engine.api.get_payload::(current_fork, payload_id).await + }; + let payload_response = payload_fut.await; + let (execution_payload, block_value) = payload_response.map(|payload_response| { + if payload_response.execution_payload_ref().fee_recipient() != payload_attributes.suggested_fee_recipient() { + error!( + self.log(), + "Inconsistent fee recipient"; + "msg" => "The fee recipient returned from the Execution Engine differs \ + from the suggested_fee_recipient set on the beacon node. This could \ + indicate that fees are being diverted to another address. Please \ + ensure that the value of suggested_fee_recipient is set correctly and \ + that the Execution Engine is trusted.", + "fee_recipient" => ?payload_response.execution_payload_ref().fee_recipient(), + "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(), + ); + } + if f(self, payload_response.execution_payload_ref()).is_some() { + warn!( + self.log(), + "Duplicate payload cached, this might indicate redundant proposal \ + attempts." + ); + } + payload_response.into() + })?; + Ok(BlockProposalContentsType::Full(BlockProposalContents::Payload { + payload: execution_payload.into(), + block_value, + _phantom: PhantomData, + })) + }) + .await + .map_err(Box::new) + .map_err(Error::EngineError) + } + async fn get_full_payload_with>( &self, parent_hash: ExecutionBlockHash, From 6515ce48f1f549eeb404c22a7661150f25ed7876 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 15 Aug 2023 00:46:58 +0300 Subject: [PATCH 03/62] block v3 flow --- beacon_node/beacon_chain/src/beacon_chain.rs | 14 ++++++++------ beacon_node/beacon_chain/src/errors.rs | 2 +- beacon_node/execution_layer/src/lib.rs | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index a2fd6882734..33ff2791854 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -459,7 +459,7 @@ pub struct BeaconChain { pub enum BeaconBlockAndStateResponse { Full((BeaconBlock>, BeaconState)), Blinded((BeaconBlock>, BeaconState)), - BeaconBlockError() + BeaconBlockError(), } type BeaconBlockAndState = (BeaconBlock, BeaconState); @@ -4347,7 +4347,8 @@ impl BeaconChain { // // Perform the final steps of combining all the parts and computing the state root. let chain = self.clone(); - let result = self.task_executor + let result = self + .task_executor .spawn_blocking_handle( move || { chain.complete_partial_beacon_block( @@ -4362,14 +4363,15 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)?; - return Ok(BeaconBlockAndStateResponse::Full(result?)) + return Ok(BeaconBlockAndStateResponse::Full(result?)); } execution_layer::BlockProposalContentsType::Blinded(block_contents) => { // Part 3/3 (blocking) // // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - let result = self.task_executor + let chain = self.clone(); + let result = self + .task_executor .spawn_blocking_handle( move || { chain.complete_partial_beacon_block( @@ -4384,7 +4386,7 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)?; - return Ok(BeaconBlockAndStateResponse::Blinded(result?)) + return Ok(BeaconBlockAndStateResponse::Blinded(result?)); } } } else { diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 94afd6ad159..d7311774796 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -273,7 +273,7 @@ pub enum BlockProductionError { TokioJoin(tokio::task::JoinError), BeaconChain(BeaconChainError), InvalidPayloadFork, - FailedToFetchBlock + FailedToFetchBlock, } easy_from_to!(BlockProcessingError, BlockProductionError); diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 7269747fb8f..d2c73955034 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -688,7 +688,7 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, &[metrics::LOCAL], ); - return Ok(BlockProposalContentsType::Full(block_proposal_contents)); + Ok(BlockProposalContentsType::Full(block_proposal_contents)) } BlockProposalContentsType::Blinded(block_proposal_contents) => { metrics::inc_counter_vec( @@ -699,7 +699,7 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, &[metrics::BUILDER], ); - return Ok(BlockProposalContentsType::Blinded(block_proposal_contents)); + Ok(BlockProposalContentsType::Blinded(block_proposal_contents)) } } } From a55e91db9d197214c11334663666f102b775c4ad Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 15 Aug 2023 23:14:02 +0300 Subject: [PATCH 04/62] continue refactor --- beacon_node/beacon_chain/src/beacon_chain.rs | 312 +++++++++++++++---- 1 file changed, 258 insertions(+), 54 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 33ff2791854..29f45751f5a 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -63,8 +63,8 @@ use crate::validator_pubkey_cache::ValidatorPubkeyCache; use crate::{metrics, BeaconChainError, BeaconForkChoiceStore, BeaconSnapshot, CachedHead}; use eth2::types::{EventKind, SseBlock, SseExtendedPayloadAttributes, SyncDuty}; use execution_layer::{ - BlockProposalContents, BuilderParams, ChainHealth, ExecutionLayer, FailedCondition, - PayloadAttributes, PayloadStatus, + BlockProposalContents, BlockProposalContentsType, BuilderParams, ChainHealth, ExecutionLayer, + FailedCondition, PayloadAttributes, PayloadStatus, }; use fork_choice::{ AttestationFromBlock, ExecutionStatus, ForkChoice, ForkchoiceUpdateParameters, @@ -4340,58 +4340,21 @@ impl BeaconChain { None }; - if let Some(block_contents) = block_contents_type { - match block_contents { - execution_layer::BlockProposalContentsType::Full(block_contents) => { - // Part 3/3 (blocking) - // - // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - let result = self - .task_executor - .spawn_blocking_handle( - move || { - chain.complete_partial_beacon_block( - partial_beacon_block, - Some(block_contents), - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)?; - - return Ok(BeaconBlockAndStateResponse::Full(result?)); - } - execution_layer::BlockProposalContentsType::Blinded(block_contents) => { - // Part 3/3 (blocking) - // - // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - let result = self - .task_executor - .spawn_blocking_handle( - move || { - chain.complete_partial_beacon_block( - partial_beacon_block, - Some(block_contents), - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)?; - - return Ok(BeaconBlockAndStateResponse::Blinded(result?)); - } - } - } else { - Err(BlockProductionError::FailedToFetchBlock) - } + let chain = self.clone(); + self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_determined_partial_beacon_block( + partial_beacon_block, + block_contents_type, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)? } /// Produce a block for some `slot` upon the given `state`. @@ -4954,6 +4917,247 @@ impl BeaconChain { }) } + fn complete_determined_partial_beacon_block( + &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 block_type = BlockType::Full; + + 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(_) => { + let block_contents_type = + block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; + match block_contents_type { + BlockProposalContentsType::Full(block_content) => { + 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_content + .to_payload() + .try_into() + .map_err(|_| BlockProductionError::InvalidPayloadFork)?, + }, + }) + } + BlockProposalContentsType::Blinded(block_content) => { + block_type = BlockType::Blinded; + 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: BlindedPayloadMerge { + execution_payload_header: block_content + .to_payload() + .into() + }, + }, + }) + } + } + } + BeaconState::Capella(_) => { + let block_contents_type = + block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; + match block_contents_type { + BlockProposalContentsType::Full(block_content) => { + 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_content + .to_payload() + .try_into() + .map_err(|_| BlockProductionError::InvalidPayloadFork)?, + bls_to_execution_changes: bls_to_execution_changes.into(), + }, + }) + } + BlockProposalContentsType::Blinded(block_content) => { + block_type = BlockType::Blinded; + 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_content + .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() + ); + + match block_type { + BlockType::Blinded => Ok(BeaconBlockAndStateResponse::Full((block, state))), + BlockType::Full => Ok(BeaconBlockAndStateResponse::Blinded((block, state))), + } + } + fn complete_partial_beacon_block>( &self, partial_beacon_block: PartialBeaconBlock, From 5d984f0c583873b0abd60064e147a183e01d2c71 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 16 Aug 2023 14:20:03 +0300 Subject: [PATCH 05/62] the full flow... --- beacon_node/beacon_chain/src/beacon_chain.rs | 282 ++++++++---------- .../beacon_chain/src/execution_payload.rs | 5 + 2 files changed, 124 insertions(+), 163 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 29f45751f5a..f20c2c98993 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -276,11 +276,6 @@ pub trait BeaconChainTypes: Send + Sync + 'static { type EthSpec: types::EthSpec; } -pub enum PartialBeaconBlockType { - Full(PartialBeaconBlock>), - Blinded(PartialBeaconBlock>), -} - /// Used internally to split block production into discrete functions. struct PartialBeaconBlock> { state: BeaconState, @@ -4309,52 +4304,86 @@ impl BeaconChain { let chain = self.clone(); let mut partial_beacon_block = self .task_executor - .spawn_blocking_handle( - move || { - chain.determine_and_produce_partial_beacon_block( - state, - state_root_opt, - produce_at_slot, - randao_reveal, - validator_graffiti, - ) + .clone() + .spawn_handle( + async move { + chain + .determine_and_produce_partial_beacon_block( + state, + state_root_opt, + produce_at_slot, + randao_reveal, + validator_graffiti, + ) + .await }, "produce_partial_beacon_block", ) .ok_or(BlockProductionError::ShuttingDown)? .await - .map_err(BlockProductionError::TokioJoin)??; + .map_err(BlockProductionError::TokioJoin)? + .ok_or(BlockProductionError::ShuttingDown)??; // Part 2/3 (async) // // Wait for the execution layer to return an execution payload (if one is required). let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); - let block_contents_type = if let Some(prepare_payload_handle) = prepare_payload_handle { - Some( - prepare_payload_handle - .await - .map_err(BlockProductionError::TokioJoin)? - .ok_or(BlockProductionError::ShuttingDown)??, - ) - } else { - None - }; + let block_contents_type_option = + if let Some(prepare_payload_handle) = prepare_payload_handle { + Some( + prepare_payload_handle + .await + .map_err(BlockProductionError::TokioJoin)? + .ok_or(BlockProductionError::ShuttingDown)??, + ) + } else { + None + }; - let chain = self.clone(); - self.task_executor - .spawn_blocking_handle( - move || { - chain.complete_determined_partial_beacon_block( - partial_beacon_block, - block_contents_type, - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)? + if let Some(block_contents_type) = block_contents_type_option { + match block_contents_type { + BlockProposalContentsType::Full(block_contents) => { + let chain = self.clone(); + let beacon_block_and_state = self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block_v3( + partial_beacon_block, + block_contents, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)??; + + Ok(BeaconBlockAndStateResponse::Full(beacon_block_and_state)) + } + BlockProposalContentsType::Blinded(block_contents) => { + let chain = self.clone(); + let beacon_block_and_state = self.task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block_v3( + partial_beacon_block, + block_contents, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)??; + + Ok(BeaconBlockAndStateResponse::Blinded(beacon_block_and_state)) + } + } + } else { + Err(BlockProductionError::FailedToFetchBlock) + } } /// Produce a block for some `slot` upon the given `state`. @@ -4435,7 +4464,7 @@ impl BeaconChain { .map_err(BlockProductionError::TokioJoin)? } - fn determine_and_produce_partial_beacon_block( + async fn determine_and_produce_partial_beacon_block( self: &Arc, mut state: BeaconState, state_root_opt: Option, @@ -4917,12 +4946,12 @@ impl BeaconChain { }) } - fn complete_determined_partial_beacon_block( + fn complete_partial_beacon_block_v3>( &self, partial_beacon_block: PartialBeaconBlockV3, - block_contents: Option>, + block_contents: BlockProposalContents, verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { let PartialBeaconBlockV3 { mut state, slot, @@ -4944,8 +4973,6 @@ impl BeaconChain { bls_to_execution_changes, } = partial_beacon_block; - let block_type = BlockType::Full; - let inner_block = match &state { BeaconState::Base(_) => BeaconBlock::Base(BeaconBlockBase { slot, @@ -4983,119 +5010,51 @@ impl BeaconChain { _phantom: PhantomData, }, }), - BeaconState::Merge(_) => { - let block_contents_type = - block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - match block_contents_type { - BlockProposalContentsType::Full(block_content) => { - 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_content - .to_payload() - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - }, - }) - } - BlockProposalContentsType::Blinded(block_content) => { - block_type = BlockType::Blinded; - 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: BlindedPayloadMerge { - execution_payload_header: block_content - .to_payload() - .into() - }, - }, - }) - } - } - } - BeaconState::Capella(_) => { - let block_contents_type = - block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - match block_contents_type { - BlockProposalContentsType::Full(block_content) => { - 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_content - .to_payload() - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - bls_to_execution_changes: bls_to_execution_changes.into(), - }, - }) - } - BlockProposalContentsType::Blinded(block_content) => { - block_type = BlockType::Blinded; - 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_content - .to_payload() - .try_into() - .map_err(|_| BlockProductionError::InvalidPayloadFork)?, - bls_to_execution_changes: bls_to_execution_changes.into(), - }, - }) - } - } - } + 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 + .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 + .to_payload() + .try_into() + .map_err(|_| BlockProductionError::InvalidPayloadFork)?, + bls_to_execution_changes: bls_to_execution_changes.into(), + }, + }), }; let block = SignedBeaconBlock::from_block( @@ -5152,10 +5111,7 @@ impl BeaconChain { "slot" => block.slot() ); - match block_type { - BlockType::Blinded => Ok(BeaconBlockAndStateResponse::Full((block, state))), - BlockType::Full => Ok(BeaconBlockAndStateResponse::Blinded((block, state))), - } + Ok((block, state)) } fn complete_partial_beacon_block>( diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 167f1208229..2b44f5c6f83 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -33,6 +33,11 @@ use types::*; pub type PreparePayloadResultV3 = Result, BlockProductionError>; pub type PreparePayloadHandleV3 = JoinHandle>>; +pub enum PreparePayloadHandleType { + Full(JoinHandle>>>), + Blinded(JoinHandle>>>), +} + pub type PreparePayloadResult = Result, BlockProductionError>; pub type PreparePayloadHandle = JoinHandle>>; From 48661b4eb30def829d6af70b170628d11c604395 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 16 Aug 2023 18:34:53 +0300 Subject: [PATCH 06/62] add api logic --- beacon_node/beacon_chain/src/beacon_chain.rs | 13 +- beacon_node/beacon_chain/src/lib.rs | 7 +- beacon_node/http_api/src/validator.rs | 147 ++++++++++++++++++- beacon_node/http_api/src/version.rs | 30 +++- common/eth2/src/lib.rs | 2 + 5 files changed, 188 insertions(+), 11 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index f20c2c98993..3481e55a0a2 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -452,12 +452,11 @@ pub struct BeaconChain { } pub enum BeaconBlockAndStateResponse { - Full((BeaconBlock>, BeaconState)), - Blinded((BeaconBlock>, BeaconState)), - BeaconBlockError(), + Full(BeaconBlockAndState>), + Blinded(BeaconBlockAndState>), } -type BeaconBlockAndState = (BeaconBlock, BeaconState); +pub type BeaconBlockAndState = (BeaconBlock, BeaconState); impl FinalizationAndCanonicity { pub fn is_finalized(self) -> bool { @@ -4344,7 +4343,8 @@ impl BeaconChain { match block_contents_type { BlockProposalContentsType::Full(block_contents) => { let chain = self.clone(); - let beacon_block_and_state = self.task_executor + let beacon_block_and_state = self + .task_executor .spawn_blocking_handle( move || { chain.complete_partial_beacon_block_v3( @@ -4363,7 +4363,8 @@ impl BeaconChain { } BlockProposalContentsType::Blinded(block_contents) => { let chain = self.clone(); - let beacon_block_and_state = self.task_executor + let beacon_block_and_state = self + .task_executor .spawn_blocking_handle( move || { chain.complete_partial_beacon_block_v3( diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index 4ea1eeee011..d15e2c300b9 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -51,9 +51,10 @@ pub mod validator_monitor; pub mod validator_pubkey_cache; pub use self::beacon_chain::{ - AttestationProcessingOutcome, BeaconChain, BeaconChainTypes, BeaconStore, ChainSegmentResult, - ForkChoiceError, OverrideForkchoiceUpdate, ProduceBlockVerification, StateSkipConfig, - WhenSlotSkipped, INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON, + AttestationProcessingOutcome, BeaconBlockAndStateResponse, BeaconChain, BeaconChainTypes, + BeaconStore, ChainSegmentResult, ForkChoiceError, OverrideForkchoiceUpdate, + ProduceBlockVerification, StateSkipConfig, WhenSlotSkipped, + INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON, INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON, }; pub use self::beacon_snapshot::BeaconSnapshot; diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 18e9dbf636b..9d1d0d01d7b 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,6 +1,23 @@ -use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; use types::*; +use std::sync::Arc; + +use beacon_chain::{ + BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes, + ProduceBlockVerification, +}; +use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; +use ssz::Encode; +use types::*; +use warp::{ + hyper::{Body, Response}, + Reply, +}; + +use crate::version::{ + add_consensus_version_header, add_execution_payload_blinded_header, + add_execution_payload_value_header, fork_versioned_response, inconsistent_fork_rejection, +}; /// Uses the `chain.validator_pubkey_cache` to resolve a pubkey to a validator /// index and then ensures that the validator exists in the given `state`. pub fn pubkey_to_validator_index( @@ -19,3 +36,131 @@ pub fn pubkey_to_validator_index( .map(Result::Ok) .transpose() } + +pub fn get_randao_verification( + query: &api_types::ValidatorBlocksQuery, + randao_reveal_infinity: bool, +) -> Result { + let randao_verification = if query.skip_randao_verification == SkipRandaoVerification::Yes { + if !randao_reveal_infinity { + return Err(warp_utils::reject::custom_bad_request( + "randao_reveal must be point-at-infinity if verification is skipped".into(), + )); + } + ProduceBlockVerification::NoVerification + } else { + ProduceBlockVerification::VerifyRandao + }; + + Ok(randao_verification) +} + +pub async fn determine_and_produce_block_json( + endpoint_version: EndpointVersion, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + let randao_reveal = query.randao_reveal.decompress().map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "randao reveal is not a valid BLS signature: {:?}", + e + )) + })?; + + let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + + match chain + .determine_and_produce_block_with_verification( + randao_reveal, + slot, + query.graffiti.map(Into::into), + randao_verification, + ) + .await + .unwrap() + { + BeaconBlockAndStateResponse::Full((block, state)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, true)) + .map(|res: Response| add_execution_payload_value_header(res, 0)) + // TODO + } + BeaconBlockAndStateResponse::Blinded((block, state)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, true)) + .map(|res: Response| add_execution_payload_value_header(res, 0)) + // TODO + } + } +} + +pub async fn determine_and_produce_block_ssz( + endpoint_version: EndpointVersion, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + let randao_reveal = query.randao_reveal.decompress().map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "randao reveal is not a valid BLS signature: {:?}", + e + )) + })?; + + let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + + // TODO: block value + let (block_ssz, fork_name, block_value) = match chain + .determine_and_produce_block_with_verification( + randao_reveal, + slot, + query.graffiti.map(Into::into), + randao_verification, + ) + .await + .unwrap() + { + BeaconBlockAndStateResponse::Full((block, state)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + (block.as_ssz_bytes(), fork_name, 0) + } + BeaconBlockAndStateResponse::Blinded((block, state)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + (block.as_ssz_bytes(), fork_name, 0) + } + }; + + Response::builder() + .status(200) + .header("Content-Type", "application/ssz") + .body(block_ssz.into()) + .map(|res: Response| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, blinded)) + .map(|res: Response| add_execution_payload_value_header(res, block_value)) + .map_err(|e| -> warp::Rejection { + warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) + }) +} diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index e01ff982201..f9af1421e19 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -1,6 +1,8 @@ use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse; use crate::api_types::EndpointVersion; -use eth2::CONSENSUS_VERSION_HEADER; +use eth2::{ + CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, +}; use serde::Serialize; use types::{ForkName, ForkVersionedResponse, InconsistentFork}; use warp::reply::{self, Reply, Response}; @@ -53,6 +55,32 @@ pub fn add_consensus_version_header(reply: T, fork_name: ForkName) -> reply::with_header(reply, CONSENSUS_VERSION_HEADER, fork_name.to_string()).into_response() } +/// Add the `Eth-Execution-Payload-Blinded` header to a response. +pub fn add_execution_payload_blinded_header( + reply: T, + execution_payload_blinded: bool, +) -> Response { + reply::with_header( + reply, + EXECUTION_PAYLOAD_BLINDED_HEADER, + execution_payload_blinded.to_string(), + ) + .into_response() +} + +/// Add the `Eth-Execution-Payload-Value` header to a response. +pub fn add_execution_payload_value_header( + reply: T, + execution_payload_value: u32, +) -> Response { + reply::with_header( + reply, + EXECUTION_PAYLOAD_VALUE_HEADER, + execution_payload_value.to_string(), + ) + .into_response() +} + pub fn inconsistent_fork_rejection(error: InconsistentFork) -> warp::reject::Rejection { warp_utils::reject::custom_server_error(format!("wrong fork: {:?}", error)) } diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 146a832e388..a0a6676972a 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -40,6 +40,8 @@ pub const V1: EndpointVersion = EndpointVersion(1); pub const V2: EndpointVersion = EndpointVersion(2); pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version"; +pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded"; +pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value"; #[derive(Debug)] pub enum Error { From ae690fb5ce23e6c520283aae348888f548cd8875 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 16 Aug 2023 18:40:35 +0300 Subject: [PATCH 07/62] add api logic --- beacon_node/http_api/src/validator.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 9d1d0d01d7b..87d526e6688 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -8,7 +8,6 @@ use beacon_chain::{ }; use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; use ssz::Encode; -use types::*; use warp::{ hyper::{Body, Response}, Reply, @@ -80,7 +79,7 @@ pub async fn determine_and_produce_block_json( .await .unwrap() { - BeaconBlockAndStateResponse::Full((block, state)) => { + BeaconBlockAndStateResponse::Full((block, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -89,11 +88,11 @@ pub async fn determine_and_produce_block_json( fork_versioned_response(endpoint_version, fork_name, block) .map(|response| warp::reply::json(&response).into_response()) .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, true)) + .map(|res| add_execution_payload_blinded_header(res, false)) .map(|res: Response| add_execution_payload_value_header(res, 0)) // TODO } - BeaconBlockAndStateResponse::Blinded((block, state)) => { + BeaconBlockAndStateResponse::Blinded((block, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -110,7 +109,6 @@ pub async fn determine_and_produce_block_json( } pub async fn determine_and_produce_block_ssz( - endpoint_version: EndpointVersion, chain: Arc>, slot: Slot, query: api_types::ValidatorBlocksQuery, @@ -125,7 +123,7 @@ pub async fn determine_and_produce_block_ssz( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; // TODO: block value - let (block_ssz, fork_name, block_value) = match chain + let (block_ssz, fork_name, block_value, blinded) = match chain .determine_and_produce_block_with_verification( randao_reveal, slot, @@ -135,21 +133,21 @@ pub async fn determine_and_produce_block_ssz( .await .unwrap() { - BeaconBlockAndStateResponse::Full((block, state)) => { + BeaconBlockAndStateResponse::Full((block, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, 0) + (block.as_ssz_bytes(), fork_name, 0, false) } - BeaconBlockAndStateResponse::Blinded((block, state)) => { + BeaconBlockAndStateResponse::Blinded((block, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, 0) + (block.as_ssz_bytes(), fork_name, 0, true) } }; From 1802e45d81192d59fa57fa8c19e8099308e1e864 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 17 Aug 2023 00:14:20 +0300 Subject: [PATCH 08/62] add new endpoint version --- beacon_node/http_api/src/lib.rs | 3 ++- beacon_node/http_api/src/version.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 9512d18aba8..69f57721b2e 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -335,7 +335,8 @@ pub fn serve( let eth_v1 = single_version(V1); let eth_v2 = single_version(V2); - + let eth_v3 = single_version(V3); + // Create a `warp` filter that provides access to the network globals. let inner_network_globals = ctx.network_globals.clone(); let network_globals = warp::any() diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index f9af1421e19..5768a570e0b 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -9,6 +9,8 @@ use warp::reply::{self, Reply, Response}; pub const V1: EndpointVersion = EndpointVersion(1); pub const V2: EndpointVersion = EndpointVersion(2); +pub const V3: EndpointVersion = EndpointVersion(3); + pub fn fork_versioned_response( endpoint_version: EndpointVersion, From bac744e2571434485847ad85d7fbe1dab997e88c Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 17 Aug 2023 00:48:11 +0300 Subject: [PATCH 09/62] added v3 endpoint --- beacon_node/http_api/src/lib.rs | 52 ++++++-------------------- beacon_node/http_api/src/validator.rs | 53 +++++++++++++++++++++++++++ beacon_node/http_api/src/version.rs | 1 - 3 files changed, 64 insertions(+), 42 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 47fe81684ec..09f0bf822e2 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -30,6 +30,7 @@ use beacon_chain::{ validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, WhenSlotSkipped, }; +use crate::validator::{produce_block_v3, produce_block_v2}; use beacon_processor::BeaconProcessorSend; pub use block_id::BlockId; use bytes::Bytes; @@ -68,7 +69,7 @@ use tokio::sync::{ use tokio_stream::{wrappers::BroadcastStream, StreamExt}; use types::{ Attestation, AttestationData, AttestationShufflingId, AttesterSlashing, BeaconStateError, - BlindedPayload, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, FullPayload, + BlindedPayload, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, ProposerPreparationData, ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, SignedBeaconBlock, SignedBlindedBeaconBlock, SignedBlsToExecutionChange, SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, @@ -77,7 +78,7 @@ use types::{ use validator::pubkey_to_validator_index; use version::{ add_consensus_version_header, execution_optimistic_finalized_fork_versioned_response, - fork_versioned_response, inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, + fork_versioned_response, inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, V3, }; use warp::http::StatusCode; use warp::sse::Event; @@ -336,7 +337,7 @@ pub fn serve( let eth_v1 = single_version(V1); let eth_v2 = single_version(V2); let eth_v3 = single_version(V3); - + // Create a `warp` filter that provides access to the network globals. let inner_network_globals = ctx.network_globals.clone(); let network_globals = warp::any() @@ -2968,6 +2969,7 @@ pub fn serve( )) })) .and(warp::path::end()) + .and(warp::header::optional::("accept")) .and(not_while_syncing_filter.clone()) .and(warp::query::()) .and(task_spawner_filter.clone()) @@ -2976,6 +2978,7 @@ pub fn serve( .then( |endpoint_version: EndpointVersion, slot: Slot, + accept_header: Option, query: api_types::ValidatorBlocksQuery, task_spawner: TaskSpawner, chain: Arc>, @@ -2986,44 +2989,11 @@ pub fn serve( "Block production request from HTTP API"; "slot" => slot ); - - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = - if query.skip_randao_verification == SkipRandaoVerification::Yes { - if !randao_reveal.is_infinity() { - return Err(warp_utils::reject::custom_bad_request( - "randao_reveal must be point-at-infinity if verification is skipped" - .into(), - )); - } - ProduceBlockVerification::NoVerification - } else { - ProduceBlockVerification::VerifyRandao - }; - - let (block, _) = chain - .produce_block_with_verification::>( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - ) - .await - .map_err(warp_utils::reject::block_production_error)?; - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) + if endpoint_version == V3 { + produce_block_v3(endpoint_version, accept_header, chain, slot, query).await + } else { + produce_block_v2(endpoint_version, chain, slot, query).await + } }) }, ); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 87d526e6688..0bdd5f6dbfc 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -54,6 +54,59 @@ pub fn get_randao_verification( Ok(randao_verification) } +pub async fn produce_block_v2( + endpoint_version: EndpointVersion, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + let randao_reveal = query.randao_reveal.decompress().map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "randao reveal is not a valid BLS signature: {:?}", + e + )) + })?; + + let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + + let (block, _) = chain + .produce_block_with_verification::>( + randao_reveal, + slot, + query.graffiti.map(Into::into), + randao_verification, + ) + .await + .map_err(warp_utils::reject::block_production_error)?; + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) +} + +pub async fn produce_block_v3( + endpoint_version: EndpointVersion, + accept_header: Option, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + if let Some(accept_header_type) = accept_header { + match accept_header_type { + api_types::Accept::Json | api_types::Accept::Any => { + determine_and_produce_block_json(endpoint_version, chain, slot, query).await + } + api_types::Accept::Ssz => determine_and_produce_block_ssz(chain, slot, query).await, + } + } else { + determine_and_produce_block_json(endpoint_version, chain, slot, query).await + } +} + pub async fn determine_and_produce_block_json( endpoint_version: EndpointVersion, chain: Arc>, diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index 5768a570e0b..f1ea852020a 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -11,7 +11,6 @@ pub const V1: EndpointVersion = EndpointVersion(1); pub const V2: EndpointVersion = EndpointVersion(2); pub const V3: EndpointVersion = EndpointVersion(3); - pub fn fork_versioned_response( endpoint_version: EndpointVersion, fork_name: ForkName, From 54860ac67153751b96842f8a20ef79a8f1391640 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 21 Aug 2023 12:49:50 +0300 Subject: [PATCH 10/62] some debugging --- beacon_node/beacon_chain/src/beacon_chain.rs | 13 +++- beacon_node/execution_layer/src/lib.rs | 2 +- beacon_node/http_api/src/validator.rs | 18 +++++- beacon_node/http_api/src/version.rs | 2 +- .../http_api/tests/interactive_tests.rs | 24 ++++++-- common/eth2/src/lib.rs | 60 +++++++++++++++++++ common/eth2/src/types.rs | 5 ++ 7 files changed, 111 insertions(+), 13 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index f5cd205d6b1..a4ba627a83f 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -3664,6 +3664,7 @@ impl BeaconChain { // Part 1/2 (blocking) // // Load the parent state from disk. + println!("part 1"); let chain = self.clone(); let (state, state_root_opt) = self .task_executor @@ -3678,6 +3679,7 @@ impl BeaconChain { // Part 2/2 (async, with some blocking components) // // Produce the block upon the state + println!("part 2"); self.determine_and_produce_block_on_state( state, state_root_opt, @@ -4300,6 +4302,7 @@ impl BeaconChain { // Part 1/3 (blocking) // // Perform the state advance and block-packing functions. + println!("yo"); let chain = self.clone(); let mut partial_beacon_block = self .task_executor @@ -4322,13 +4325,14 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)? .ok_or(BlockProductionError::ShuttingDown)??; - + println!("does it get here"); // Part 2/3 (async) // // Wait for the execution layer to return an execution payload (if one is required). let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); let block_contents_type_option = if let Some(prepare_payload_handle) = prepare_payload_handle { + println!("ITS NOT NONE"); Some( prepare_payload_handle .await @@ -4336,6 +4340,7 @@ impl BeaconChain { .ok_or(BlockProductionError::ShuttingDown)??, ) } else { + println!("ITS NONE"); None }; @@ -4523,8 +4528,12 @@ impl BeaconChain { // If required, start the process of loading an execution payload from the EL early. This // allows it to run concurrently with things like attestation packing. + let prepare_payload_handle = match &state { - BeaconState::Base(_) | BeaconState::Altair(_) => None, + BeaconState::Base(_) | BeaconState::Altair(_) => { + println!("the state is base or"); + None + }, BeaconState::Merge(_) | BeaconState::Capella(_) => { let prepare_payload_handle = determine_and_get_execution_payload( self.clone(), diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 0d79305c4bb..586709e8132 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -118,6 +118,7 @@ impl From for Error { } } + pub enum BlockProposalContentsType { Full(BlockProposalContents>), Blinded(BlockProposalContents>), @@ -800,7 +801,6 @@ impl ExecutionLayer { if let Some(builder) = self.builder() { let slot = builder_params.slot; let pubkey = builder_params.pubkey; - match builder_params.chain_health { ChainHealth::Healthy => { info!( diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 0bdd5f6dbfc..6fed43df6ba 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -121,7 +121,7 @@ pub async fn determine_and_produce_block_json( })?; let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - + println!("lets try to fetch"); match chain .determine_and_produce_block_with_verification( randao_reveal, @@ -130,9 +130,15 @@ pub async fn determine_and_produce_block_json( randao_verification, ) .await - .unwrap() + .map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "faield to fetch a block: {:?}", + e + )) + })? { BeaconBlockAndStateResponse::Full((block, _)) => { + println!("full"); let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -146,6 +152,7 @@ pub async fn determine_and_produce_block_json( // TODO } BeaconBlockAndStateResponse::Blinded((block, _)) => { + println!("blinded"); let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -184,7 +191,12 @@ pub async fn determine_and_produce_block_ssz( randao_verification, ) .await - .unwrap() + .map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "faield to fetch a block: {:?}", + e + )) + })? { BeaconBlockAndStateResponse::Full((block, _)) => { let fork_name = block diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index f1ea852020a..da83a2c14ef 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -18,7 +18,7 @@ pub fn fork_versioned_response( ) -> Result, warp::reject::Rejection> { let fork_name = if endpoint_version == V1 { None - } else if endpoint_version == V2 { + } else if endpoint_version == V2 || endpoint_version == V3 { Some(fork_name) } else { return Err(unsupported_version_rejection(endpoint_version)); diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index d7ea7c26284..9c55950c312 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -21,6 +21,8 @@ use types::{ MainnetEthSpec, MinimalEthSpec, ProposerPreparationData, Slot, }; +use eth2::types::ForkVersionedBeaconBlockType::{Full, Blinded}; + type E = MainnetEthSpec; // Test that the deposit_contract endpoint returns the correct chain_id and address. @@ -617,14 +619,24 @@ pub async fn proposer_boost_re_org_test( let randao_reveal = harness .sign_randao_reveal(&state_b, proposer_index, slot_c) .into(); - let unsigned_block_c = tester + let unsigned_block_type = tester .client - .get_validator_blocks(slot_c, &randao_reveal, None) + .get_validator_blocks_v3::(slot_c, &randao_reveal, None) .await - .unwrap() - .data; - let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b); - + .unwrap(); + + let block_c = match unsigned_block_type { + Full(unsigned_block_c) => { + println!("full"); + harness.sign_beacon_block(unsigned_block_c.data, &state_b) + }, + Blinded(unsigned_block_c) => { + println!("blinded"); + harness.sign_beacon_block(unsigned_block_c.data, &state_b) + } + }; + // let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b); + if should_re_org { // Block C should build on A. assert_eq!(block_c.parent_root(), block_a_root.into()); diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index a0a6676972a..44ead55d2f9 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -38,11 +38,14 @@ use store::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedRes pub const V1: EndpointVersion = EndpointVersion(1); pub const V2: EndpointVersion = EndpointVersion(2); +pub const V3: EndpointVersion = EndpointVersion(3); pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version"; pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded"; pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value"; + + #[derive(Debug)] pub enum Error { /// The `reqwest` client raised an error. @@ -1615,6 +1618,63 @@ impl BeaconNodeHttpClient { self.get(path).await } + /// `GET v3/validator/blocks/{slot}` + pub async fn get_validator_blocks_v3( + &self, + slot: Slot, + randao_reveal: &SignatureBytes, + graffiti: Option<&Graffiti>, + ) -> Result, Error> { + self.get_validator_blocks_v3_modular(slot, randao_reveal, graffiti, SkipRandaoVerification::No) + .await + } + + /// `GET v3/validator/blocks/{slot}` + pub async fn get_validator_blocks_v3_modular( + &self, + slot: Slot, + randao_reveal: &SignatureBytes, + graffiti: Option<&Graffiti>, + skip_randao_verification: SkipRandaoVerification, + ) -> Result, Error> { + let mut path = self.eth_path(V3)?; + + path.path_segments_mut() + .map_err(|()| Error::InvalidUrl(self.server.clone()))? + .push("validator") + .push("blocks") + .push(&slot.to_string()); + + path.query_pairs_mut() + .append_pair("randao_reveal", &randao_reveal.to_string()); + + if let Some(graffiti) = graffiti { + path.query_pairs_mut() + .append_pair("graffiti", &graffiti.to_string()); + } + + if skip_randao_verification == SkipRandaoVerification::Yes { + path.query_pairs_mut() + .append_pair("skip_randao_verification", ""); + } + + println!("before"); + + let response = self.get_response(path, |b| b).await?; + + println!("after"); + + if let Some(header_value) = response.headers().get(EXECUTION_PAYLOAD_BLINDED_HEADER) { + if header_value.eq("true") { + let blinded_payload = response.json::>>>().await?; + return Ok(ForkVersionedBeaconBlockType::Blinded(blinded_payload)) + } + }; + + let full_payload = response.json::>>>().await?; + Ok(ForkVersionedBeaconBlockType::Full(full_payload)) + } + /// `GET v2/validator/blinded_blocks/{slot}` pub async fn get_validator_blinded_blocks>( &self, diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index f451d3b8f2e..e851af71ad8 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -1311,6 +1311,11 @@ pub struct BroadcastValidationQuery { pub broadcast_validation: BroadcastValidation, } +pub enum ForkVersionedBeaconBlockType { + Full(ForkVersionedResponse>>), + Blinded(ForkVersionedResponse>>) +} + #[cfg(test)] mod tests { use super::*; From 17f00f36b4a78ec6591a364bba6f2bc74961cce7 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 31 Aug 2023 20:57:11 +0300 Subject: [PATCH 11/62] merge v2 flow with v3 --- beacon_node/beacon_chain/src/beacon_chain.rs | 20 +++---- .../beacon_chain/src/execution_payload.rs | 5 ++ beacon_node/execution_layer/src/lib.rs | 53 ++++++++++------- beacon_node/http_api/src/lib.rs | 6 +- beacon_node/http_api/src/validator.rs | 59 ++++++++++--------- .../http_api/tests/interactive_tests.rs | 8 +-- common/eth2/src/lib.rs | 25 +++++--- common/eth2/src/types.rs | 3 +- consensus/types/src/payload.rs | 7 +++ 9 files changed, 110 insertions(+), 76 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 045416a0c67..7a077019cd6 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -109,6 +109,7 @@ use task_executor::{ShutdownReason, TaskExecutor}; use tokio_stream::Stream; use tree_hash::TreeHash; use types::beacon_state::CloneConfig; +use types::payload::BlockProductionVersion; use types::*; pub type ForkChoiceError = fork_choice::Error; @@ -3660,11 +3661,11 @@ impl BeaconChain { slot: Slot, validator_graffiti: Option, verification: ProduceBlockVerification, + block_production_version: BlockProductionVersion, ) -> Result, BlockProductionError> { // Part 1/2 (blocking) // // Load the parent state from disk. - println!("part 1"); let chain = self.clone(); let (state, state_root_opt) = self .task_executor @@ -3679,7 +3680,6 @@ impl BeaconChain { // Part 2/2 (async, with some blocking components) // // Produce the block upon the state - println!("part 2"); self.determine_and_produce_block_on_state( state, state_root_opt, @@ -3687,6 +3687,7 @@ impl BeaconChain { randao_reveal, validator_graffiti, verification, + block_production_version, ) .await } @@ -4298,11 +4299,11 @@ impl BeaconChain { randao_reveal: Signature, validator_graffiti: Option, verification: ProduceBlockVerification, + block_production_version: BlockProductionVersion, ) -> Result, BlockProductionError> { // Part 1/3 (blocking) // // Perform the state advance and block-packing functions. - println!("yo"); let chain = self.clone(); let mut partial_beacon_block = self .task_executor @@ -4316,6 +4317,7 @@ impl BeaconChain { produce_at_slot, randao_reveal, validator_graffiti, + block_production_version, ) .await }, @@ -4325,14 +4327,12 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)? .ok_or(BlockProductionError::ShuttingDown)??; - println!("does it get here"); // Part 2/3 (async) // // Wait for the execution layer to return an execution payload (if one is required). let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); let block_contents_type_option = if let Some(prepare_payload_handle) = prepare_payload_handle { - println!("ITS NOT NONE"); Some( prepare_payload_handle .await @@ -4340,7 +4340,6 @@ impl BeaconChain { .ok_or(BlockProductionError::ShuttingDown)??, ) } else { - println!("ITS NONE"); None }; @@ -4477,6 +4476,7 @@ impl BeaconChain { produce_at_slot: Slot, randao_reveal: Signature, validator_graffiti: Option, + block_production_version: BlockProductionVersion, ) -> Result, BlockProductionError> { let eth1_chain = self .eth1_chain @@ -4528,18 +4528,16 @@ impl BeaconChain { // If required, start the process of loading an execution payload from the EL early. This // allows it to run concurrently with things like attestation packing. - + let prepare_payload_handle = match &state { - BeaconState::Base(_) | BeaconState::Altair(_) => { - println!("the state is base or"); - None - }, + BeaconState::Base(_) | BeaconState::Altair(_) => None, BeaconState::Merge(_) | BeaconState::Capella(_) => { let prepare_payload_handle = determine_and_get_execution_payload( self.clone(), &state, proposer_index, builder_params, + block_production_version, )?; Some(prepare_payload_handle) } diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 2b44f5c6f83..d79cec7b749 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -28,6 +28,7 @@ use std::marker::PhantomData; use std::sync::Arc; use tokio::task::JoinHandle; use tree_hash::TreeHash; +use types::payload::BlockProductionVersion; use types::*; pub type PreparePayloadResultV3 = Result, BlockProductionError>; @@ -416,6 +417,7 @@ pub fn determine_and_get_execution_payload( state: &BeaconState, proposer_index: u64, builder_params: BuilderParams, + block_production_version: BlockProductionVersion, ) -> Result, BlockProductionError> { // Compute all required values from the `state` now to avoid needing to pass it into a spawned // task. @@ -450,6 +452,7 @@ pub fn determine_and_get_execution_payload( latest_execution_payload_header_block_hash, builder_params, withdrawals, + block_production_version, ) .await }, @@ -654,6 +657,7 @@ pub async fn determine_and_prepare_execution_payload( latest_execution_payload_header_block_hash: ExecutionBlockHash, builder_params: BuilderParams, withdrawals: Option>, + block_production_version: BlockProductionVersion, ) -> Result, BlockProductionError> where T: BeaconChainTypes, @@ -740,6 +744,7 @@ where builder_params, fork, &chain.spec, + block_production_version, ) .await .map_err(BlockProductionError::GetPayloadFailed)?; diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 586709e8132..a6a0abe8a13 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -38,6 +38,7 @@ use tokio::{ }; use tokio_stream::wrappers::WatchStream; use tree_hash::TreeHash; +use types::payload::BlockProductionVersion; use types::{AbstractExecPayload, BeaconStateError, ExecPayload, FullPayload}; use types::{ BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionPayloadCapella, ExecutionPayloadMerge, @@ -118,7 +119,6 @@ impl From for Error { } } - pub enum BlockProposalContentsType { Full(BlockProposalContents>), Blinded(BlockProposalContents>), @@ -652,26 +652,39 @@ impl ExecutionLayer { builder_params: BuilderParams, current_fork: ForkName, spec: &ChainSpec, + block_production_version: BlockProductionVersion, ) -> Result, Error> { - let payload_result_type = match self - .determine_and_fetch_payload( - parent_hash, - payload_attributes, - forkchoice_update_params, - builder_params, - current_fork, - spec, - ) - .await - { - Ok(payload) => payload, - Err(e) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, - &[metrics::FAILURE], - ); - return Err(e); - } + let payload_result_type = match block_production_version { + BlockProductionVersion::V3 | BlockProductionVersion::BlindedV2 => match self + .determine_and_fetch_payload( + parent_hash, + payload_attributes, + forkchoice_update_params, + builder_params, + current_fork, + spec, + ) + .await + { + Ok(payload) => payload, + Err(e) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, + &[metrics::FAILURE], + ); + return Err(e); + } + }, + BlockProductionVersion::FullV2 => self + .get_full_payload_with_v3( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + noop, + ) + .await + .map(ProvenancedPayload::Local)?, }; let block_proposal_content_type = match payload_result_type { diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index fb05052c3ad..0117278c137 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -26,12 +26,12 @@ mod validator; mod validator_inclusion; mod version; +use crate::validator::{produce_block_v2, produce_block_v3}; use beacon_chain::{ attestation_verification::VerifiedAttestation, observed_operations::ObservationOutcome, validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, WhenSlotSkipped, }; -use crate::validator::{produce_block_v3, produce_block_v2}; use beacon_processor::BeaconProcessorSend; pub use block_id::BlockId; use builder_states::get_next_withdrawals; @@ -83,7 +83,8 @@ use types::{ use validator::pubkey_to_validator_index; use version::{ add_consensus_version_header, execution_optimistic_finalized_fork_versioned_response, - fork_versioned_response, inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, V3, + fork_versioned_response, inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, + V3, }; use warp::http::StatusCode; use warp::sse::Event; @@ -346,7 +347,6 @@ pub fn serve( let eth_v1 = single_version(V1); let eth_v2 = single_version(V2); - let eth_v3 = single_version(V3); // Create a `warp` filter that provides access to the network globals. let inner_network_globals = ctx.network_globals.clone(); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 6fed43df6ba..ef982f8c110 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,4 +1,4 @@ -use types::*; +use types::{payload::BlockProductionVersion, *}; use std::sync::Arc; @@ -69,23 +69,34 @@ pub async fn produce_block_v2( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - let (block, _) = chain - .produce_block_with_verification::>( + let block_response = chain + .determine_and_produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), randao_verification, + BlockProductionVersion::FullV2, ) .await .map_err(warp_utils::reject::block_production_error)?; - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) + + match block_response { + BeaconBlockAndStateResponse::Full((block, _)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + } + BeaconBlockAndStateResponse::Blinded((_, _)) => { + Err(warp_utils::reject::custom_server_error( + "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() + )) + } + } } pub async fn produce_block_v3( @@ -121,24 +132,22 @@ pub async fn determine_and_produce_block_json( })?; let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - println!("lets try to fetch"); - match chain + + let block_response = chain .determine_and_produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), randao_verification, + BlockProductionVersion::V3, ) .await .map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "faield to fetch a block: {:?}", - e - )) - })? - { + warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) + })?; + + match block_response { BeaconBlockAndStateResponse::Full((block, _)) => { - println!("full"); let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -152,7 +161,6 @@ pub async fn determine_and_produce_block_json( // TODO } BeaconBlockAndStateResponse::Blinded((block, _)) => { - println!("blinded"); let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -189,15 +197,12 @@ pub async fn determine_and_produce_block_ssz( slot, query.graffiti.map(Into::into), randao_verification, + BlockProductionVersion::V3, ) .await .map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "faield to fetch a block: {:?}", - e - )) - })? - { + warp_utils::reject::custom_bad_request(format!("faield to fetch a block: {:?}", e)) + })? { BeaconBlockAndStateResponse::Full((block, _)) => { let fork_name = block .to_ref() diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index 9c55950c312..0c51da5110b 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -21,7 +21,7 @@ use types::{ MainnetEthSpec, MinimalEthSpec, ProposerPreparationData, Slot, }; -use eth2::types::ForkVersionedBeaconBlockType::{Full, Blinded}; +use eth2::types::ForkVersionedBeaconBlockType::{Blinded, Full}; type E = MainnetEthSpec; @@ -624,19 +624,19 @@ pub async fn proposer_boost_re_org_test( .get_validator_blocks_v3::(slot_c, &randao_reveal, None) .await .unwrap(); - + let block_c = match unsigned_block_type { Full(unsigned_block_c) => { println!("full"); harness.sign_beacon_block(unsigned_block_c.data, &state_b) - }, + } Blinded(unsigned_block_c) => { println!("blinded"); harness.sign_beacon_block(unsigned_block_c.data, &state_b) } }; // let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b); - + if should_re_org { // Block C should build on A. assert_eq!(block_c.parent_root(), block_a_root.into()); diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index afd37782762..d544b3a3e5e 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -44,8 +44,6 @@ pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version"; pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded"; pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value"; - - #[derive(Debug)] pub enum Error { /// The `reqwest` client raised an error. @@ -1642,9 +1640,14 @@ impl BeaconNodeHttpClient { randao_reveal: &SignatureBytes, graffiti: Option<&Graffiti>, ) -> Result, Error> { - self.get_validator_blocks_v3_modular(slot, randao_reveal, graffiti, SkipRandaoVerification::No) - .await - } + self.get_validator_blocks_v3_modular( + slot, + randao_reveal, + graffiti, + SkipRandaoVerification::No, + ) + .await + } /// `GET v3/validator/blocks/{slot}` pub async fn get_validator_blocks_v3_modular( @@ -1683,12 +1686,16 @@ impl BeaconNodeHttpClient { if let Some(header_value) = response.headers().get(EXECUTION_PAYLOAD_BLINDED_HEADER) { if header_value.eq("true") { - let blinded_payload = response.json::>>>().await?; - return Ok(ForkVersionedBeaconBlockType::Blinded(blinded_payload)) + let blinded_payload = response + .json::>>>() + .await?; + return Ok(ForkVersionedBeaconBlockType::Blinded(blinded_payload)); } }; - - let full_payload = response.json::>>>().await?; + + let full_payload = response + .json::>>>() + .await?; Ok(ForkVersionedBeaconBlockType::Full(full_payload)) } diff --git a/common/eth2/src/types.rs b/common/eth2/src/types.rs index d4f40cf4bc0..35911fc002c 100644 --- a/common/eth2/src/types.rs +++ b/common/eth2/src/types.rs @@ -1338,10 +1338,9 @@ pub mod serde_status_code { pub enum ForkVersionedBeaconBlockType { Full(ForkVersionedResponse>>), - Blinded(ForkVersionedResponse>>) + Blinded(ForkVersionedResponse>>), } - #[cfg(test)] mod tests { use super::*; diff --git a/consensus/types/src/payload.rs b/consensus/types/src/payload.rs index 2795c7f1092..f365d875d15 100644 --- a/consensus/types/src/payload.rs +++ b/consensus/types/src/payload.rs @@ -915,3 +915,10 @@ impl From> for ExecutionPayloadHeader { } } } + +/// The block production flow version to be used. +pub enum BlockProductionVersion { + V3, + BlindedV2, + FullV2, +} From 272cb76e4ecf8c34ee2ccbecb3afce7258929483 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 4 Sep 2023 20:56:36 +0300 Subject: [PATCH 12/62] debugging --- beacon_node/beacon_chain/src/beacon_chain.rs | 28 +++++- .../beacon_chain/src/execution_payload.rs | 1 + beacon_node/builder_client/src/lib.rs | 2 + beacon_node/execution_layer/src/lib.rs | 3 + beacon_node/http_api/src/lib.rs | 14 ++- beacon_node/http_api/src/validator.rs | 96 ++++++++++++++----- .../http_api/tests/interactive_tests.rs | 4 +- beacon_node/http_api/tests/tests.rs | 13 ++- common/eth2/src/lib.rs | 5 +- 9 files changed, 131 insertions(+), 35 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7a077019cd6..20f79ba776d 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4353,7 +4353,7 @@ impl BeaconChain { move || { chain.complete_partial_beacon_block_v3( partial_beacon_block, - block_contents, + Some(block_contents), verification, ) }, @@ -4373,7 +4373,7 @@ impl BeaconChain { move || { chain.complete_partial_beacon_block_v3( partial_beacon_block, - block_contents, + Some(block_contents), verification, ) }, @@ -4387,7 +4387,24 @@ impl BeaconChain { } } } else { - Err(BlockProductionError::FailedToFetchBlock) + let chain = self.clone(); + let beacon_block_and_state = self + .task_executor + .spawn_blocking_handle( + move || { + chain.complete_partial_beacon_block_v3( + partial_beacon_block, + None, + verification, + ) + }, + "complete_partial_beacon_block", + ) + .ok_or(BlockProductionError::ShuttingDown)? + .await + .map_err(BlockProductionError::TokioJoin)??; + + Ok(BeaconBlockAndStateResponse::Full(beacon_block_and_state)) } } @@ -4547,6 +4564,7 @@ impl BeaconChain { self.op_pool.get_slashings_and_exits(&state, &self.spec); let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; + let deposits = eth1_chain.deposits_for_block_inclusion(&state, ð1_data, &self.spec)?; let bls_to_execution_changes = self @@ -4957,7 +4975,7 @@ impl BeaconChain { fn complete_partial_beacon_block_v3>( &self, partial_beacon_block: PartialBeaconBlockV3, - block_contents: BlockProposalContents, + block_contents: Option>, verification: ProduceBlockVerification, ) -> Result, BlockProductionError> { let PartialBeaconBlockV3 { @@ -5035,6 +5053,7 @@ impl BeaconChain { sync_aggregate: sync_aggregate .ok_or(BlockProductionError::MissingSyncAggregate)?, execution_payload: block_contents + .ok_or(BlockProductionError::MissingExecutionPayload)? .to_payload() .try_into() .map_err(|_| BlockProductionError::InvalidPayloadFork)?, @@ -5057,6 +5076,7 @@ impl BeaconChain { sync_aggregate: sync_aggregate .ok_or(BlockProductionError::MissingSyncAggregate)?, execution_payload: block_contents + .ok_or(BlockProductionError::MissingExecutionPayload)? .to_payload() .try_into() .map_err(|_| BlockProductionError::InvalidPayloadFork)?, diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index d79cec7b749..65d1c90c183 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -618,6 +618,7 @@ where // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. // // This future is not executed here, it's up to the caller to await it. + println!("ATTEMPT TO FETCH PAYLOAD"); let block_contents = execution_layer .get_payload::( parent_hash, diff --git a/beacon_node/builder_client/src/lib.rs b/beacon_node/builder_client/src/lib.rs index c78f686d02b..24c31aa70e3 100644 --- a/beacon_node/builder_client/src/lib.rs +++ b/beacon_node/builder_client/src/lib.rs @@ -125,6 +125,8 @@ impl BuilderHttpClient { ) -> Result<(), Error> { let mut path = self.server.full.clone(); + println!("post_builder_validators"); + path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? .push("eth") diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index a6a0abe8a13..75c8ea9ee18 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -738,6 +738,7 @@ impl ExecutionLayer { ) -> Result, Error> { let payload_result = match Payload::block_type() { BlockType::Blinded => { + println!("BLOCK TYPE IS BLINDED"); let _timer = metrics::start_timer_vec( &metrics::EXECUTION_LAYER_REQUEST_TIMES, &[metrics::GET_BLINDED_PAYLOAD], @@ -753,6 +754,7 @@ impl ExecutionLayer { .await } BlockType::Full => { + println!("BLOCK TYPE IS FULL"); let _timer = metrics::start_timer_vec( &metrics::EXECUTION_LAYER_REQUEST_TIMES, &[metrics::GET_PAYLOAD], @@ -1092,6 +1094,7 @@ impl ExecutionLayer { current_fork: ForkName, spec: &ChainSpec, ) -> Result>, Error> { + println!("BLINDED"); if let Some(builder) = self.builder() { let slot = builder_params.slot; let pubkey = builder_params.pubkey; diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 0117278c137..57593316ca1 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3516,6 +3516,8 @@ pub fn serve( chain: Arc>, log: Logger, register_val_data: Vec| async { + + println!("post_validator_register_validator"); let (tx, rx) = oneshot::channel(); let initial_result = task_spawner @@ -3532,12 +3534,16 @@ pub fn serve( .map_err(warp_utils::reject::beacon_chain_error)?; let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch()); + println!("post_validator_register_validator 1"); + debug!( log, "Received register validator request"; "count" => register_val_data.len(), ); + println!("post_validator_register_validator 2"); + let head_snapshot = chain.head_snapshot(); let spec = &chain.spec; @@ -3609,6 +3615,8 @@ pub fn serve( "count" => filtered_registration_data.len(), ); + println!("yo 1"); + // It's a waste of a `BeaconProcessor` worker to just // wait on a response from the builder (especially since // they have frequent timeouts). Spawn a new task and @@ -3624,7 +3632,7 @@ pub fn serve( .as_ref() .ok_or(BeaconChainError::BuilderMissing) .map_err(warp_utils::reject::beacon_chain_error)?; - + println!("yo 2"); builder .post_builder_validators(&filtered_registration_data) .await @@ -3639,6 +3647,7 @@ pub fn serve( // Forward the HTTP status code if we are able to, otherwise fall back // to a server error. if let eth2::Error::ServerMessage(message) = e { + println!("SERVER MESSAGE 1"); if message.code == StatusCode::BAD_REQUEST.as_u16() { return warp_utils::reject::custom_bad_request( message.message, @@ -3651,6 +3660,7 @@ pub fn serve( ); } } + println!("SERVER MESSAGE 2"); warp_utils::reject::custom_server_error(format!("{e:?}")) }) }; @@ -3663,6 +3673,8 @@ pub fn serve( }) .await; + println!("{:?}", initial_result); + if initial_result.is_err() { return task_spawner::convert_rejection(initial_result).await; } diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index ef982f8c110..2c56a60cd2e 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -6,7 +6,9 @@ use beacon_chain::{ BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, }; -use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; +use eth2::types::{ + self as api_types, EndpointVersion, SkipRandaoVerification, ValidatorBlocksQuery, +}; use ssz::Encode; use warp::{ hyper::{Body, Response}, @@ -54,6 +56,51 @@ pub fn get_randao_verification( Ok(randao_verification) } +pub async fn produce_blinded_block_v2( + endpoint_version: EndpointVersion, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + let randao_reveal = query.randao_reveal.decompress().map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "randao reveal is not a valid BLS signature: {:?}", + e + )) + })?; + + let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + let block_response = chain + .determine_and_produce_block_with_verification( + randao_reveal, + slot, + query.graffiti.map(Into::into), + randao_verification, + BlockProductionVersion::FullV2, + ) + .await + .map_err(warp_utils::reject::block_production_error)?; + + match block_response { + BeaconBlockAndStateResponse::Full((_, _)) => { + println!("We shouldnt ever make it in here"); + Err(warp_utils::reject::custom_server_error( + "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() + )) + } + BeaconBlockAndStateResponse::Blinded((block, _)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + } + } +} + pub async fn produce_block_v2( endpoint_version: EndpointVersion, chain: Arc>, @@ -92,6 +139,7 @@ pub async fn produce_block_v2( .map(|res| add_consensus_version_header(res, fork_name)) } BeaconBlockAndStateResponse::Blinded((_, _)) => { + println!("We shouldnt ever make it in here"); Err(warp_utils::reject::custom_server_error( "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() )) @@ -148,30 +196,10 @@ pub async fn determine_and_produce_block_json( match block_response { BeaconBlockAndStateResponse::Full((block, _)) => { - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, false)) - .map(|res: Response| add_execution_payload_value_header(res, 0)) - // TODO + generate_json_response_v3(chain, block, endpoint_version, false) } BeaconBlockAndStateResponse::Blinded((block, _)) => { - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, true)) - .map(|res: Response| add_execution_payload_value_header(res, 0)) - // TODO + generate_json_response_v3(chain, block, endpoint_version, true) } } } @@ -232,3 +260,25 @@ pub async fn determine_and_produce_block_ssz( warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) }) } + +pub fn generate_json_response_v3< + T: BeaconChainTypes, + E: EthSpec, + Payload: AbstractExecPayload, +>( + chain: Arc>, + block: BeaconBlock, + endpoint_version: EndpointVersion, + blinded_payload_flag: bool, +) -> Result, warp::Rejection> { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, blinded_payload_flag)) + .map(|res: Response| add_execution_payload_value_header(res, 0)) +} diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index 0c51da5110b..1c63b53567a 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -624,7 +624,7 @@ pub async fn proposer_boost_re_org_test( .get_validator_blocks_v3::(slot_c, &randao_reveal, None) .await .unwrap(); - + /* let block_c = match unsigned_block_type { Full(unsigned_block_c) => { println!("full"); @@ -723,7 +723,7 @@ pub async fn proposer_boost_re_org_test( payload_attribs.timestamp(), payload_attribs.prev_randao(), ); - } + }*/ } // Test that running fork choice before proposing results in selection of the correct head. diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index adaf1a0f2d4..559370d0a27 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -3038,6 +3038,8 @@ impl ApiTester { .await .unwrap(); + println!("MADE IT FAR"); + for (val_index, (_, fee_recipient)) in self .chain .head_snapshot() @@ -3413,6 +3415,8 @@ impl ApiTester { .parse::() .unwrap(); + println!("test1"); + // Mutate prev randao. self.mock_builder .as_ref() @@ -3420,6 +3424,8 @@ impl ApiTester { .builder .add_operation(Operation::PrevRandao(invalid_prev_randao)); + println!("test2"); + let slot = self.chain.slot().unwrap(); let epoch = self.chain.epoch().unwrap(); let expected_prev_randao = self @@ -3428,9 +3434,12 @@ impl ApiTester { .cached_head() .head_random() .unwrap(); - + println!("test3"); let (_, randao_reveal) = self.get_test_randao(slot, epoch).await; + + println!("test4"); + let payload: BlindedPayload = self .client .get_validator_blinded_blocks::>(slot, &randao_reveal, None) @@ -3442,6 +3451,8 @@ impl ApiTester { .unwrap() .into(); + println!("{:?}", payload); + assert_eq!(payload.prev_randao(), expected_prev_randao); // If this cache is populated, it indicates fallback to the local EE was correctly used. diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index d544b3a3e5e..b060bae4106 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1678,12 +1678,8 @@ impl BeaconNodeHttpClient { .append_pair("skip_randao_verification", ""); } - println!("before"); - let response = self.get_response(path, |b| b).await?; - println!("after"); - if let Some(header_value) = response.headers().get(EXECUTION_PAYLOAD_BLINDED_HEADER) { if header_value.eq("true") { let blinded_payload = response @@ -1706,6 +1702,7 @@ impl BeaconNodeHttpClient { randao_reveal: &SignatureBytes, graffiti: Option<&Graffiti>, ) -> Result>, Error> { + println!("GET VALIDATOR BLINDED BLOCKS"); self.get_validator_blinded_blocks_modular( slot, randao_reveal, From 682eb619ea9380bab7196f1a0ae825bf981004e1 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 01:03:54 +0300 Subject: [PATCH 13/62] tests passing --- Cargo.lock | 452 +++++++++++++++++++++++++++-------------------------- 1 file changed, 230 insertions(+), 222 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad7b6fe14ce..8c7ae84cb35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -328,7 +328,7 @@ checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", ] [[package]] @@ -339,7 +339,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -350,7 +350,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -374,7 +374,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", ] [[package]] @@ -446,7 +446,7 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "rustversion", "serde", "serde_json", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -517,9 +517,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64ct" @@ -959,9 +959,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", "libc", @@ -1009,14 +1009,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets 0.48.5", ] [[package]] @@ -1387,11 +1387,11 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ - "nix 0.26.2", + "nix 0.27.1", "windows-sys 0.48.0", ] @@ -1419,7 +1419,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms 3.0.2", + "platforms 3.1.2", "rustc_version", "subtle", "zeroize", @@ -1433,7 +1433,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1602,9 +1602,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" [[package]] name = "derivative" @@ -1625,7 +1625,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1643,9 +1643,9 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7a532c1f99a0f596f6960a60d1e119e91582b24b39e2d83a190e61262c3ef0c" +checksum = "d98235fdc2f355d330a8244184ab6b4b33c28679c0b4158f63138e51d6cf7e88" dependencies = [ "bitflags 2.4.0", "byteorder", @@ -1657,14 +1657,14 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74398b79d81e52e130d991afeed9c86034bb1b7735f46d2f5bf7deb261d80303" +checksum = "e054665eaf6d97d1e7125512bb2d35d07c73ac86cc6920174cb42d1ab697a554" dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1684,7 +1684,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1799,7 +1799,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -1943,9 +1943,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -1975,7 +1975,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "ed25519-dalek", "hex", @@ -2054,9 +2054,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -2726,6 +2726,12 @@ dependencies = [ "windows-acl", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "fixed-hash" version = "0.7.0" @@ -2889,7 +2895,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "waker-fn", ] @@ -2901,7 +2907,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -2911,7 +2917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" dependencies = [ "futures-io", - "rustls 0.21.6", + "rustls 0.21.7", ] [[package]] @@ -2956,7 +2962,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "pin-utils", "slab", ] @@ -3040,9 +3046,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "git-version" @@ -3096,9 +3102,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -3191,21 +3197,20 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ "hashbrown 0.14.0", ] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.3", "bytes", "headers-core", "http", @@ -3335,7 +3340,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", ] [[package]] @@ -3441,7 +3446,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "socket2 0.4.9", "tokio", "tower-service", @@ -3458,7 +3463,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.6", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -3604,7 +3609,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.4", + "parity-scale-codec 3.6.5", ] [[package]] @@ -3730,7 +3735,7 @@ dependencies = [ "socket2 0.5.3", "widestring 1.0.2", "windows-sys 0.48.0", - "winreg 0.50.0", + "winreg", ] [[package]] @@ -3809,7 +3814,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "pem", "ring", "serde", @@ -4101,7 +4106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d157562dba6017193e5285acf6b1054759e83540bfd79f75b69d6ce774c88da" dependencies = [ "asynchronous-codec", - "base64 0.21.2", + "base64 0.21.3", "byteorder", "bytes", "either", @@ -4284,7 +4289,7 @@ dependencies = [ "parking_lot 0.12.1", "quinn", "rand 0.8.5", - "rustls 0.21.6", + "rustls 0.21.7", "socket2 0.5.3", "thiserror", "tokio", @@ -4323,7 +4328,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -4355,7 +4360,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-webpki", "thiserror", "x509-parser", @@ -4787,9 +4792,9 @@ checksum = "8c408dc227d302f1496c84d9dc68c00fec6f56f9228a18f3023f976f3ca7c945" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "memoffset" @@ -5240,14 +5245,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "libc", - "static_assertions", ] [[package]] @@ -5309,9 +5313,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg 1.1.0", "num-integer", @@ -5388,9 +5392,9 @@ dependencies = [ [[package]] name = "object" -version = "0.31.1" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -5456,11 +5460,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -5477,7 +5481,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -5488,18 +5492,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.27.0+1.1.1v" +version = "300.1.3+3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" +checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -5566,15 +5570,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.4", + "parity-scale-codec-derive 3.6.5", "serde", ] @@ -5592,9 +5596,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.4" +version = "3.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5653,7 +5657,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec 1.11.0", - "windows-targets 0.48.3", + "windows-targets 0.48.5", ] [[package]] @@ -5778,7 +5782,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -5789,9 +5793,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -5833,9 +5837,9 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "platforms" -version = "3.0.2" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" [[package]] name = "plotters" @@ -5877,7 +5881,7 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "windows-sys 0.48.0", ] @@ -5906,11 +5910,11 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" +checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "byteorder", "bytes", "fallible-iterator", @@ -5924,9 +5928,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" +checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" dependencies = [ "bytes", "fallible-iterator", @@ -6034,13 +6038,13 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro-warning" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" +checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -6102,7 +6106,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -6214,11 +6218,11 @@ checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" dependencies = [ "bytes", "futures-io", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.6", + "rustls 0.21.7", "thiserror", "tokio", "tracing", @@ -6234,7 +6238,7 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash", - "rustls 0.21.6", + "rustls 0.21.7", "slab", "thiserror", "tinyvec", @@ -6441,14 +6445,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.6", - "regex-syntax 0.7.4", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", ] [[package]] @@ -6462,13 +6466,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.4", + "regex-syntax 0.7.5", ] [[package]] @@ -6479,17 +6483,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "encoding_rs", "futures-core", @@ -6507,8 +6511,8 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.12", - "rustls 0.21.6", + "pin-project-lite 0.2.13", + "rustls 0.21.7", "rustls-pemfile", "serde", "serde_json", @@ -6523,8 +6527,8 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.22.6", - "winreg 0.10.1", + "webpki-roots 0.25.2", + "winreg", ] [[package]] @@ -6634,7 +6638,7 @@ dependencies = [ "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", - "hashlink 0.8.3", + "hashlink 0.8.4", "libsqlite3-sys", "smallvec 1.11.0", ] @@ -6705,9 +6709,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.8" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ "bitflags 2.4.0", "errno", @@ -6718,9 +6722,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring", @@ -6730,9 +6734,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -6746,7 +6750,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", ] [[package]] @@ -6812,7 +6816,7 @@ checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.6.4", + "parity-scale-codec 3.6.5", "scale-info-derive", ] @@ -6956,9 +6960,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] @@ -6996,13 +7000,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -7034,7 +7038,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -7249,15 +7253,15 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg 1.1.0", ] @@ -7339,9 +7343,9 @@ checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" [[package]] name = "slog-async" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "766c59b252e62a34651412870ff55d8c4e6d04df19b43eecb2703e417b097ffe" +checksum = "72c8038f898a2c79507940990f05386455b3a317d8f18d4caea7cbc3d5096b84" dependencies = [ "crossbeam-channel", "slog", @@ -7660,10 +7664,11 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -7758,9 +7763,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.29" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", @@ -7874,14 +7879,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand 2.0.0", "redox_syscall 0.3.5", - "rustix 0.38.8", + "rustix 0.38.11", "windows-sys 0.48.0", ] @@ -7948,22 +7953,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -7987,9 +7992,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -8008,9 +8013,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -8091,7 +8096,7 @@ dependencies = [ "mio", "num_cpus", "parking_lot 0.12.1", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "signal-hook-registry", "socket2 0.5.3", "tokio-macros", @@ -8104,7 +8109,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "tokio", ] @@ -8116,7 +8121,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -8131,9 +8136,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" +checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" dependencies = [ "async-trait", "byteorder", @@ -8145,12 +8150,14 @@ dependencies = [ "parking_lot 0.12.1", "percent-encoding", "phf", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "postgres-protocol", "postgres-types", + "rand 0.8.5", "socket2 0.5.3", "tokio", "tokio-util 0.7.8", + "whoami", ] [[package]] @@ -8159,7 +8166,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.8", + "rustls 0.20.9", "tokio", "webpki", ] @@ -8170,7 +8177,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.6", + "rustls 0.21.7", "tokio", ] @@ -8181,7 +8188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "tokio", "tokio-util 0.7.8", ] @@ -8194,7 +8201,7 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" dependencies = [ "futures-util", "log", - "rustls 0.20.8", + "rustls 0.20.9", "tokio", "tokio-rustls 0.23.4", "tungstenite 0.17.3", @@ -8225,7 +8232,7 @@ dependencies = [ "futures-io", "futures-sink", "log", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "slab", "tokio", ] @@ -8239,7 +8246,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "slab", "tokio", "tracing", @@ -8297,7 +8304,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "tokio", "tower-layer", "tower-service", @@ -8324,7 +8331,7 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", - "pin-project-lite 0.2.12", + "pin-project-lite 0.2.13", "tracing-attributes", "tracing-core", ] @@ -8337,7 +8344,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] @@ -8505,7 +8512,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.20.8", + "rustls 0.20.9", "sha-1 0.10.1", "thiserror", "url", @@ -8612,9 +8619,9 @@ checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" [[package]] name = "unicase" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" dependencies = [ "version_check", ] @@ -8699,9 +8706,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna 0.4.0", @@ -8960,7 +8967,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", "wasm-bindgen-shared", ] @@ -8994,7 +9001,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9007,9 +9014,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -9107,9 +9114,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" dependencies = [ "ring", "untrusted", @@ -9130,6 +9137,16 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + [[package]] name = "widestring" version = "0.4.3" @@ -9198,7 +9215,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.3", + "windows-targets 0.48.5", ] [[package]] @@ -9228,7 +9245,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.3", + "windows-targets 0.48.5", ] [[package]] @@ -9248,17 +9265,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.3", - "windows_aarch64_msvc 0.48.3", - "windows_i686_gnu 0.48.3", - "windows_i686_msvc 0.48.3", - "windows_x86_64_gnu 0.48.3", - "windows_x86_64_gnullvm 0.48.3", - "windows_x86_64_msvc 0.48.3", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -9269,9 +9286,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -9287,9 +9304,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -9305,9 +9322,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -9323,9 +9340,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -9341,9 +9358,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -9353,9 +9370,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -9371,28 +9388,19 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.3" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97" +checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winreg" version = "0.50.0" @@ -9467,9 +9475,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1" +checksum = "1eee6bf5926be7cf998d7381a9a23d833fd493f6a8034658a9505a4dc4b20444" [[package]] name = "xmltree" @@ -9530,7 +9538,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.29", + "syn 2.0.31", ] [[package]] From 03f442fd6648c23a0ba8e1c80859b5dfb7365c34 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 01:04:36 +0300 Subject: [PATCH 14/62] tests passing --- beacon_node/beacon_chain/src/execution_payload.rs | 1 - beacon_node/http_api/src/validator.rs | 2 -- beacon_node/http_api/tests/tests.rs | 13 ------------- common/eth2/src/lib.rs | 1 - 4 files changed, 17 deletions(-) diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 65d1c90c183..d79cec7b749 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -618,7 +618,6 @@ where // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. // // This future is not executed here, it's up to the caller to await it. - println!("ATTEMPT TO FETCH PAYLOAD"); let block_contents = execution_layer .get_payload::( parent_hash, diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 2c56a60cd2e..ccd8f03e44c 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -83,7 +83,6 @@ pub async fn produce_blinded_block_v2( match block_response { BeaconBlockAndStateResponse::Full((_, _)) => { - println!("We shouldnt ever make it in here"); Err(warp_utils::reject::custom_server_error( "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() )) @@ -139,7 +138,6 @@ pub async fn produce_block_v2( .map(|res| add_consensus_version_header(res, fork_name)) } BeaconBlockAndStateResponse::Blinded((_, _)) => { - println!("We shouldnt ever make it in here"); Err(warp_utils::reject::custom_server_error( "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() )) diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 559370d0a27..1e19b8da528 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -3038,8 +3038,6 @@ impl ApiTester { .await .unwrap(); - println!("MADE IT FAR"); - for (val_index, (_, fee_recipient)) in self .chain .head_snapshot() @@ -3415,8 +3413,6 @@ impl ApiTester { .parse::() .unwrap(); - println!("test1"); - // Mutate prev randao. self.mock_builder .as_ref() @@ -3424,8 +3420,6 @@ impl ApiTester { .builder .add_operation(Operation::PrevRandao(invalid_prev_randao)); - println!("test2"); - let slot = self.chain.slot().unwrap(); let epoch = self.chain.epoch().unwrap(); let expected_prev_randao = self @@ -3434,12 +3428,8 @@ impl ApiTester { .cached_head() .head_random() .unwrap(); - println!("test3"); let (_, randao_reveal) = self.get_test_randao(slot, epoch).await; - - println!("test4"); - let payload: BlindedPayload = self .client .get_validator_blinded_blocks::>(slot, &randao_reveal, None) @@ -3451,8 +3441,6 @@ impl ApiTester { .unwrap() .into(); - println!("{:?}", payload); - assert_eq!(payload.prev_randao(), expected_prev_randao); // If this cache is populated, it indicates fallback to the local EE was correctly used. @@ -4453,7 +4441,6 @@ impl ApiTester { assert_eq!(withdrawal_response.data, expected_withdrawals.to_vec()); } Err(e) => { - println!("{:?}", e); panic!("query failed incorrectly"); } } diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index b060bae4106..3a68ffa4d33 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1702,7 +1702,6 @@ impl BeaconNodeHttpClient { randao_reveal: &SignatureBytes, graffiti: Option<&Graffiti>, ) -> Result>, Error> { - println!("GET VALIDATOR BLINDED BLOCKS"); self.get_validator_blinded_blocks_modular( slot, randao_reveal, From 877973e204c901e9e1a146829c358f2f8f875a10 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 01:07:04 +0300 Subject: [PATCH 15/62] revert cargo lock --- Cargo.lock | 452 ++++++++++++++++++++++++++--------------------------- 1 file changed, 222 insertions(+), 230 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8c7ae84cb35..ad7b6fe14ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,9 +63,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.21.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -328,7 +328,7 @@ checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", ] [[package]] @@ -339,7 +339,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -350,7 +350,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -374,7 +374,7 @@ dependencies = [ "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", ] [[package]] @@ -446,7 +446,7 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "rustversion", "serde", "serde_json", @@ -478,9 +478,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", @@ -517,9 +517,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.3" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] name = "base64ct" @@ -959,9 +959,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" dependencies = [ "jobserver", "libc", @@ -1009,14 +1009,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.28" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ed24df0632f708f5f6d8082675bef2596f7084dee3dd55f632290bf35bfe0f" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.48.5", + "winapi", ] [[package]] @@ -1387,11 +1387,11 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ - "nix 0.27.1", + "nix 0.26.2", "windows-sys 0.48.0", ] @@ -1419,7 +1419,7 @@ dependencies = [ "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms 3.1.2", + "platforms 3.0.2", "rustc_version", "subtle", "zeroize", @@ -1433,7 +1433,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -1602,9 +1602,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" [[package]] name = "derivative" @@ -1625,7 +1625,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -1643,9 +1643,9 @@ dependencies = [ [[package]] name = "diesel" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98235fdc2f355d330a8244184ab6b4b33c28679c0b4158f63138e51d6cf7e88" +checksum = "f7a532c1f99a0f596f6960a60d1e119e91582b24b39e2d83a190e61262c3ef0c" dependencies = [ "bitflags 2.4.0", "byteorder", @@ -1657,14 +1657,14 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e054665eaf6d97d1e7125512bb2d35d07c73ac86cc6920174cb42d1ab697a554" +checksum = "74398b79d81e52e130d991afeed9c86034bb1b7735f46d2f5bf7deb261d80303" dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -1684,7 +1684,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -1799,7 +1799,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -1943,9 +1943,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] @@ -1975,7 +1975,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0be7b2ac146c1f99fe245c02d16af0696450d8e06c135db75e10eeb9e642c20d" dependencies = [ - "base64 0.21.3", + "base64 0.21.2", "bytes", "ed25519-dalek", "hex", @@ -2054,9 +2054,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -2726,12 +2726,6 @@ dependencies = [ "windows-acl", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "fixed-hash" version = "0.7.0" @@ -2895,7 +2889,7 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "waker-fn", ] @@ -2907,7 +2901,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -2917,7 +2911,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" dependencies = [ "futures-io", - "rustls 0.21.7", + "rustls 0.21.6", ] [[package]] @@ -2962,7 +2956,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "pin-utils", "slab", ] @@ -3046,9 +3040,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "git-version" @@ -3102,9 +3096,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -3197,20 +3191,21 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" dependencies = [ "hashbrown 0.14.0", ] [[package]] name = "headers" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64 0.21.3", + "base64 0.13.1", + "bitflags 1.3.2", "bytes", "headers-core", "http", @@ -3340,7 +3335,7 @@ checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", ] [[package]] @@ -3446,7 +3441,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "socket2 0.4.9", "tokio", "tower-service", @@ -3463,7 +3458,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.7", + "rustls 0.21.6", "tokio", "tokio-rustls 0.24.1", ] @@ -3609,7 +3604,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.4", ] [[package]] @@ -3735,7 +3730,7 @@ dependencies = [ "socket2 0.5.3", "widestring 1.0.2", "windows-sys 0.48.0", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -3814,7 +3809,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.3", + "base64 0.21.2", "pem", "ring", "serde", @@ -4106,7 +4101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d157562dba6017193e5285acf6b1054759e83540bfd79f75b69d6ce774c88da" dependencies = [ "asynchronous-codec", - "base64 0.21.3", + "base64 0.21.2", "byteorder", "bytes", "either", @@ -4289,7 +4284,7 @@ dependencies = [ "parking_lot 0.12.1", "quinn", "rand 0.8.5", - "rustls 0.21.7", + "rustls 0.21.6", "socket2 0.5.3", "thiserror", "tokio", @@ -4328,7 +4323,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -4360,7 +4355,7 @@ dependencies = [ "libp2p-identity", "rcgen", "ring", - "rustls 0.21.7", + "rustls 0.21.6", "rustls-webpki", "thiserror", "x509-parser", @@ -4792,9 +4787,9 @@ checksum = "8c408dc227d302f1496c84d9dc68c00fec6f56f9228a18f3023f976f3ca7c945" [[package]] name = "memchr" -version = "2.6.3" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -5245,13 +5240,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.27.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags 2.4.0", + "bitflags 1.3.2", "cfg-if", "libc", + "static_assertions", ] [[package]] @@ -5313,9 +5309,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg 1.1.0", "num-integer", @@ -5392,9 +5388,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -5460,11 +5456,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ - "bitflags 2.4.0", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -5481,7 +5477,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -5492,18 +5488,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.3+3.1.2" +version = "111.27.0+1.1.1v" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107" +checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", @@ -5570,15 +5566,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.5", + "parity-scale-codec-derive 3.6.4", "serde", ] @@ -5596,9 +5592,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -5657,7 +5653,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec 1.11.0", - "windows-targets 0.48.5", + "windows-targets 0.48.3", ] [[package]] @@ -5782,7 +5778,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -5793,9 +5789,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -5837,9 +5833,9 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "platforms" -version = "3.1.2" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" [[package]] name = "plotters" @@ -5881,7 +5877,7 @@ dependencies = [ "concurrent-queue", "libc", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "windows-sys 0.48.0", ] @@ -5910,11 +5906,11 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d" dependencies = [ - "base64 0.21.3", + "base64 0.21.2", "byteorder", "bytes", "fallible-iterator", @@ -5928,9 +5924,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "f028f05971fe20f512bcc679e2c10227e57809a3af86a7606304435bc8896cd6" dependencies = [ "bytes", "fallible-iterator", @@ -6038,13 +6034,13 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro-warning" -version = "0.4.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" +checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -6106,7 +6102,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -6218,11 +6214,11 @@ checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" dependencies = [ "bytes", "futures-io", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.6", "thiserror", "tokio", "tracing", @@ -6238,7 +6234,7 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.6", "slab", "thiserror", "tinyvec", @@ -6445,14 +6441,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.5" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.8", - "regex-syntax 0.7.5", + "regex-automata 0.3.6", + "regex-syntax 0.7.4", ] [[package]] @@ -6466,13 +6462,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.5", + "regex-syntax 0.7.4", ] [[package]] @@ -6483,17 +6479,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.3", + "base64 0.21.2", "bytes", "encoding_rs", "futures-core", @@ -6511,8 +6507,8 @@ dependencies = [ "native-tls", "once_cell", "percent-encoding", - "pin-project-lite 0.2.13", - "rustls 0.21.7", + "pin-project-lite 0.2.12", + "rustls 0.21.6", "rustls-pemfile", "serde", "serde_json", @@ -6527,8 +6523,8 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.25.2", - "winreg", + "webpki-roots 0.22.6", + "winreg 0.10.1", ] [[package]] @@ -6638,7 +6634,7 @@ dependencies = [ "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", - "hashlink 0.8.4", + "hashlink 0.8.3", "libsqlite3-sys", "smallvec 1.11.0", ] @@ -6709,9 +6705,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.11" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ "bitflags 2.4.0", "errno", @@ -6722,9 +6718,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.9" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", @@ -6734,9 +6730,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", @@ -6750,7 +6746,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.3", + "base64 0.21.2", ] [[package]] @@ -6816,7 +6812,7 @@ checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.4", "scale-info-derive", ] @@ -6960,9 +6956,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] @@ -7000,13 +6996,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -7038,7 +7034,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -7253,15 +7249,15 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.11" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "slab" -version = "0.4.9" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg 1.1.0", ] @@ -7343,9 +7339,9 @@ checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" [[package]] name = "slog-async" -version = "2.8.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c8038f898a2c79507940990f05386455b3a317d8f18d4caea7cbc3d5096b84" +checksum = "766c59b252e62a34651412870ff55d8c4e6d04df19b43eecb2703e417b097ffe" dependencies = [ "crossbeam-channel", "slog", @@ -7664,11 +7660,10 @@ dependencies = [ [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "db3737bde7edce97102e0e2b15365bf7a20bfdb5f60f4f9e8d7004258a51a8da" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -7763,9 +7758,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.31" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -7879,14 +7874,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ "cfg-if", "fastrand 2.0.0", "redox_syscall 0.3.5", - "rustix 0.38.11", + "rustix 0.38.8", "windows-sys 0.48.0", ] @@ -7953,22 +7948,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -7992,9 +7987,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ "deranged", "itoa", @@ -8013,9 +8008,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -8096,7 +8091,7 @@ dependencies = [ "mio", "num_cpus", "parking_lot 0.12.1", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "signal-hook-registry", "socket2 0.5.3", "tokio-macros", @@ -8109,7 +8104,7 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", ] @@ -8121,7 +8116,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -8136,9 +8131,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1" dependencies = [ "async-trait", "byteorder", @@ -8150,14 +8145,12 @@ dependencies = [ "parking_lot 0.12.1", "percent-encoding", "phf", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "postgres-protocol", "postgres-types", - "rand 0.8.5", "socket2 0.5.3", "tokio", "tokio-util 0.7.8", - "whoami", ] [[package]] @@ -8166,7 +8159,7 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.9", + "rustls 0.20.8", "tokio", "webpki", ] @@ -8177,7 +8170,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.6", "tokio", ] @@ -8188,7 +8181,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tokio-util 0.7.8", ] @@ -8201,7 +8194,7 @@ checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" dependencies = [ "futures-util", "log", - "rustls 0.20.9", + "rustls 0.20.8", "tokio", "tokio-rustls 0.23.4", "tungstenite 0.17.3", @@ -8232,7 +8225,7 @@ dependencies = [ "futures-io", "futures-sink", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "slab", "tokio", ] @@ -8246,7 +8239,7 @@ dependencies = [ "bytes", "futures-core", "futures-sink", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "slab", "tokio", "tracing", @@ -8304,7 +8297,7 @@ dependencies = [ "futures-core", "futures-util", "pin-project", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tokio", "tower-layer", "tower-service", @@ -8331,7 +8324,7 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.12", "tracing-attributes", "tracing-core", ] @@ -8344,7 +8337,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] @@ -8512,7 +8505,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.20.9", + "rustls 0.20.8", "sha-1 0.10.1", "thiserror", "url", @@ -8619,9 +8612,9 @@ checksum = "ccb97dac3243214f8d8507998906ca3e2e0b900bf9bf4870477f125b82e68f6e" [[package]] name = "unicase" -version = "2.7.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" dependencies = [ "version_check", ] @@ -8706,9 +8699,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", "idna 0.4.0", @@ -8967,7 +8960,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", "wasm-bindgen-shared", ] @@ -9001,7 +8994,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9014,9 +9007,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" dependencies = [ "futures-util", "js-sys", @@ -9114,9 +9107,9 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e74f82d49d545ad128049b7e88f6576df2da6b02e9ce565c6f533be576957e" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" dependencies = [ "ring", "untrusted", @@ -9137,16 +9130,6 @@ version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" -[[package]] -name = "whoami" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - [[package]] name = "widestring" version = "0.4.3" @@ -9215,7 +9198,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.48.3", ] [[package]] @@ -9245,7 +9228,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.48.3", ] [[package]] @@ -9265,17 +9248,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows_aarch64_gnullvm 0.48.3", + "windows_aarch64_msvc 0.48.3", + "windows_i686_gnu 0.48.3", + "windows_i686_msvc 0.48.3", + "windows_x86_64_gnu 0.48.3", + "windows_x86_64_gnullvm 0.48.3", + "windows_x86_64_msvc 0.48.3", ] [[package]] @@ -9286,9 +9269,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c" [[package]] name = "windows_aarch64_msvc" @@ -9304,9 +9287,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4" [[package]] name = "windows_i686_gnu" @@ -9322,9 +9305,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83" [[package]] name = "windows_i686_msvc" @@ -9340,9 +9323,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4" [[package]] name = "windows_x86_64_gnu" @@ -9358,9 +9341,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad" [[package]] name = "windows_x86_64_gnullvm" @@ -9370,9 +9353,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d" [[package]] name = "windows_x86_64_msvc" @@ -9388,19 +9371,28 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.48.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1" [[package]] name = "winnow" -version = "0.5.15" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97" dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "winreg" version = "0.50.0" @@ -9475,9 +9467,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.17" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eee6bf5926be7cf998d7381a9a23d833fd493f6a8034658a9505a4dc4b20444" +checksum = "47430998a7b5d499ccee752b41567bc3afc57e1327dc855b1a2aa44ce29b5fa1" [[package]] name = "xmltree" @@ -9538,7 +9530,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn 2.0.29", ] [[package]] From 5be31132df9597077fe192ddd13c7c6e99f79687 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 01:28:56 +0300 Subject: [PATCH 16/62] initial v3 test --- beacon_node/builder_client/src/lib.rs | 2 -- beacon_node/http_api/src/lib.rs | 13 ------------- beacon_node/http_api/tests/interactive_tests.rs | 8 +++----- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/beacon_node/builder_client/src/lib.rs b/beacon_node/builder_client/src/lib.rs index 24c31aa70e3..c78f686d02b 100644 --- a/beacon_node/builder_client/src/lib.rs +++ b/beacon_node/builder_client/src/lib.rs @@ -125,8 +125,6 @@ impl BuilderHttpClient { ) -> Result<(), Error> { let mut path = self.server.full.clone(); - println!("post_builder_validators"); - path.path_segments_mut() .map_err(|()| Error::InvalidUrl(self.server.clone()))? .push("eth") diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 57593316ca1..a6ff560ae60 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3516,8 +3516,6 @@ pub fn serve( chain: Arc>, log: Logger, register_val_data: Vec| async { - - println!("post_validator_register_validator"); let (tx, rx) = oneshot::channel(); let initial_result = task_spawner @@ -3534,16 +3532,12 @@ pub fn serve( .map_err(warp_utils::reject::beacon_chain_error)?; let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch()); - println!("post_validator_register_validator 1"); - debug!( log, "Received register validator request"; "count" => register_val_data.len(), ); - println!("post_validator_register_validator 2"); - let head_snapshot = chain.head_snapshot(); let spec = &chain.spec; @@ -3615,8 +3609,6 @@ pub fn serve( "count" => filtered_registration_data.len(), ); - println!("yo 1"); - // It's a waste of a `BeaconProcessor` worker to just // wait on a response from the builder (especially since // they have frequent timeouts). Spawn a new task and @@ -3632,7 +3624,6 @@ pub fn serve( .as_ref() .ok_or(BeaconChainError::BuilderMissing) .map_err(warp_utils::reject::beacon_chain_error)?; - println!("yo 2"); builder .post_builder_validators(&filtered_registration_data) .await @@ -3647,7 +3638,6 @@ pub fn serve( // Forward the HTTP status code if we are able to, otherwise fall back // to a server error. if let eth2::Error::ServerMessage(message) = e { - println!("SERVER MESSAGE 1"); if message.code == StatusCode::BAD_REQUEST.as_u16() { return warp_utils::reject::custom_bad_request( message.message, @@ -3660,7 +3650,6 @@ pub fn serve( ); } } - println!("SERVER MESSAGE 2"); warp_utils::reject::custom_server_error(format!("{e:?}")) }) }; @@ -3673,8 +3662,6 @@ pub fn serve( }) .await; - println!("{:?}", initial_result); - if initial_result.is_err() { return task_spawner::convert_rejection(initial_result).await; } diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index 1c63b53567a..fb112b0c4b8 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -624,15 +624,13 @@ pub async fn proposer_boost_re_org_test( .get_validator_blocks_v3::(slot_c, &randao_reveal, None) .await .unwrap(); - /* + let block_c = match unsigned_block_type { Full(unsigned_block_c) => { - println!("full"); harness.sign_beacon_block(unsigned_block_c.data, &state_b) } Blinded(unsigned_block_c) => { - println!("blinded"); - harness.sign_beacon_block(unsigned_block_c.data, &state_b) + panic!("Should not be a blinded block"); } }; // let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b); @@ -723,7 +721,7 @@ pub async fn proposer_boost_re_org_test( payload_attribs.timestamp(), payload_attribs.prev_randao(), ); - }*/ + } } // Test that running fork choice before proposing results in selection of the correct head. From ae2b1d3d85265ac475510abaf7d528ffdff2b837 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 18:27:35 +0300 Subject: [PATCH 17/62] blinded payload test case passing --- beacon_node/execution_layer/src/lib.rs | 285 ++++++++++++++++++++++++- beacon_node/http_api/src/lib.rs | 41 +--- beacon_node/http_api/src/validator.rs | 15 +- 3 files changed, 294 insertions(+), 47 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 75c8ea9ee18..b2546baef8c 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -655,7 +655,7 @@ impl ExecutionLayer { block_production_version: BlockProductionVersion, ) -> Result, Error> { let payload_result_type = match block_production_version { - BlockProductionVersion::V3 | BlockProductionVersion::BlindedV2 => match self + BlockProductionVersion::V3 => match self .determine_and_fetch_payload( parent_hash, payload_attributes, @@ -675,6 +675,21 @@ impl ExecutionLayer { return Err(e); } }, + BlockProductionVersion::BlindedV2 => { + let _timer = metrics::start_timer_vec( + &metrics::EXECUTION_LAYER_REQUEST_TIMES, + &[metrics::GET_BLINDED_PAYLOAD], + ); + self.get_blinded_payload_v2( + parent_hash, + payload_attributes, + forkchoice_update_params, + builder_params, + current_fork, + spec, + ) + .await? + }, BlockProductionVersion::FullV2 => self .get_full_payload_with_v3( parent_hash, @@ -738,7 +753,6 @@ impl ExecutionLayer { ) -> Result, Error> { let payload_result = match Payload::block_type() { BlockType::Blinded => { - println!("BLOCK TYPE IS BLINDED"); let _timer = metrics::start_timer_vec( &metrics::EXECUTION_LAYER_REQUEST_TIMES, &[metrics::GET_BLINDED_PAYLOAD], @@ -754,7 +768,6 @@ impl ExecutionLayer { .await } BlockType::Full => { - println!("BLOCK TYPE IS FULL"); let _timer = metrics::start_timer_vec( &metrics::EXECUTION_LAYER_REQUEST_TIMES, &[metrics::GET_PAYLOAD], @@ -1085,6 +1098,272 @@ impl ExecutionLayer { .map(ProvenancedPayload::Local) } + async fn get_blinded_payload_v2( + &self, + parent_hash: ExecutionBlockHash, + payload_attributes: &PayloadAttributes, + forkchoice_update_params: ForkchoiceUpdateParameters, + builder_params: BuilderParams, + current_fork: ForkName, + spec: &ChainSpec, + ) -> Result>, Error> { + if let Some(builder) = self.builder() { + let slot = builder_params.slot; + let pubkey = builder_params.pubkey; + + match builder_params.chain_health { + ChainHealth::Healthy => { + info!( + self.log(), + "Requesting blinded header from connected builder"; + "slot" => ?slot, + "pubkey" => ?pubkey, + "parent_hash" => ?parent_hash, + ); + + // Wait for the builder *and* local EL to produce a payload (or return an error). + let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( + timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { + builder + .get_builder_header::>(slot, parent_hash, &pubkey) + .await + }), + timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { + self.get_full_payload_caching::>( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await + }) + ); + + info!( + self.log(), + "Requested blinded execution payload"; + "relay_fee_recipient" => match &relay_result { + Ok(Some(r)) => format!("{:?}", r.data.message.header.fee_recipient()), + Ok(None) => "empty response".to_string(), + Err(_) => "request failed".to_string(), + }, + "relay_response_ms" => relay_duration.as_millis(), + "local_fee_recipient" => match &local_result { + Ok(proposal_contents) => format!("{:?}", proposal_contents.payload().fee_recipient()), + Err(_) => "request failed".to_string() + }, + "local_response_ms" => local_duration.as_millis(), + "parent_hash" => ?parent_hash, + ); + + return match (relay_result, local_result) { + (Err(e), Ok(local)) => { + warn!( + self.log(), + "Builder error when requesting payload"; + "info" => "falling back to local execution client", + "relay_error" => ?e, + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + } + (Ok(None), Ok(local)) => { + info!( + self.log(), + "Builder did not return a payload"; + "info" => "falling back to local execution client", + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + } + (Ok(Some(relay)), Ok(local)) => { + let header = &relay.data.message.header; + + info!( + self.log(), + "Received local and builder payloads"; + "relay_block_hash" => ?header.block_hash(), + "local_block_hash" => ?local.payload().block_hash(), + "parent_hash" => ?parent_hash, + ); + + let relay_value = relay.data.message.value; + let local_value = *local.block_value(); + if !self.inner.always_prefer_builder_payload { + if local_value >= relay_value { + info!( + self.log(), + "Local block is more profitable than relay block"; + "local_block_value" => %local_value, + "relay_value" => %relay_value + ); + return Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))); + } else { + info!( + self.log(), + "Relay block is more profitable than local block"; + "local_block_value" => %local_value, + "relay_value" => %relay_value + ); + } + } + + match verify_builder_bid( + &relay, + parent_hash, + payload_attributes, + Some(local.payload().block_number()), + self.inner.builder_profit_threshold, + current_fork, + spec, + ) { + Ok(()) => Ok(ProvenancedPayload::Builder( + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }), + )), + Err(reason) if !reason.payload_invalid() => { + info!( + self.log(), + "Builder payload ignored"; + "info" => "using local payload", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + } + Err(reason) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, + &[reason.as_ref().as_ref()], + ); + warn!( + self.log(), + "Builder returned invalid payload"; + "info" => "using local payload", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + } + } + } + (Ok(Some(relay)), Err(local_error)) => { + let header = &relay.data.message.header; + + info!( + self.log(), + "Received builder payload with local error"; + "relay_block_hash" => ?header.block_hash(), + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + match verify_builder_bid( + &relay, + parent_hash, + payload_attributes, + None, + self.inner.builder_profit_threshold, + current_fork, + spec, + ) { + Ok(()) => Ok(ProvenancedPayload::Builder( + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }), + )), + // If the payload is valid then use it. The local EE failed + // to produce a payload so we have no alternative. + Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( + BlockProposalContentsType::Blinded( + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }), + )), + Err(reason) => { + metrics::inc_counter_vec( + &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, + &[reason.as_ref().as_ref()], + ); + crit!( + self.log(), + "Builder returned invalid payload"; + "info" => "no local payload either - unable to propose block", + "reason" => %reason, + "relay_block_hash" => ?header.block_hash(), + "parent_hash" => ?parent_hash, + ); + Err(Error::CannotProduceHeader) + } + } + } + (Err(relay_error), Err(local_error)) => { + crit!( + self.log(), + "Unable to produce execution payload"; + "info" => "the local EL and builder both failed - unable to propose block", + "relay_error" => ?relay_error, + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + Err(Error::CannotProduceHeader) + } + (Ok(None), Err(local_error)) => { + crit!( + self.log(), + "Unable to produce execution payload"; + "info" => "the local EL failed and the builder returned nothing - \ + the block proposal will be missed", + "local_error" => ?local_error, + "parent_hash" => ?parent_hash, + ); + + Err(Error::CannotProduceHeader) + } + }; + } + ChainHealth::Unhealthy(condition) => info!( + self.log(), + "Chain is unhealthy, using local payload"; + "info" => "this helps protect the network. the --builder-fallback flags \ + can adjust the expected health conditions.", + "failed_condition" => ?condition + ), + // Intentional no-op, so we never attempt builder API proposals pre-merge. + ChainHealth::PreMerge => (), + ChainHealth::Optimistic => info!( + self.log(), + "Chain is optimistic; can't build payload"; + "info" => "the local execution engine is syncing and the builder network \ + cannot safely be used - unable to propose block" + ), + } + } + println!("YOOOO"); + let payload = self.get_full_payload_caching::>( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await?; + Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(payload))) + } + async fn get_blinded_payload>( &self, parent_hash: ExecutionBlockHash, diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index a6ff560ae60..4f0e30d92eb 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -26,7 +26,7 @@ mod validator; mod validator_inclusion; mod version; -use crate::validator::{produce_block_v2, produce_block_v3}; +use crate::validator::{produce_block_v2, produce_blinded_block_v2, produce_block_v3}; use beacon_chain::{ attestation_verification::VerifiedAttestation, observed_operations::ObservationOutcome, validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError, @@ -3060,44 +3060,7 @@ pub fn serve( task_spawner: TaskSpawner, chain: Arc>| { task_spawner.spawn_async_with_rejection(Priority::P0, async move { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = - if query.skip_randao_verification == SkipRandaoVerification::Yes { - if !randao_reveal.is_infinity() { - return Err(warp_utils::reject::custom_bad_request( - "randao_reveal must be point-at-infinity if verification is skipped" - .into() - )); - } - ProduceBlockVerification::NoVerification - } else { - ProduceBlockVerification::VerifyRandao - }; - - let (block, _) = chain - .produce_block_with_verification::>( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - ) - .await - .map_err(warp_utils::reject::block_production_error)?; - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - // Pose as a V2 endpoint so we return the fork `version`. - fork_versioned_response(V2, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) + produce_blinded_block_v2(EndpointVersion(2), chain, slot, query).await }) }, ); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index ccd8f03e44c..b45266a398d 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -76,16 +76,21 @@ pub async fn produce_blinded_block_v2( slot, query.graffiti.map(Into::into), randao_verification, - BlockProductionVersion::FullV2, + BlockProductionVersion::BlindedV2, ) .await .map_err(warp_utils::reject::block_production_error)?; match block_response { - BeaconBlockAndStateResponse::Full((_, _)) => { - Err(warp_utils::reject::custom_server_error( - "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() - )) + BeaconBlockAndStateResponse::Full((block, _)) => { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) } BeaconBlockAndStateResponse::Blinded((block, _)) => { let fork_name = block From 0edfcbd0e797167ed0ab4b619b2bc954c4fa39d7 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 23:20:06 +0300 Subject: [PATCH 18/62] fix clippy issues --- beacon_node/beacon_chain/src/beacon_chain.rs | 1 + beacon_node/beacon_chain/src/test_utils.rs | 54 +++++++++++-------- beacon_node/execution_layer/src/lib.rs | 1 + beacon_node/http_api/src/lib.rs | 8 +-- beacon_node/http_api/src/validator.rs | 2 +- .../http_api/tests/interactive_tests.rs | 2 +- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 20f79ba776d..60ff2608dd3 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4291,6 +4291,7 @@ impl BeaconChain { /// The provided `state_root_opt` should only ever be set to `Some` if the contained value is /// equal to the root of `state`. Providing this value will serve as an optimization to avoid /// performing a tree hash in some scenarios. + #[allow(clippy::too_many_arguments)] pub async fn determine_and_produce_block_on_state( self: &Arc, state: BeaconState, diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 5fc05c5551f..a1182132048 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -1,5 +1,6 @@ use crate::observed_operations::ObservationOutcome; pub use crate::persisted_beacon_chain::PersistedBeaconChain; +use crate::BeaconBlockAndStateResponse; pub use crate::{ beacon_chain::{BEACON_CHAIN_DB_KEY, ETH1_CACHE_DB_KEY, FORK_CHOICE_DB_KEY, OP_POOL_DB_KEY}, migrate::MigratorConfig, @@ -50,6 +51,7 @@ use std::time::Duration; use store::{config::StoreConfig, HotColdDB, ItemStore, LevelDB, MemoryStore}; use task_executor::{test_utils::TestRuntime, ShutdownReason}; use tree_hash::TreeHash; +use types::payload::BlockProductionVersion; use types::sync_selection_proof::SyncSelectionProof; pub use types::test_utils::generate_deterministic_keypairs; use types::{typenum::U4294967296, *}; @@ -770,27 +772,31 @@ where let randao_reveal = self.sign_randao_reveal(&state, proposer_index, slot); - let (block, state) = self + if let BeaconBlockAndStateResponse::Full((block, state)) = self .chain - .produce_block_on_state( + .determine_and_produce_block_on_state( state, None, slot, randao_reveal, Some(graffiti), ProduceBlockVerification::VerifyRandao, + BlockProductionVersion::FullV2, ) .await - .unwrap(); - - let signed_block = block.sign( - &self.validator_keypairs[proposer_index].sk, - &state.fork(), - state.genesis_validators_root(), - &self.spec, - ); + .unwrap() + { + let signed_block = block.sign( + &self.validator_keypairs[proposer_index].sk, + &state.fork(), + state.genesis_validators_root(), + &self.spec, + ); - (signed_block, state) + (signed_block, state) + } else { + panic!("Should always be a full payload response") + } } /// Useful for the `per_block_processing` tests. Creates a block, and returns the state after @@ -819,27 +825,31 @@ where let pre_state = state.clone(); - let (block, state) = self + if let BeaconBlockAndStateResponse::Full((block, state)) = self .chain - .produce_block_on_state( + .determine_and_produce_block_on_state( state, None, slot, randao_reveal, Some(graffiti), ProduceBlockVerification::VerifyRandao, + BlockProductionVersion::FullV2, ) .await - .unwrap(); - - let signed_block = block.sign( - &self.validator_keypairs[proposer_index].sk, - &state.fork(), - state.genesis_validators_root(), - &self.spec, - ); + .unwrap() + { + let signed_block = block.sign( + &self.validator_keypairs[proposer_index].sk, + &state.fork(), + state.genesis_validators_root(), + &self.spec, + ); - (signed_block, pre_state) + (signed_block, pre_state) + } else { + panic!("Should always be a full payload response"); + } } /// Create a randao reveal for a block at `slot`. diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index b2546baef8c..628949cd739 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -644,6 +644,7 @@ impl ExecutionLayer { /// /// The result will be returned from the first node that returns successfully. No more nodes /// will be contacted. + #[allow(clippy::too_many_arguments)] pub async fn determine_and_get_payload( &self, parent_hash: ExecutionBlockHash, diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 4f0e30d92eb..a756c5dd017 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -30,7 +30,7 @@ use crate::validator::{produce_block_v2, produce_blinded_block_v2, produce_block use beacon_chain::{ attestation_verification::VerifiedAttestation, observed_operations::ObservationOutcome, validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError, - BeaconChainTypes, ProduceBlockVerification, WhenSlotSkipped, + BeaconChainTypes, WhenSlotSkipped, }; use beacon_processor::BeaconProcessorSend; pub use block_id::BlockId; @@ -39,7 +39,7 @@ use bytes::Bytes; use directory::DEFAULT_ROOT_DIR; use eth2::types::{ self as api_types, BroadcastValidation, EndpointVersion, ForkChoice, ForkChoiceNode, - SkipRandaoVerification, ValidatorId, ValidatorStatus, + ValidatorId, ValidatorStatus, }; use lighthouse_network::{types::SyncState, EnrExt, NetworkGlobals, PeerId, PubsubMessage}; use lighthouse_version::version_with_platform; @@ -74,7 +74,7 @@ use tokio_stream::{ }; use types::{ Attestation, AttestationData, AttestationShufflingId, AttesterSlashing, BeaconStateError, - BlindedPayload, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, + CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, ProposerPreparationData, ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, SignedBeaconBlock, SignedBlindedBeaconBlock, SignedBlsToExecutionChange, SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, @@ -83,7 +83,7 @@ use types::{ use validator::pubkey_to_validator_index; use version::{ add_consensus_version_header, execution_optimistic_finalized_fork_versioned_response, - fork_versioned_response, inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, + inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, V3, }; use warp::http::StatusCode; diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index b45266a398d..1d6a001895f 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -7,7 +7,7 @@ use beacon_chain::{ ProduceBlockVerification, }; use eth2::types::{ - self as api_types, EndpointVersion, SkipRandaoVerification, ValidatorBlocksQuery, + self as api_types, EndpointVersion, SkipRandaoVerification, }; use ssz::Encode; use warp::{ diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index fb112b0c4b8..b2d990a8eb5 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -629,7 +629,7 @@ pub async fn proposer_boost_re_org_test( Full(unsigned_block_c) => { harness.sign_beacon_block(unsigned_block_c.data, &state_b) } - Blinded(unsigned_block_c) => { + Blinded(_) => { panic!("Should not be a blinded block"); } }; From 2599fecdc86cc318a1f0f7239e83aebc5dbf92c8 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 23:35:01 +0300 Subject: [PATCH 19/62] cleanup --- beacon_node/beacon_chain/src/beacon_chain.rs | 384 +------------------ beacon_node/beacon_chain/src/test_utils.rs | 4 +- beacon_node/http_api/src/validator.rs | 8 +- 3 files changed, 11 insertions(+), 385 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 60ff2608dd3..7c4c4c15501 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -3636,26 +3636,7 @@ impl BeaconChain { Ok(()) } - /// Produce a new block at the given `slot`. - /// - /// The produced block will not be inherently valid, it must be signed by a block producer. - /// Block signing is out of the scope of this function and should be done by a separate program. - pub async fn produce_block + 'static>( - self: &Arc, - randao_reveal: Signature, - slot: Slot, - validator_graffiti: Option, - ) -> Result, BlockProductionError> { - self.produce_block_with_verification( - randao_reveal, - slot, - validator_graffiti, - ProduceBlockVerification::VerifyRandao, - ) - .await - } - - pub async fn determine_and_produce_block_with_verification( + pub async fn produce_block_with_verification( self: &Arc, randao_reveal: Signature, slot: Slot, @@ -3680,7 +3661,7 @@ impl BeaconChain { // Part 2/2 (async, with some blocking components) // // Produce the block upon the state - self.determine_and_produce_block_on_state( + self.produce_block_on_state( state, state_root_opt, slot, @@ -3692,44 +3673,6 @@ impl BeaconChain { .await } - /// Same as `produce_block` but allowing for configuration of RANDAO-verification. - pub async fn produce_block_with_verification< - Payload: AbstractExecPayload + 'static, - >( - self: &Arc, - randao_reveal: Signature, - slot: Slot, - validator_graffiti: Option, - verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { - // Part 1/2 (blocking) - // - // Load the parent state from disk. - let chain = self.clone(); - let (state, state_root_opt) = self - .task_executor - .spawn_blocking_handle( - move || chain.load_state_for_block_production(slot), - "produce_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)??; - - // Part 2/2 (async, with some blocking components) - // - // Produce the block upon the state - self.produce_block_on_state::( - state, - state_root_opt, - slot, - randao_reveal, - validator_graffiti, - verification, - ) - .await - } - /// Load a beacon state from the database for block production. This is a long-running process /// that should not be performed in an `async` context. fn load_state_for_block_production( @@ -4292,7 +4235,7 @@ impl BeaconChain { /// equal to the root of `state`. Providing this value will serve as an optimization to avoid /// performing a tree hash in some scenarios. #[allow(clippy::too_many_arguments)] - pub async fn determine_and_produce_block_on_state( + pub async fn produce_block_on_state( self: &Arc, state: BeaconState, state_root_opt: Option, @@ -4312,7 +4255,7 @@ impl BeaconChain { .spawn_handle( async move { chain - .determine_and_produce_partial_beacon_block( + .produce_partial_beacon_block( state, state_root_opt, produce_at_slot, @@ -4409,85 +4352,7 @@ impl BeaconChain { } } - /// Produce a block for some `slot` upon the given `state`. - /// - /// Typically the `self.produce_block()` function should be used, instead of calling this - /// function directly. This function is useful for purposefully creating forks or blocks at - /// non-current slots. - /// - /// If required, the given state will be advanced to the given `produce_at_slot`, then a block - /// will be produced at that slot height. - /// - /// The provided `state_root_opt` should only ever be set to `Some` if the contained value is - /// equal to the root of `state`. Providing this value will serve as an optimization to avoid - /// performing a tree hash in some scenarios. - pub async fn produce_block_on_state + 'static>( - self: &Arc, - state: BeaconState, - state_root_opt: Option, - produce_at_slot: Slot, - randao_reveal: Signature, - validator_graffiti: Option, - verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { - // Part 1/3 (blocking) - // - // Perform the state advance and block-packing functions. - let chain = self.clone(); - let mut partial_beacon_block = self - .task_executor - .spawn_blocking_handle( - move || { - chain.produce_partial_beacon_block( - state, - state_root_opt, - produce_at_slot, - randao_reveal, - validator_graffiti, - ) - }, - "produce_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)??; - - // Part 2/3 (async) - // - // Wait for the execution layer to return an execution payload (if one is required). - let prepare_payload_handle = partial_beacon_block.prepare_payload_handle.take(); - let block_contents = if let Some(prepare_payload_handle) = prepare_payload_handle { - Some( - prepare_payload_handle - .await - .map_err(BlockProductionError::TokioJoin)? - .ok_or(BlockProductionError::ShuttingDown)??, - ) - } else { - None - }; - - // Part 3/3 (blocking) - // - // Perform the final steps of combining all the parts and computing the state root. - let chain = self.clone(); - self.task_executor - .spawn_blocking_handle( - move || { - chain.complete_partial_beacon_block( - partial_beacon_block, - block_contents, - verification, - ) - }, - "complete_partial_beacon_block", - ) - .ok_or(BlockProductionError::ShuttingDown)? - .await - .map_err(BlockProductionError::TokioJoin)? - } - - async fn determine_and_produce_partial_beacon_block( + async fn produce_partial_beacon_block( self: &Arc, mut state: BeaconState, state_root_opt: Option, @@ -4734,245 +4599,6 @@ impl BeaconChain { }) } - fn produce_partial_beacon_block + 'static>( - self: &Arc, - mut state: BeaconState, - state_root_opt: Option, - produce_at_slot: Slot, - randao_reveal: Signature, - validator_graffiti: Option, - ) -> Result, BlockProductionError> { - let eth1_chain = self - .eth1_chain - .as_ref() - .ok_or(BlockProductionError::NoEth1ChainConnection)?; - - // It is invalid to try to produce a block using a state from a future slot. - if state.slot() > produce_at_slot { - return Err(BlockProductionError::StateSlotTooHigh { - produce_at_slot, - state_slot: state.slot(), - }); - } - - let slot_timer = metrics::start_timer(&metrics::BLOCK_PRODUCTION_SLOT_PROCESS_TIMES); - - // Ensure the state has performed a complete transition into the required slot. - complete_state_advance(&mut state, state_root_opt, produce_at_slot, &self.spec)?; - - drop(slot_timer); - - state.build_committee_cache(RelativeEpoch::Current, &self.spec)?; - - let parent_root = if state.slot() > 0 { - *state - .get_block_root(state.slot() - 1) - .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)? - } else { - state.latest_block_header().canonical_root() - }; - - let proposer_index = state.get_beacon_proposer_index(state.slot(), &self.spec)? as u64; - - let pubkey = state - .validators() - .get(proposer_index as usize) - .map(|v| v.pubkey) - .ok_or(BlockProductionError::BeaconChain( - BeaconChainError::ValidatorIndexUnknown(proposer_index as usize), - ))?; - - let builder_params = BuilderParams { - pubkey, - slot: state.slot(), - chain_health: self - .is_healthy(&parent_root) - .map_err(BlockProductionError::BeaconChain)?, - }; - - // If required, start the process of loading an execution payload from the EL early. This - // allows it to run concurrently with things like attestation packing. - let prepare_payload_handle = match &state { - BeaconState::Base(_) | BeaconState::Altair(_) => None, - BeaconState::Merge(_) | BeaconState::Capella(_) => { - let prepare_payload_handle = - get_execution_payload(self.clone(), &state, proposer_index, builder_params)?; - Some(prepare_payload_handle) - } - }; - - let (mut proposer_slashings, mut attester_slashings, mut voluntary_exits) = - self.op_pool.get_slashings_and_exits(&state, &self.spec); - - let eth1_data = eth1_chain.eth1_data_for_block_production(&state, &self.spec)?; - let deposits = eth1_chain.deposits_for_block_inclusion(&state, ð1_data, &self.spec)?; - - let bls_to_execution_changes = self - .op_pool - .get_bls_to_execution_changes(&state, &self.spec); - - // Iterate through the naive aggregation pool and ensure all the attestations from there - // are included in the operation pool. - let unagg_import_timer = - metrics::start_timer(&metrics::BLOCK_PRODUCTION_UNAGGREGATED_TIMES); - for attestation in self.naive_aggregation_pool.read().iter() { - let import = |attestation: &Attestation| { - let attesting_indices = get_attesting_indices_from_state(&state, attestation)?; - self.op_pool - .insert_attestation(attestation.clone(), attesting_indices) - }; - if let Err(e) = import(attestation) { - // Don't stop block production if there's an error, just create a log. - error!( - self.log, - "Attestation did not transfer to op pool"; - "reason" => ?e - ); - } - } - drop(unagg_import_timer); - - // Override the beacon node's graffiti with graffiti from the validator, if present. - let graffiti = match validator_graffiti { - Some(graffiti) => graffiti, - None => self.graffiti, - }; - - let attestation_packing_timer = - metrics::start_timer(&metrics::BLOCK_PRODUCTION_ATTESTATION_TIMES); - - let mut prev_filter_cache = HashMap::new(); - let prev_attestation_filter = |att: &AttestationRef| { - self.filter_op_pool_attestation(&mut prev_filter_cache, att, &state) - }; - let mut curr_filter_cache = HashMap::new(); - let curr_attestation_filter = |att: &AttestationRef| { - self.filter_op_pool_attestation(&mut curr_filter_cache, att, &state) - }; - - let mut attestations = self - .op_pool - .get_attestations( - &state, - prev_attestation_filter, - curr_attestation_filter, - &self.spec, - ) - .map_err(BlockProductionError::OpPoolError)?; - drop(attestation_packing_timer); - - // If paranoid mode is enabled re-check the signatures of every included message. - // This will be a lot slower but guards against bugs in block production and can be - // quickly rolled out without a release. - if self.config.paranoid_block_proposal { - let mut tmp_ctxt = ConsensusContext::new(state.slot()); - attestations.retain(|att| { - verify_attestation_for_block_inclusion( - &state, - att, - &mut tmp_ctxt, - VerifySignatures::True, - &self.spec, - ) - .map_err(|e| { - warn!( - self.log, - "Attempted to include an invalid attestation"; - "err" => ?e, - "block_slot" => state.slot(), - "attestation" => ?att - ); - }) - .is_ok() - }); - - proposer_slashings.retain(|slashing| { - slashing - .clone() - .validate(&state, &self.spec) - .map_err(|e| { - warn!( - self.log, - "Attempted to include an invalid proposer slashing"; - "err" => ?e, - "block_slot" => state.slot(), - "slashing" => ?slashing - ); - }) - .is_ok() - }); - - attester_slashings.retain(|slashing| { - slashing - .clone() - .validate(&state, &self.spec) - .map_err(|e| { - warn!( - self.log, - "Attempted to include an invalid attester slashing"; - "err" => ?e, - "block_slot" => state.slot(), - "slashing" => ?slashing - ); - }) - .is_ok() - }); - - voluntary_exits.retain(|exit| { - exit.clone() - .validate(&state, &self.spec) - .map_err(|e| { - warn!( - self.log, - "Attempted to include an invalid proposer slashing"; - "err" => ?e, - "block_slot" => state.slot(), - "exit" => ?exit - ); - }) - .is_ok() - }); - } - - let slot = state.slot(); - - let sync_aggregate = if matches!(&state, BeaconState::Base(_)) { - None - } else { - let sync_aggregate = self - .op_pool - .get_sync_aggregate(&state) - .map_err(BlockProductionError::OpPoolError)? - .unwrap_or_else(|| { - warn!( - self.log, - "Producing block with no sync contributions"; - "slot" => state.slot(), - ); - SyncAggregate::new() - }); - Some(sync_aggregate) - }; - - Ok(PartialBeaconBlock { - state, - slot, - proposer_index, - parent_root, - randao_reveal, - eth1_data, - graffiti, - proposer_slashings, - attester_slashings, - attestations, - deposits, - voluntary_exits, - sync_aggregate, - prepare_payload_handle, - bls_to_execution_changes, - }) - } - fn complete_partial_beacon_block_v3>( &self, partial_beacon_block: PartialBeaconBlockV3, diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index a1182132048..522eb233f53 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -774,7 +774,7 @@ where if let BeaconBlockAndStateResponse::Full((block, state)) = self .chain - .determine_and_produce_block_on_state( + .produce_block_on_state( state, None, slot, @@ -827,7 +827,7 @@ where if let BeaconBlockAndStateResponse::Full((block, state)) = self .chain - .determine_and_produce_block_on_state( + .produce_block_on_state( state, None, slot, diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 1d6a001895f..8ad2f4aa6d0 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -71,7 +71,7 @@ pub async fn produce_blinded_block_v2( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; let block_response = chain - .determine_and_produce_block_with_verification( + .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), @@ -121,7 +121,7 @@ pub async fn produce_block_v2( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; let block_response = chain - .determine_and_produce_block_with_verification( + .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), @@ -185,7 +185,7 @@ pub async fn determine_and_produce_block_json( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; let block_response = chain - .determine_and_produce_block_with_verification( + .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), @@ -223,7 +223,7 @@ pub async fn determine_and_produce_block_ssz( // TODO: block value let (block_ssz, fork_name, block_value, blinded) = match chain - .determine_and_produce_block_with_verification( + .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), From 0f0c41e7d933927b0b68cfe46fe7d17c51e486aa Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 5 Sep 2023 23:46:25 +0300 Subject: [PATCH 20/62] cleanup --- beacon_node/beacon_chain/src/beacon_chain.rs | 212 +----------------- .../beacon_chain/src/execution_payload.rs | 71 +----- 2 files changed, 14 insertions(+), 269 deletions(-) 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. From f285d164bc0a115afed854e3f28ae39d8952723f Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 6 Sep 2023 00:27:39 +0300 Subject: [PATCH 21/62] remove dead code --- beacon_node/beacon_chain/src/beacon_chain.rs | 5 +- .../beacon_chain/src/execution_payload.rs | 124 +---- beacon_node/execution_layer/src/lib.rs | 449 ++---------------- beacon_node/execution_layer/src/metrics.rs | 1 - .../src/test_utils/mock_execution_layer.rs | 32 +- beacon_node/http_api/src/lib.rs | 15 +- beacon_node/http_api/src/validator.rs | 4 +- .../http_api/tests/interactive_tests.rs | 6 +- .../src/test_rig.rs | 35 +- 9 files changed, 112 insertions(+), 559 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index fb0d2bb4b66..be75dce38c7 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -20,10 +20,7 @@ use crate::errors::{BeaconChainError as Error, BlockProductionError}; use crate::eth1_chain::{Eth1Chain, Eth1ChainBackend}; use crate::eth1_finalization_cache::{Eth1FinalizationCache, Eth1FinalizationData}; use crate::events::ServerSentEventHandler; -use crate::execution_payload::{ - get_execution_payload, NotifyExecutionLayer, - PreparePayloadHandle, -}; +use crate::execution_payload::{get_execution_payload, NotifyExecutionLayer, PreparePayloadHandle}; use crate::fork_choice_signal::{ForkChoiceSignalRx, ForkChoiceSignalTx, ForkChoiceWaitResult}; use crate::head_tracker::HeadTracker; use crate::historical_blocks::HistoricalBlockError; diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index f3a8d978fca..f9b4568cf18 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -31,16 +31,8 @@ use tree_hash::TreeHash; use types::payload::BlockProductionVersion; use types::*; -pub type PreparePayloadResultV3 = Result, BlockProductionError>; -pub type PreparePayloadHandle = JoinHandle>>; - -pub enum PreparePayloadHandleType { - Full(JoinHandle>>>), - Blinded(JoinHandle>>>), -} - -pub type PreparePayloadResult = - Result, BlockProductionError>; +pub type PreparePayloadResult = Result, BlockProductionError>; +pub type PreparePayloadHandle = JoinHandle>>; #[derive(PartialEq)] pub enum AllowOptimisticImport { @@ -442,7 +434,7 @@ pub fn get_execution_payload( .clone() .spawn_handle( async move { - determine_and_prepare_execution_payload::( + prepare_execution_payload::( &chain, is_merge_transition_complete, timestamp, @@ -477,113 +469,7 @@ pub fn get_execution_payload( /// /// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal #[allow(clippy::too_many_arguments)] -pub async fn prepare_execution_payload( - chain: &Arc>, - is_merge_transition_complete: bool, - timestamp: u64, - random: Hash256, - proposer_index: u64, - latest_execution_payload_header_block_hash: ExecutionBlockHash, - builder_params: BuilderParams, - withdrawals: Option>, -) -> Result, BlockProductionError> -where - T: BeaconChainTypes, - Payload: AbstractExecPayload, -{ - let current_epoch = builder_params.slot.epoch(T::EthSpec::slots_per_epoch()); - let spec = &chain.spec; - let fork = spec.fork_name_at_slot::(builder_params.slot); - let execution_layer = chain - .execution_layer - .as_ref() - .ok_or(BlockProductionError::ExecutionLayerMissing)?; - - let parent_hash = if !is_merge_transition_complete { - let is_terminal_block_hash_set = spec.terminal_block_hash != ExecutionBlockHash::zero(); - let is_activation_epoch_reached = - current_epoch >= spec.terminal_block_hash_activation_epoch; - - if is_terminal_block_hash_set && !is_activation_epoch_reached { - // Use the "empty" payload if there's a terminal block hash, but we haven't reached the - // terminal block epoch yet. - return BlockProposalContents::default_at_fork(fork).map_err(Into::into); - } - - let terminal_pow_block_hash = execution_layer - .get_terminal_pow_block_hash(spec, timestamp) - .await - .map_err(BlockProductionError::TerminalPoWBlockLookupFailed)?; - - if let Some(terminal_pow_block_hash) = terminal_pow_block_hash { - terminal_pow_block_hash - } else { - // If the merge transition hasn't occurred yet and the EL hasn't found the terminal - // block, return an "empty" payload. - return BlockProposalContents::default_at_fork(fork).map_err(Into::into); - } - } else { - latest_execution_payload_header_block_hash - }; - - // Try to obtain the fork choice update parameters from the cached head. - // - // Use a blocking task to interact with the `canonical_head` lock otherwise we risk blocking the - // core `tokio` executor. - let inner_chain = chain.clone(); - let forkchoice_update_params = chain - .spawn_blocking_handle( - move || { - inner_chain - .canonical_head - .cached_head() - .forkchoice_update_parameters() - }, - "prepare_execution_payload_forkchoice_update_params", - ) - .await - .map_err(BlockProductionError::BeaconChain)?; - - let suggested_fee_recipient = execution_layer - .get_suggested_fee_recipient(proposer_index) - .await; - let payload_attributes = - PayloadAttributes::new(timestamp, random, suggested_fee_recipient, withdrawals); - - // Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. - // - // This future is not executed here, it's up to the caller to await it. - let block_contents = execution_layer - .get_payload::( - parent_hash, - &payload_attributes, - forkchoice_update_params, - builder_params, - fork, - &chain.spec, - ) - .await - .map_err(BlockProductionError::GetPayloadFailed)?; - - Ok(block_contents) -} - -/// 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. -/// -/// ## 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 `prepare_execution_payload` function in the Validator Guide: -/// -/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/validator.md#block-proposal -#[allow(clippy::too_many_arguments)] -pub async fn determine_and_prepare_execution_payload( +pub async fn prepare_execution_payload( chain: &Arc>, is_merge_transition_complete: bool, timestamp: u64, @@ -672,7 +558,7 @@ where // // This future is not executed here, it's up to the caller to await it. let block_contents = execution_layer - .determine_and_get_payload( + .get_payload( parent_hash, &payload_attributes, forkchoice_update_params, diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 628949cd739..14658f53fcf 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -41,7 +41,7 @@ use tree_hash::TreeHash; use types::payload::BlockProductionVersion; use types::{AbstractExecPayload, BeaconStateError, ExecPayload, FullPayload}; use types::{ - BlindedPayload, BlockType, ChainSpec, Epoch, ExecutionPayloadCapella, ExecutionPayloadMerge, + BlindedPayload, ChainSpec, Epoch, ExecutionPayloadCapella, ExecutionPayloadMerge, ForkVersionedResponse, ProposerPreparationData, PublicKeyBytes, Signature, SignedBeaconBlock, Slot, }; @@ -645,7 +645,7 @@ impl ExecutionLayer { /// The result will be returned from the first node that returns successfully. No more nodes /// will be contacted. #[allow(clippy::too_many_arguments)] - pub async fn determine_and_get_payload( + pub async fn get_payload( &self, parent_hash: ExecutionBlockHash, payload_attributes: &PayloadAttributes, @@ -690,7 +690,7 @@ impl ExecutionLayer { spec, ) .await? - }, + } BlockProductionVersion::FullV2 => self .get_full_payload_with_v3( parent_hash, @@ -734,90 +734,6 @@ impl ExecutionLayer { } } - /// Maps to the `engine_getPayload` JSON-RPC call. - /// - /// However, it will attempt to call `self.prepare_payload` if it cannot find an existing - /// payload id for the given parameters. - /// - /// ## Fallback Behavior - /// - /// The result will be returned from the first node that returns successfully. No more nodes - /// will be contacted. - pub async fn get_payload>( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - builder_params: BuilderParams, - current_fork: ForkName, - spec: &ChainSpec, - ) -> Result, Error> { - let payload_result = match Payload::block_type() { - BlockType::Blinded => { - let _timer = metrics::start_timer_vec( - &metrics::EXECUTION_LAYER_REQUEST_TIMES, - &[metrics::GET_BLINDED_PAYLOAD], - ); - self.get_blinded_payload( - parent_hash, - payload_attributes, - forkchoice_update_params, - builder_params, - current_fork, - spec, - ) - .await - } - BlockType::Full => { - let _timer = metrics::start_timer_vec( - &metrics::EXECUTION_LAYER_REQUEST_TIMES, - &[metrics::GET_PAYLOAD], - ); - self.get_full_payload( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await - .map(ProvenancedPayload::Local) - } - }; - - // Track some metrics and return the result. - match payload_result { - Ok(ProvenancedPayload::Local(block_proposal_contents)) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, - &[metrics::SUCCESS], - ); - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, - &[metrics::LOCAL], - ); - Ok(block_proposal_contents) - } - Ok(ProvenancedPayload::Builder(block_proposal_contents)) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, - &[metrics::SUCCESS], - ); - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, - &[metrics::BUILDER], - ); - Ok(block_proposal_contents) - } - Err(e) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_OUTCOME, - &[metrics::FAILURE], - ); - Err(e) - } - } - } - async fn determine_and_fetch_payload( &self, parent_hash: ExecutionBlockHash, @@ -1126,7 +1042,11 @@ impl ExecutionLayer { let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { builder - .get_builder_header::>(slot, parent_hash, &pubkey) + .get_builder_header::>( + slot, + parent_hash, + &pubkey, + ) .await }), timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { @@ -1167,7 +1087,9 @@ impl ExecutionLayer { "local_block_hash" => ?local.payload().block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(local), + )) } (Ok(None), Ok(local)) => { info!( @@ -1177,7 +1099,9 @@ impl ExecutionLayer { "local_block_hash" => ?local.payload().block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(local), + )) } (Ok(Some(relay)), Ok(local)) => { let header = &relay.data.message.header; @@ -1200,7 +1124,9 @@ impl ExecutionLayer { "local_block_value" => %local_value, "relay_value" => %relay_value ); - return Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))); + return Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(local), + )); } else { info!( self.log(), @@ -1222,11 +1148,12 @@ impl ExecutionLayer { ) { Ok(()) => Ok(ProvenancedPayload::Builder( BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }), + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), Err(reason) if !reason.payload_invalid() => { info!( @@ -1237,7 +1164,9 @@ impl ExecutionLayer { "relay_block_hash" => ?header.block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(local), + )) } Err(reason) => { metrics::inc_counter_vec( @@ -1252,7 +1181,9 @@ impl ExecutionLayer { "relay_block_hash" => ?header.block_hash(), "parent_hash" => ?parent_hash, ); - Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(local))) + Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(local), + )) } } } @@ -1278,21 +1209,23 @@ impl ExecutionLayer { ) { Ok(()) => Ok(ProvenancedPayload::Builder( BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }), + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), // If the payload is valid then use it. The local EE failed // to produce a payload so we have no alternative. Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }), + BlockProposalContents::Payload { + payload: relay.data.message.header, + block_value: relay.data.message.value, + _phantom: PhantomData, + }, + ), )), Err(reason) => { metrics::inc_counter_vec( @@ -1355,295 +1288,17 @@ impl ExecutionLayer { } } println!("YOOOO"); - let payload = self.get_full_payload_caching::>( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await?; - Ok(ProvenancedPayload::Local(BlockProposalContentsType::Blinded(payload))) - } - - async fn get_blinded_payload>( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - builder_params: BuilderParams, - current_fork: ForkName, - spec: &ChainSpec, - ) -> Result>, Error> { - println!("BLINDED"); - if let Some(builder) = self.builder() { - let slot = builder_params.slot; - let pubkey = builder_params.pubkey; - - match builder_params.chain_health { - ChainHealth::Healthy => { - info!( - self.log(), - "Requesting blinded header from connected builder"; - "slot" => ?slot, - "pubkey" => ?pubkey, - "parent_hash" => ?parent_hash, - ); - - // Wait for the builder *and* local EL to produce a payload (or return an error). - let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( - timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { - builder - .get_builder_header::(slot, parent_hash, &pubkey) - .await - }), - timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { - self.get_full_payload_caching::( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await - }) - ); - - info!( - self.log(), - "Requested blinded execution payload"; - "relay_fee_recipient" => match &relay_result { - Ok(Some(r)) => format!("{:?}", r.data.message.header.fee_recipient()), - Ok(None) => "empty response".to_string(), - Err(_) => "request failed".to_string(), - }, - "relay_response_ms" => relay_duration.as_millis(), - "local_fee_recipient" => match &local_result { - Ok(proposal_contents) => format!("{:?}", proposal_contents.payload().fee_recipient()), - Err(_) => "request failed".to_string() - }, - "local_response_ms" => local_duration.as_millis(), - "parent_hash" => ?parent_hash, - ); - - return match (relay_result, local_result) { - (Err(e), Ok(local)) => { - warn!( - self.log(), - "Builder error when requesting payload"; - "info" => "falling back to local execution client", - "relay_error" => ?e, - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local(local)) - } - (Ok(None), Ok(local)) => { - info!( - self.log(), - "Builder did not return a payload"; - "info" => "falling back to local execution client", - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local(local)) - } - (Ok(Some(relay)), Ok(local)) => { - let header = &relay.data.message.header; - - info!( - self.log(), - "Received local and builder payloads"; - "relay_block_hash" => ?header.block_hash(), - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - - let relay_value = relay.data.message.value; - let local_value = *local.block_value(); - if !self.inner.always_prefer_builder_payload { - if local_value >= relay_value { - info!( - self.log(), - "Local block is more profitable than relay block"; - "local_block_value" => %local_value, - "relay_value" => %relay_value - ); - return Ok(ProvenancedPayload::Local(local)); - } else { - info!( - self.log(), - "Relay block is more profitable than local block"; - "local_block_value" => %local_value, - "relay_value" => %relay_value - ); - } - } - - match verify_builder_bid( - &relay, - parent_hash, - payload_attributes, - Some(local.payload().block_number()), - self.inner.builder_profit_threshold, - current_fork, - spec, - ) { - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - )), - Err(reason) if !reason.payload_invalid() => { - info!( - self.log(), - "Builder payload ignored"; - "info" => "using local payload", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local(local)) - } - Err(reason) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, - &[reason.as_ref().as_ref()], - ); - warn!( - self.log(), - "Builder returned invalid payload"; - "info" => "using local payload", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local(local)) - } - } - } - (Ok(Some(relay)), Err(local_error)) => { - let header = &relay.data.message.header; - - info!( - self.log(), - "Received builder payload with local error"; - "relay_block_hash" => ?header.block_hash(), - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - match verify_builder_bid( - &relay, - parent_hash, - payload_attributes, - None, - self.inner.builder_profit_threshold, - current_fork, - spec, - ) { - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - )), - // If the payload is valid then use it. The local EE failed - // to produce a payload so we have no alternative. - Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - )), - Err(reason) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, - &[reason.as_ref().as_ref()], - ); - crit!( - self.log(), - "Builder returned invalid payload"; - "info" => "no local payload either - unable to propose block", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Err(Error::CannotProduceHeader) - } - } - } - (Err(relay_error), Err(local_error)) => { - crit!( - self.log(), - "Unable to produce execution payload"; - "info" => "the local EL and builder both failed - unable to propose block", - "relay_error" => ?relay_error, - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - Err(Error::CannotProduceHeader) - } - (Ok(None), Err(local_error)) => { - crit!( - self.log(), - "Unable to produce execution payload"; - "info" => "the local EL failed and the builder returned nothing - \ - the block proposal will be missed", - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - Err(Error::CannotProduceHeader) - } - }; - } - ChainHealth::Unhealthy(condition) => info!( - self.log(), - "Chain is unhealthy, using local payload"; - "info" => "this helps protect the network. the --builder-fallback flags \ - can adjust the expected health conditions.", - "failed_condition" => ?condition - ), - // Intentional no-op, so we never attempt builder API proposals pre-merge. - ChainHealth::PreMerge => (), - ChainHealth::Optimistic => info!( - self.log(), - "Chain is optimistic; can't build payload"; - "info" => "the local execution engine is syncing and the builder network \ - cannot safely be used - unable to propose block" - ), - } - } - self.get_full_payload_caching( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await - .map(ProvenancedPayload::Local) - } - - /// Get a full payload without caching its result in the execution layer's payload cache. - async fn get_full_payload>( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - current_fork: ForkName, - ) -> Result, Error> { - self.get_full_payload_with( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - noop, - ) - .await + let payload = self + .get_full_payload_caching::>( + parent_hash, + payload_attributes, + forkchoice_update_params, + current_fork, + ) + .await?; + Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(payload), + )) } /// Get a full payload and cache its result in the execution layer's payload cache. diff --git a/beacon_node/execution_layer/src/metrics.rs b/beacon_node/execution_layer/src/metrics.rs index 3ed99ca6068..79a3ca003ab 100644 --- a/beacon_node/execution_layer/src/metrics.rs +++ b/beacon_node/execution_layer/src/metrics.rs @@ -2,7 +2,6 @@ pub use lighthouse_metrics::*; pub const HIT: &str = "hit"; pub const MISS: &str = "miss"; -pub const GET_PAYLOAD: &str = "get_payload"; pub const GET_BLINDED_PAYLOAD: &str = "get_blinded_payload"; pub const GET_BLINDED_PAYLOAD_LOCAL: &str = "get_blinded_payload_local"; pub const GET_BLINDED_PAYLOAD_BUILDER: &str = "get_blinded_payload_builder"; diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 2b512d8b1c2..5fac14f724c 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -8,8 +8,7 @@ use crate::{ use sensitive_url::SensitiveUrl; use task_executor::TaskExecutor; use tempfile::NamedTempFile; -use tree_hash::TreeHash; -use types::{Address, ChainSpec, Epoch, EthSpec, FullPayload, Hash256, MainnetEthSpec}; +use types::{Address, ChainSpec, Epoch, EthSpec, Hash256, MainnetEthSpec}; pub struct MockExecutionLayer { pub server: MockServer, @@ -134,9 +133,10 @@ impl MockExecutionLayer { let suggested_fee_recipient = self.el.get_suggested_fee_recipient(validator_index).await; let payload_attributes = PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None); - let payload: ExecutionPayload = self + + let block_proposal_content_type = self .el - .get_payload::>( + .get_payload( parent_hash, &payload_attributes, forkchoice_update_params, @@ -144,11 +144,15 @@ impl MockExecutionLayer { // FIXME: do we need to consider other forks somehow? What about withdrawals? ForkName::Merge, &self.spec, + BlockProductionVersion::FullV2, ) .await - .unwrap() - .to_payload() - .into(); + .unwrap(); + + let payload: ExecutionPayload = match block_proposal_content_type { + BlockProposalContentsType::Full(block) => block.to_payload().into(), + BlockProposalContentsType::Blinded(_) => panic!("Should always be a full payload"), + }; let block_hash = payload.block_hash(); assert_eq!(payload.parent_hash(), parent_hash); @@ -169,9 +173,10 @@ impl MockExecutionLayer { let suggested_fee_recipient = self.el.get_suggested_fee_recipient(validator_index).await; let payload_attributes = PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None); - let payload_header = self + + let block_proposal_content_type = self .el - .get_payload::>( + .get_payload( parent_hash, &payload_attributes, forkchoice_update_params, @@ -179,10 +184,15 @@ impl MockExecutionLayer { // FIXME: do we need to consider other forks somehow? What about withdrawals? ForkName::Merge, &self.spec, + BlockProductionVersion::BlindedV2, ) .await - .unwrap() - .to_payload(); + .unwrap(); + + let payload_header = match block_proposal_content_type { + BlockProposalContentsType::Full(_) => panic!("Should always be a blinded payload"), + BlockProposalContentsType::Blinded(block) => block.to_payload(), + }; assert_eq!(payload_header.block_hash(), block_hash); assert_eq!(payload_header.parent_hash(), parent_hash); diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index a756c5dd017..ff87bffede4 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -26,7 +26,7 @@ mod validator; mod validator_inclusion; mod version; -use crate::validator::{produce_block_v2, produce_blinded_block_v2, produce_block_v3}; +use crate::validator::{produce_blinded_block_v2, produce_block_v2, produce_block_v3}; use beacon_chain::{ attestation_verification::VerifiedAttestation, observed_operations::ObservationOutcome, validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError, @@ -74,17 +74,16 @@ use tokio_stream::{ }; use types::{ Attestation, AttestationData, AttestationShufflingId, AttesterSlashing, BeaconStateError, - CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, - ProposerPreparationData, ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, - SignedBeaconBlock, SignedBlindedBeaconBlock, SignedBlsToExecutionChange, - SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, - SyncCommitteeMessage, SyncContributionData, + CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, ProposerPreparationData, + ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, SignedBeaconBlock, + SignedBlindedBeaconBlock, SignedBlsToExecutionChange, SignedContributionAndProof, + SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncCommitteeMessage, + SyncContributionData, }; use validator::pubkey_to_validator_index; use version::{ add_consensus_version_header, execution_optimistic_finalized_fork_versioned_response, - inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, - V3, + inconsistent_fork_rejection, unsupported_version_rejection, V1, V2, V3, }; use warp::http::StatusCode; use warp::sse::Event; diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 8ad2f4aa6d0..ec5527cbc9a 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -6,9 +6,7 @@ use beacon_chain::{ BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, }; -use eth2::types::{ - self as api_types, EndpointVersion, SkipRandaoVerification, -}; +use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; use ssz::Encode; use warp::{ hyper::{Body, Response}, diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index b2d990a8eb5..a4c082a404c 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -624,11 +624,9 @@ pub async fn proposer_boost_re_org_test( .get_validator_blocks_v3::(slot_c, &randao_reveal, None) .await .unwrap(); - + let block_c = match unsigned_block_type { - Full(unsigned_block_c) => { - harness.sign_beacon_block(unsigned_block_c.data, &state_b) - } + Full(unsigned_block_c) => harness.sign_beacon_block(unsigned_block_c.data, &state_b), Blinded(_) => { panic!("Should not be a blinded block"); } diff --git a/testing/execution_engine_integration/src/test_rig.rs b/testing/execution_engine_integration/src/test_rig.rs index 654b8628b8f..f2d0bf2f827 100644 --- a/testing/execution_engine_integration/src/test_rig.rs +++ b/testing/execution_engine_integration/src/test_rig.rs @@ -4,19 +4,20 @@ use crate::execution_engine::{ use crate::transactions::transactions; use ethers_providers::Middleware; use execution_layer::{ - BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, PayloadStatus, + BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, PayloadStatus, BlockProposalContentsType, }; use fork_choice::ForkchoiceUpdateParameters; use reqwest::{header::CONTENT_TYPE, Client}; use sensitive_url::SensitiveUrl; use serde_json::{json, Value}; +use types::payload::BlockProductionVersion; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use task_executor::TaskExecutor; use tokio::time::sleep; use types::{ Address, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, - ForkName, FullPayload, Hash256, MainnetEthSpec, PublicKeyBytes, Slot, Uint256, + ForkName, Hash256, MainnetEthSpec, PublicKeyBytes, Slot, Uint256, }; const EXECUTION_ENGINE_START_TIMEOUT: Duration = Duration::from_secs(30); @@ -310,10 +311,10 @@ impl TestRig { .await; let payload_attributes = PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None); - let valid_payload = self + let block_proposal_content_type = self .ee_a .execution_layer - .get_payload::>( + .get_payload( parent_hash, &payload_attributes, forkchoice_update_params, @@ -321,11 +322,17 @@ impl TestRig { // FIXME: think about how to test other forks ForkName::Merge, &self.spec, + BlockProductionVersion::FullV2 ) .await - .unwrap() - .to_payload() - .execution_payload(); + .unwrap(); + + let valid_payload = match block_proposal_content_type { + BlockProposalContentsType::Full(block) => block.to_payload().execution_payload(), + BlockProposalContentsType::Blinded(_) => panic!("Should always be a blinded payload"), + }; + + assert_eq!(valid_payload.transactions().len(), pending_txs.len()); /* @@ -450,10 +457,10 @@ impl TestRig { .await; let payload_attributes = PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None); - let second_payload = self + let block_proposal_content_type = self .ee_a .execution_layer - .get_payload::>( + .get_payload( parent_hash, &payload_attributes, forkchoice_update_params, @@ -461,11 +468,15 @@ impl TestRig { // FIXME: think about how to test other forks ForkName::Merge, &self.spec, + BlockProductionVersion::FullV2, ) .await - .unwrap() - .to_payload() - .execution_payload(); + .unwrap(); + + let second_payload = match block_proposal_content_type { + BlockProposalContentsType::Full(block) => block.to_payload().execution_payload(), + BlockProposalContentsType::Blinded(_) => panic!("Should always be a blinded payload"), + }; /* * Execution Engine A: From 8021687e412facf164b4a18686dedb7f783c64c4 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 6 Sep 2023 07:31:43 +0300 Subject: [PATCH 22/62] fixed logs --- testing/execution_engine_integration/src/test_rig.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/execution_engine_integration/src/test_rig.rs b/testing/execution_engine_integration/src/test_rig.rs index f2d0bf2f827..ca5fb0adc04 100644 --- a/testing/execution_engine_integration/src/test_rig.rs +++ b/testing/execution_engine_integration/src/test_rig.rs @@ -329,7 +329,7 @@ impl TestRig { let valid_payload = match block_proposal_content_type { BlockProposalContentsType::Full(block) => block.to_payload().execution_payload(), - BlockProposalContentsType::Blinded(_) => panic!("Should always be a blinded payload"), + BlockProposalContentsType::Blinded(_) => panic!("Should always be a full payload"), }; @@ -475,7 +475,7 @@ impl TestRig { let second_payload = match block_proposal_content_type { BlockProposalContentsType::Full(block) => block.to_payload().execution_payload(), - BlockProposalContentsType::Blinded(_) => panic!("Should always be a blinded payload"), + BlockProposalContentsType::Blinded(_) => panic!("Should always be a full payload"), }; /* From a59a9668959f487b75c0e6f5924f9abf4c2d116a Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 6 Sep 2023 08:05:18 +0300 Subject: [PATCH 23/62] add block value --- beacon_node/beacon_chain/src/beacon_chain.rs | 200 ++++++++++-------- beacon_node/beacon_chain/src/test_utils.rs | 4 +- beacon_node/http_api/src/validator.rs | 30 +-- .../src/test_rig.rs | 10 +- 4 files changed, 133 insertions(+), 111 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index be75dce38c7..c7c84b976bc 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -431,11 +431,11 @@ pub struct BeaconChain { } pub enum BeaconBlockAndStateResponse { - Full(BeaconBlockAndState>), - Blinded(BeaconBlockAndState>), + Full(BeaconBlockAndStateAndValue>), + Blinded(BeaconBlockAndStateAndValue>), } -pub type BeaconBlockAndState = (BeaconBlock, BeaconState); +pub type BeaconBlockAndStateAndValue = (BeaconBlock, BeaconState, u32); impl FinalizationAndCanonicity { pub fn is_finalized(self) -> bool { @@ -4582,7 +4582,7 @@ impl BeaconChain { partial_beacon_block: PartialBeaconBlock, block_contents: Option>, verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { let PartialBeaconBlock { mut state, slot, @@ -4604,90 +4604,112 @@ impl BeaconChain { 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 (inner_block, block_value) = 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, + }, + }), + 0, + ), + 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, + }, + }), + 0, + ), + BeaconState::Merge(_) => { + let block_proposal_contents = + block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; + let block_value = block_proposal_contents.block_value().as_u32(); + + ( + 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_proposal_contents + .to_payload() + .try_into() + .map_err(|_| BlockProductionError::InvalidPayloadFork)?, + }, + }), + block_value, + ) + } + BeaconState::Capella(_) => { + let block_proposal_contents = + block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; + let block_value = block_proposal_contents.block_value().as_u32(); + + ( + 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_proposal_contents + .to_payload() + .try_into() + .map_err(|_| BlockProductionError::InvalidPayloadFork)?, + bls_to_execution_changes: bls_to_execution_changes.into(), + }, + }), + block_value, + ) + } }; let block = SignedBeaconBlock::from_block( @@ -4744,7 +4766,7 @@ impl BeaconChain { "slot" => block.slot() ); - Ok((block, state)) + Ok((block, state, block_value)) } /// This method must be called whenever an execution engine indicates that a payload is diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 522eb233f53..a2e7d6decc0 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -772,7 +772,7 @@ where let randao_reveal = self.sign_randao_reveal(&state, proposer_index, slot); - if let BeaconBlockAndStateResponse::Full((block, state)) = self + if let BeaconBlockAndStateResponse::Full((block, state, _)) = self .chain .produce_block_on_state( state, @@ -825,7 +825,7 @@ where let pre_state = state.clone(); - if let BeaconBlockAndStateResponse::Full((block, state)) = self + if let BeaconBlockAndStateResponse::Full((block, state, _)) = self .chain .produce_block_on_state( state, diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index ec5527cbc9a..e0a0623f885 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -80,7 +80,7 @@ pub async fn produce_blinded_block_v2( .map_err(warp_utils::reject::block_production_error)?; match block_response { - BeaconBlockAndStateResponse::Full((block, _)) => { + BeaconBlockAndStateResponse::Full((block, _, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -90,7 +90,7 @@ pub async fn produce_blinded_block_v2( .map(|response| warp::reply::json(&response).into_response()) .map(|res| add_consensus_version_header(res, fork_name)) } - BeaconBlockAndStateResponse::Blinded((block, _)) => { + BeaconBlockAndStateResponse::Blinded((block, _, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -130,7 +130,7 @@ pub async fn produce_block_v2( .map_err(warp_utils::reject::block_production_error)?; match block_response { - BeaconBlockAndStateResponse::Full((block, _)) => { + BeaconBlockAndStateResponse::Full((block, _, _)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) @@ -140,7 +140,7 @@ pub async fn produce_block_v2( .map(|response| warp::reply::json(&response).into_response()) .map(|res| add_consensus_version_header(res, fork_name)) } - BeaconBlockAndStateResponse::Blinded((_, _)) => { + BeaconBlockAndStateResponse::Blinded((_, _, _)) => { Err(warp_utils::reject::custom_server_error( "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() )) @@ -196,11 +196,11 @@ pub async fn determine_and_produce_block_json( })?; match block_response { - BeaconBlockAndStateResponse::Full((block, _)) => { - generate_json_response_v3(chain, block, endpoint_version, false) + BeaconBlockAndStateResponse::Full((block, _, block_value)) => { + generate_json_response_v3(chain, block, endpoint_version, block_value, false) } - BeaconBlockAndStateResponse::Blinded((block, _)) => { - generate_json_response_v3(chain, block, endpoint_version, true) + BeaconBlockAndStateResponse::Blinded((block, _, block_value)) => { + generate_json_response_v3(chain, block, endpoint_version, block_value, true) } } } @@ -219,7 +219,6 @@ pub async fn determine_and_produce_block_ssz( let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - // TODO: block value let (block_ssz, fork_name, block_value, blinded) = match chain .produce_block_with_verification( randao_reveal, @@ -230,23 +229,23 @@ pub async fn determine_and_produce_block_ssz( ) .await .map_err(|e| { - warp_utils::reject::custom_bad_request(format!("faield to fetch a block: {:?}", e)) + warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) })? { - BeaconBlockAndStateResponse::Full((block, _)) => { + BeaconBlockAndStateResponse::Full((block, _, block_value)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, 0, false) + (block.as_ssz_bytes(), fork_name, block_value, false) } - BeaconBlockAndStateResponse::Blinded((block, _)) => { + BeaconBlockAndStateResponse::Blinded((block, _, block_value)) => { let fork_name = block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, 0, true) + (block.as_ssz_bytes(), fork_name, block_value, true) } }; @@ -270,6 +269,7 @@ pub fn generate_json_response_v3< chain: Arc>, block: BeaconBlock, endpoint_version: EndpointVersion, + block_value: u32, blinded_payload_flag: bool, ) -> Result, warp::Rejection> { let fork_name = block @@ -281,5 +281,5 @@ pub fn generate_json_response_v3< .map(|response| warp::reply::json(&response).into_response()) .map(|res| add_consensus_version_header(res, fork_name)) .map(|res| add_execution_payload_blinded_header(res, blinded_payload_flag)) - .map(|res: Response| add_execution_payload_value_header(res, 0)) + .map(|res: Response| add_execution_payload_value_header(res, block_value)) } diff --git a/testing/execution_engine_integration/src/test_rig.rs b/testing/execution_engine_integration/src/test_rig.rs index ca5fb0adc04..00c1dcd7f48 100644 --- a/testing/execution_engine_integration/src/test_rig.rs +++ b/testing/execution_engine_integration/src/test_rig.rs @@ -4,17 +4,18 @@ use crate::execution_engine::{ use crate::transactions::transactions; use ethers_providers::Middleware; use execution_layer::{ - BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, PayloadStatus, BlockProposalContentsType, + BlockProposalContentsType, BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, + PayloadStatus, }; use fork_choice::ForkchoiceUpdateParameters; use reqwest::{header::CONTENT_TYPE, Client}; use sensitive_url::SensitiveUrl; use serde_json::{json, Value}; -use types::payload::BlockProductionVersion; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; use task_executor::TaskExecutor; use tokio::time::sleep; +use types::payload::BlockProductionVersion; use types::{ Address, ChainSpec, EthSpec, ExecutionBlockHash, ExecutionPayload, ExecutionPayloadHeader, ForkName, Hash256, MainnetEthSpec, PublicKeyBytes, Slot, Uint256, @@ -322,7 +323,7 @@ impl TestRig { // FIXME: think about how to test other forks ForkName::Merge, &self.spec, - BlockProductionVersion::FullV2 + BlockProductionVersion::FullV2, ) .await .unwrap(); @@ -331,8 +332,7 @@ impl TestRig { BlockProposalContentsType::Full(block) => block.to_payload().execution_payload(), BlockProposalContentsType::Blinded(_) => panic!("Should always be a full payload"), }; - - + assert_eq!(valid_payload.transactions().len(), pending_txs.len()); /* From d5cb547a001b7119bb1af103934220e748b99426 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 6 Sep 2023 08:53:19 +0300 Subject: [PATCH 24/62] block value fix --- beacon_node/beacon_chain/src/beacon_chain.rs | 11 ++++++----- beacon_node/http_api/src/validator.rs | 2 +- beacon_node/http_api/src/version.rs | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index c7c84b976bc..499e9dd1331 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -435,7 +435,8 @@ pub enum BeaconBlockAndStateResponse { Blinded(BeaconBlockAndStateAndValue>), } -pub type BeaconBlockAndStateAndValue = (BeaconBlock, BeaconState, u32); +pub type BeaconBlockAndStateAndValue = + (BeaconBlock, BeaconState, Uint256); impl FinalizationAndCanonicity { pub fn is_finalized(self) -> bool { @@ -4623,7 +4624,7 @@ impl BeaconChain { _phantom: PhantomData, }, }), - 0, + Uint256::zero(), ), BeaconState::Altair(_) => ( BeaconBlock::Altair(BeaconBlockAltair { @@ -4645,12 +4646,12 @@ impl BeaconChain { _phantom: PhantomData, }, }), - 0, + Uint256::zero(), ), BeaconState::Merge(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let block_value = block_proposal_contents.block_value().as_u32(); + let block_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Merge(BeaconBlockMerge { @@ -4681,7 +4682,7 @@ impl BeaconChain { BeaconState::Capella(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let block_value = block_proposal_contents.block_value().as_u32(); + let block_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Capella(BeaconBlockCapella { diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index e0a0623f885..dfa759d08a0 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -269,7 +269,7 @@ pub fn generate_json_response_v3< chain: Arc>, block: BeaconBlock, endpoint_version: EndpointVersion, - block_value: u32, + block_value: Uint256, blinded_payload_flag: bool, ) -> Result, warp::Rejection> { let fork_name = block diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index da83a2c14ef..f72bf8af31e 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -4,7 +4,7 @@ use eth2::{ CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, }; use serde::Serialize; -use types::{ForkName, ForkVersionedResponse, InconsistentFork}; +use types::{ForkName, ForkVersionedResponse, InconsistentFork, Uint256}; use warp::reply::{self, Reply, Response}; pub const V1: EndpointVersion = EndpointVersion(1); @@ -72,7 +72,7 @@ pub fn add_execution_payload_blinded_header( /// Add the `Eth-Execution-Payload-Value` header to a response. pub fn add_execution_payload_value_header( reply: T, - execution_payload_value: u32, + execution_payload_value: Uint256, ) -> Response { reply::with_header( reply, From 36f863a649807173e8cb755a5e80003d9c3f7833 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 6 Sep 2023 09:16:20 +0300 Subject: [PATCH 25/62] linting --- beacon_node/http_api/tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon_node/http_api/tests/tests.rs b/beacon_node/http_api/tests/tests.rs index 1e19b8da528..e78e8d785bd 100644 --- a/beacon_node/http_api/tests/tests.rs +++ b/beacon_node/http_api/tests/tests.rs @@ -4440,7 +4440,7 @@ impl ApiTester { assert_eq!(withdrawal_response.finalized, Some(false)); assert_eq!(withdrawal_response.data, expected_withdrawals.to_vec()); } - Err(e) => { + Err(_) => { panic!("query failed incorrectly"); } } From c68e7afcefbd318d6424054486409b633788f7e1 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 27 Sep 2023 23:03:15 +0300 Subject: [PATCH 26/62] merge unstable --- beacon_node/http_api/src/lib.rs | 4 +- beacon_node/http_api/src/validator.rs | 3 +- common/eth2/src/lib.rs | 82 +++++++++++++++------------ 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index aebbb566b47..49971445bca 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3004,7 +3004,6 @@ pub fn serve( .and(warp::header::optional::("accept")) .and(not_while_syncing_filter.clone()) .and(warp::query::()) - .and(warp::header::optional::("accept")) .and(task_spawner_filter.clone()) .and(chain_filter.clone()) .and(log_filter.clone()) @@ -3013,7 +3012,6 @@ pub fn serve( slot: Slot, accept_header: Option, query: api_types::ValidatorBlocksQuery, - accept_header: Option, task_spawner: TaskSpawner, chain: Arc>, log: Logger| { @@ -3055,7 +3053,7 @@ pub fn serve( task_spawner: TaskSpawner, chain: Arc>| { task_spawner.spawn_async_with_rejection(Priority::P0, async move { - produce_blinded_block_v2(EndpointVersion(2), chain, slot, query).await + produce_blinded_block_v2(EndpointVersion(2), accept_header, chain, slot, query).await }) }, ); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 4fb53c9f04e..48549f65583 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,5 +1,5 @@ use types::{payload::BlockProductionVersion, *}; - +use bytes::Bytes; use std::sync::Arc; use beacon_chain::{ @@ -56,6 +56,7 @@ pub fn get_randao_verification( pub async fn produce_blinded_block_v2( endpoint_version: EndpointVersion, + accept_header: Option, chain: Arc>, slot: Slot, query: api_types::ValidatorBlocksQuery, diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 838c57747c3..033087c1bf9 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1603,6 +1603,26 @@ impl BeaconNodeHttpClient { .await } + /// `GET v2/validator/blocks/{slot}` + pub async fn get_validator_blocks_modular>( + &self, + slot: Slot, + randao_reveal: &SignatureBytes, + graffiti: Option<&Graffiti>, + skip_randao_verification: SkipRandaoVerification, + ) -> Result>, Error> { + let path = self + .get_validator_blocks_path::( + slot, + randao_reveal, + graffiti, + skip_randao_verification, + ) + .await?; + + self.get(path).await + } + /// returns `GET v2/validator/blocks/{slot}` URL path pub async fn get_validator_blocks_path>( &self, @@ -1635,26 +1655,6 @@ impl BeaconNodeHttpClient { Ok(path) } - /// `GET v2/validator/blocks/{slot}` - pub async fn get_validator_blocks_modular>( - &self, - slot: Slot, - randao_reveal: &SignatureBytes, - graffiti: Option<&Graffiti>, - skip_randao_verification: SkipRandaoVerification, - ) -> Result>, Error> { - let path = self - .get_validator_blocks_path::( - slot, - randao_reveal, - graffiti, - skip_randao_verification, - ) - .await?; - - self.get(path).await - } - /// `GET v3/validator/blocks/{slot}` pub async fn get_validator_blocks_v3( &self, @@ -1662,18 +1662,7 @@ impl BeaconNodeHttpClient { randao_reveal: &SignatureBytes, graffiti: Option<&Graffiti>, ) -> Result, Error> { - self.get_validator_blocks_v3_modular() - } - - /// `GET v2/validator/blocks/{slot}` in ssz format - pub async fn get_validator_blocks_ssz>( - &self, - slot: Slot, - randao_reveal: &SignatureBytes, - graffiti: Option<&Graffiti>, - skip_randao_verification: SkipRandaoVerification, - ) -> Result>, Error> { - self.get_validator_blocks_modular_ssz::( + self.get_validator_blocks_v3_modular( slot, randao_reveal, graffiti, @@ -1682,8 +1671,8 @@ impl BeaconNodeHttpClient { .await } - /// `GET v2/validator/blocks/{slot}` in ssz format - pub async fn get_validator_blocks_modular_ssz>( + /// `GET v3/validator/blocks/{slot}` + pub async fn get_validator_blocks_v3_modular( &self, slot: Slot, randao_reveal: &SignatureBytes, @@ -1728,8 +1717,29 @@ impl BeaconNodeHttpClient { Ok(ForkVersionedBeaconBlockType::Full(full_payload)) } - /// `GET v3/validator/blocks/{slot}` - pub async fn get_validator_blocks_v3_modular( + /// `GET v2/validator/blocks/{slot}` in ssz format + pub async fn get_validator_blocks_ssz>( + &self, + slot: Slot, + randao_reveal: &SignatureBytes, + graffiti: Option<&Graffiti>, + ) -> Result>, Error> { + self.get_validator_blocks_modular_ssz::( + slot, + randao_reveal, + graffiti, + SkipRandaoVerification::No, + ) + .await + } + + /// `GET v2/validator/blocks/{slot}` in ssz format + pub async fn get_validator_blocks_modular_ssz>( + &self, + slot: Slot, + randao_reveal: &SignatureBytes, + graffiti: Option<&Graffiti>, + skip_randao_verification: SkipRandaoVerification, ) -> Result>, Error> { let path = self .get_validator_blocks_path::( From df250835c60554c20d4df0a17ddcb52a70d2f743 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 27 Sep 2023 23:23:20 +0300 Subject: [PATCH 27/62] refactor --- beacon_node/http_api/src/lib.rs | 3 +- beacon_node/http_api/src/validator.rs | 173 ++++++++++---------------- common/eth2/src/lib.rs | 4 +- 3 files changed, 73 insertions(+), 107 deletions(-) diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 49971445bca..99a9e15ae86 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3053,7 +3053,8 @@ pub fn serve( task_spawner: TaskSpawner, chain: Arc>| { task_spawner.spawn_async_with_rejection(Priority::P0, async move { - produce_blinded_block_v2(EndpointVersion(2), accept_header, chain, slot, query).await + produce_blinded_block_v2(EndpointVersion(2), accept_header, chain, slot, query) + .await }) }, ); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 48549f65583..3db18c7f020 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,6 +1,6 @@ -use types::{payload::BlockProductionVersion, *}; use bytes::Bytes; use std::sync::Arc; +use types::{payload::BlockProductionVersion, *}; use beacon_chain::{ BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes, @@ -82,111 +82,10 @@ pub async fn produce_blinded_block_v2( match block_response { BeaconBlockAndStateResponse::Full((block, _, _)) => { - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!( - "failed to create response: {}", - e - )) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } + build_response_v2(chain, block, endpoint_version) } BeaconBlockAndStateResponse::Blinded((block, _, _)) => { - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!( - "failed to create response: {}", - e - )) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } - } - } -} - -pub async fn produce_block_v2( - endpoint_version: EndpointVersion, - accept_header: Option, - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, -) -> Result, warp::Rejection> { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - - let block_response = chain - .produce_block_with_verification( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - BlockProductionVersion::FullV2, - ) - .await - .map_err(warp_utils::reject::block_production_error)?; - - match block_response { - BeaconBlockAndStateResponse::Full((block, _, _)) => { - let fork_name = block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block.as_ssz_bytes().into()) - .map(|res: Response| { - add_consensus_version_header(res, fork_name) - }) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!( - "failed to create response: {}", - e - )) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } - } - BeaconBlockAndStateResponse::Blinded((_, _, _)) => { - Err(warp_utils::reject::custom_server_error( - "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() - )) + build_response_v2(chain, block, endpoint_version) } } } @@ -326,3 +225,69 @@ pub fn generate_json_response_v3< .map(|res| add_execution_payload_blinded_header(res, blinded_payload_flag)) .map(|res: Response| add_execution_payload_value_header(res, block_value)) } + + + +pub async fn produce_block_v2( + endpoint_version: EndpointVersion, + accept_header: Option, + chain: Arc>, + slot: Slot, + query: api_types::ValidatorBlocksQuery, +) -> Result, warp::Rejection> { + let randao_reveal = query.randao_reveal.decompress().map_err(|e| { + warp_utils::reject::custom_bad_request(format!( + "randao reveal is not a valid BLS signature: {:?}", + e + )) + })?; + + let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + + let block_response = chain + .produce_block_with_verification( + randao_reveal, + slot, + query.graffiti.map(Into::into), + randao_verification, + BlockProductionVersion::FullV2, + ) + .await + .map_err(warp_utils::reject::block_production_error)?; + + match block_response { + BeaconBlockAndStateResponse::Full((block, _, _)) => { + build_response_v2(chain, block, endpoint_version) + } + BeaconBlockAndStateResponse::Blinded((_, _, _)) => { + Err(warp_utils::reject::custom_server_error( + "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() + )) + } + } +} + +pub fn build_response_v2>( + chain: Arc>, + block: BeaconBlock, + endpoint_version: EndpointVersion, +) -> Result, warp::Rejection> { + let fork_name = block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + match accept_header { + Some(api_types::Accept::Ssz) => Response::builder() + .status(200) + .header("Content-Type", "application/octet-stream") + .body(block.as_ssz_bytes().into()) + .map(|res: Response| add_consensus_version_header(res, fork_name)) + .map_err(|e| { + warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) + }), + _ => fork_versioned_response(endpoint_version, fork_name, block) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)), + } +} diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 033087c1bf9..1071ec14d03 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -1671,8 +1671,8 @@ impl BeaconNodeHttpClient { .await } - /// `GET v3/validator/blocks/{slot}` - pub async fn get_validator_blocks_v3_modular( + /// `GET v3/validator/blocks/{slot}` + pub async fn get_validator_blocks_v3_modular( &self, slot: Slot, randao_reveal: &SignatureBytes, From 91d37e95a42ff2d12248f749a33cf14f8be4cc1c Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 28 Sep 2023 16:51:01 +0300 Subject: [PATCH 28/62] add consensus block value --- beacon_node/beacon_chain/src/beacon_chain.rs | 58 +++++++++------ beacon_node/beacon_chain/src/lib.rs | 4 +- beacon_node/beacon_chain/src/test_utils.rs | 20 ++--- beacon_node/http_api/src/validator.rs | 73 ++++++++++++------- beacon_node/http_api/src/version.rs | 19 ++++- .../http_api/tests/interactive_tests.rs | 1 - common/eth2/src/lib.rs | 1 + 7 files changed, 111 insertions(+), 65 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 53a85c43030..a0d613c4920 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -430,13 +430,17 @@ pub struct BeaconChain { pub genesis_backfill_slot: Slot, } -pub enum BeaconBlockAndStateResponse { - Full(BeaconBlockAndStateAndValue>), - Blinded(BeaconBlockAndStateAndValue>), +pub enum BeaconBlockResponseType { + Full(BeaconBlockResponse>), + Blinded(BeaconBlockResponse>), } -pub type BeaconBlockAndStateAndValue = - (BeaconBlock, BeaconState, Uint256); +pub struct BeaconBlockResponse> { + pub block: BeaconBlock, + pub state: BeaconState, + pub execution_block_value: Option, + pub consensus_block_value: Option, +} impl FinalizationAndCanonicity { pub fn is_finalized(self) -> bool { @@ -3622,7 +3626,7 @@ impl BeaconChain { validator_graffiti: Option, verification: ProduceBlockVerification, block_production_version: BlockProductionVersion, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { // Part 1/2 (blocking) // // Load the parent state from disk. @@ -4223,7 +4227,7 @@ impl BeaconChain { validator_graffiti: Option, verification: ProduceBlockVerification, block_production_version: BlockProductionVersion, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { // Part 1/3 (blocking) // // Perform the state advance and block-packing functions. @@ -4270,7 +4274,7 @@ impl BeaconChain { match block_contents_type { BlockProposalContentsType::Full(block_contents) => { let chain = self.clone(); - let beacon_block_and_state = self + let beacon_block_response = self .task_executor .spawn_blocking_handle( move || { @@ -4286,11 +4290,11 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)??; - Ok(BeaconBlockAndStateResponse::Full(beacon_block_and_state)) + Ok(BeaconBlockResponseType::Full(beacon_block_response)) } BlockProposalContentsType::Blinded(block_contents) => { let chain = self.clone(); - let beacon_block_and_state = self + let beacon_block_response = self .task_executor .spawn_blocking_handle( move || { @@ -4306,12 +4310,12 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)??; - Ok(BeaconBlockAndStateResponse::Blinded(beacon_block_and_state)) + Ok(BeaconBlockResponseType::Blinded(beacon_block_response)) } } } else { let chain = self.clone(); - let beacon_block_and_state = self + let beacon_block_response = self .task_executor .spawn_blocking_handle( move || { @@ -4327,7 +4331,7 @@ impl BeaconChain { .await .map_err(BlockProductionError::TokioJoin)??; - Ok(BeaconBlockAndStateResponse::Full(beacon_block_and_state)) + Ok(BeaconBlockResponseType::Full(beacon_block_response)) } } @@ -4583,7 +4587,7 @@ impl BeaconChain { partial_beacon_block: PartialBeaconBlock, block_contents: Option>, verification: ProduceBlockVerification, - ) -> Result, BlockProductionError> { + ) -> Result, BlockProductionError> { let PartialBeaconBlock { mut state, slot, @@ -4605,7 +4609,7 @@ impl BeaconChain { bls_to_execution_changes, } = partial_beacon_block; - let (inner_block, block_value) = match &state { + let (inner_block, execution_block_value) = match &state { BeaconState::Base(_) => ( BeaconBlock::Base(BeaconBlockBase { slot, @@ -4651,7 +4655,7 @@ impl BeaconChain { BeaconState::Merge(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let block_value = block_proposal_contents.block_value().to_owned(); + let execution_block_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Merge(BeaconBlockMerge { @@ -4676,13 +4680,13 @@ impl BeaconChain { .map_err(|_| BlockProductionError::InvalidPayloadFork)?, }, }), - block_value, + execution_block_value, ) } BeaconState::Capella(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let block_value = block_proposal_contents.block_value().to_owned(); + let execution_block_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Capella(BeaconBlockCapella { @@ -4708,13 +4712,13 @@ impl BeaconChain { bls_to_execution_changes: bls_to_execution_changes.into(), }, }), - block_value, + execution_block_value, ) } }; let block = SignedBeaconBlock::from_block( - inner_block, + inner_block.clone(), // The block is not signed here, that is the task of a validator client. Signature::empty(), ); @@ -4739,6 +4743,13 @@ impl BeaconChain { }; // Use a context without block root or proposer index so that both are checked. let mut ctxt = ConsensusContext::new(block.slot()); + + let consensus_block_value = self + .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state.clone()) + .unwrap() + .total; + + per_block_processing( &mut state, &block, @@ -4767,7 +4778,12 @@ impl BeaconChain { "slot" => block.slot() ); - Ok((block, state, block_value)) + Ok(BeaconBlockResponse { + block, + state, + execution_block_value: Some(execution_block_value), + consensus_block_value: Some(consensus_block_value), + }) } /// This method must be called whenever an execution engine indicates that a payload is diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index d15e2c300b9..92f079f2a8e 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -51,8 +51,8 @@ pub mod validator_monitor; pub mod validator_pubkey_cache; pub use self::beacon_chain::{ - AttestationProcessingOutcome, BeaconBlockAndStateResponse, BeaconChain, BeaconChainTypes, - BeaconStore, ChainSegmentResult, ForkChoiceError, OverrideForkchoiceUpdate, + AttestationProcessingOutcome, BeaconBlockResponse, BeaconBlockResponseType, BeaconChain, + BeaconChainTypes, BeaconStore, ChainSegmentResult, ForkChoiceError, OverrideForkchoiceUpdate, ProduceBlockVerification, StateSkipConfig, WhenSlotSkipped, INVALID_FINALIZED_MERGE_TRANSITION_BLOCK_SHUTDOWN_REASON, INVALID_JUSTIFIED_PAYLOAD_SHUTDOWN_REASON, diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 4a25b61319f..7eb28e2bee5 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -1,6 +1,6 @@ use crate::observed_operations::ObservationOutcome; pub use crate::persisted_beacon_chain::PersistedBeaconChain; -use crate::BeaconBlockAndStateResponse; +use crate::BeaconBlockResponseType; pub use crate::{ beacon_chain::{BEACON_CHAIN_DB_KEY, ETH1_CACHE_DB_KEY, FORK_CHOICE_DB_KEY, OP_POOL_DB_KEY}, migrate::MigratorConfig, @@ -777,7 +777,7 @@ where let randao_reveal = self.sign_randao_reveal(&state, proposer_index, slot); - if let BeaconBlockAndStateResponse::Full((block, state, _)) = self + if let BeaconBlockResponseType::Full(block_response) = self .chain .produce_block_on_state( state, @@ -791,14 +791,14 @@ where .await .unwrap() { - let signed_block = block.sign( + let signed_block = block_response.block.sign( &self.validator_keypairs[proposer_index].sk, - &state.fork(), - state.genesis_validators_root(), + &block_response.state.fork(), + block_response.state.genesis_validators_root(), &self.spec, ); - (signed_block, state) + (signed_block, block_response.state) } else { panic!("Should always be a full payload response") } @@ -830,7 +830,7 @@ where let pre_state = state.clone(); - if let BeaconBlockAndStateResponse::Full((block, state, _)) = self + if let BeaconBlockResponseType::Full(block_response) = self .chain .produce_block_on_state( state, @@ -844,10 +844,10 @@ where .await .unwrap() { - let signed_block = block.sign( + let signed_block = block_response.block.sign( &self.validator_keypairs[proposer_index].sk, - &state.fork(), - state.genesis_validators_root(), + &block_response.state.fork(), + block_response.state.genesis_validators_root(), &self.spec, ); diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 3db18c7f020..bb8e63469d3 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use types::{payload::BlockProductionVersion, *}; use beacon_chain::{ - BeaconBlockAndStateResponse, BeaconChain, BeaconChainError, BeaconChainTypes, + BeaconBlockResponse, BeaconBlockResponseType, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, }; use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; @@ -14,8 +14,9 @@ use warp::{ }; use crate::version::{ - add_consensus_version_header, add_execution_payload_blinded_header, - add_execution_payload_value_header, fork_versioned_response, inconsistent_fork_rejection, + add_consensus_payload_value_header, add_consensus_version_header, + add_execution_payload_blinded_header, add_execution_payload_value_header, + fork_versioned_response, inconsistent_fork_rejection, }; /// Uses the `chain.validator_pubkey_cache` to resolve a pubkey to a validator /// index and then ensures that the validator exists in the given `state`. @@ -81,11 +82,11 @@ pub async fn produce_blinded_block_v2( .map_err(warp_utils::reject::block_production_error)?; match block_response { - BeaconBlockAndStateResponse::Full((block, _, _)) => { - build_response_v2(chain, block, endpoint_version) + BeaconBlockResponseType::Full(block_response) => { + build_response_v2(chain, block_response.block, endpoint_version, accept_header) } - BeaconBlockAndStateResponse::Blinded((block, _, _)) => { - build_response_v2(chain, block, endpoint_version) + BeaconBlockResponseType::Blinded(block_response) => { + build_response_v2(chain, block_response.block, endpoint_version, accept_header) } } } @@ -138,11 +139,11 @@ pub async fn determine_and_produce_block_json( })?; match block_response { - BeaconBlockAndStateResponse::Full((block, _, block_value)) => { - generate_json_response_v3(chain, block, endpoint_version, block_value, false) + BeaconBlockResponseType::Full(block_response) => { + generate_json_response_v3(chain, block_response, endpoint_version, false) } - BeaconBlockAndStateResponse::Blinded((block, _, block_value)) => { - generate_json_response_v3(chain, block, endpoint_version, block_value, true) + BeaconBlockResponseType::Blinded(block_response) => { + generate_json_response_v3(chain, block_response, endpoint_version, true) } } } @@ -173,21 +174,33 @@ pub async fn determine_and_produce_block_ssz( .map_err(|e| { warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) })? { - BeaconBlockAndStateResponse::Full((block, _, block_value)) => { - let fork_name = block + BeaconBlockResponseType::Full(block_response) => { + let fork_name = block_response + .block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, block_value, false) + ( + block_response.block.as_ssz_bytes(), + fork_name, + block_response.execution_block_value, + false, + ) } - BeaconBlockAndStateResponse::Blinded((block, _, block_value)) => { - let fork_name = block + BeaconBlockResponseType::Blinded(block_response) => { + let fork_name = block_response + .block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - (block.as_ssz_bytes(), fork_name, block_value, true) + ( + block_response.block.as_ssz_bytes(), + fork_name, + block_response.execution_block_value, + true, + ) } }; @@ -209,25 +222,28 @@ pub fn generate_json_response_v3< Payload: AbstractExecPayload, >( chain: Arc>, - block: BeaconBlock, + beacon_block_response: BeaconBlockResponse, endpoint_version: EndpointVersion, - block_value: Uint256, blinded_payload_flag: bool, ) -> Result, warp::Rejection> { - let fork_name = block + let fork_name = beacon_block_response + .block .to_ref() .fork_name(&chain.spec) .map_err(inconsistent_fork_rejection)?; - fork_versioned_response(endpoint_version, fork_name, block) + fork_versioned_response(endpoint_version, fork_name, beacon_block_response.block) .map(|response| warp::reply::json(&response).into_response()) .map(|res| add_consensus_version_header(res, fork_name)) .map(|res| add_execution_payload_blinded_header(res, blinded_payload_flag)) - .map(|res: Response| add_execution_payload_value_header(res, block_value)) + .map(|res| { + add_execution_payload_value_header(res, beacon_block_response.execution_block_value) + }) + .map(|res| { + add_consensus_payload_value_header(res, beacon_block_response.consensus_block_value) + }) } - - pub async fn produce_block_v2( endpoint_version: EndpointVersion, accept_header: Option, @@ -256,10 +272,10 @@ pub async fn produce_block_v2( .map_err(warp_utils::reject::block_production_error)?; match block_response { - BeaconBlockAndStateResponse::Full((block, _, _)) => { - build_response_v2(chain, block, endpoint_version) + BeaconBlockResponseType::Full(block_response) => { + build_response_v2(chain, block_response.block, endpoint_version, accept_header) } - BeaconBlockAndStateResponse::Blinded((_, _, _)) => { + BeaconBlockResponseType::Blinded(_) => { Err(warp_utils::reject::custom_server_error( "Returned a blinded block. It should be impossible to return a blinded block via the Full Payload V2 block fetching flow.".to_string() )) @@ -267,10 +283,11 @@ pub async fn produce_block_v2( } } -pub fn build_response_v2>( +pub fn build_response_v2>( chain: Arc>, block: BeaconBlock, endpoint_version: EndpointVersion, + accept_header: Option, ) -> Result, warp::Rejection> { let fork_name = block .to_ref() diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index f72bf8af31e..460dc0ed33e 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -1,7 +1,7 @@ use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse; use crate::api_types::EndpointVersion; use eth2::{ - CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, + CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, CONSENSUS_PAYLOAD_VALUE_HEADER, }; use serde::Serialize; use types::{ForkName, ForkVersionedResponse, InconsistentFork, Uint256}; @@ -72,12 +72,25 @@ pub fn add_execution_payload_blinded_header( /// Add the `Eth-Execution-Payload-Value` header to a response. pub fn add_execution_payload_value_header( reply: T, - execution_payload_value: Uint256, + execution_payload_value: Option, ) -> Response { reply::with_header( reply, EXECUTION_PAYLOAD_VALUE_HEADER, - execution_payload_value.to_string(), + execution_payload_value.unwrap_or_default().to_string(), + ) + .into_response() +} + +/// Add the `Eth-Execution-Payload-Value` header to a response. +pub fn add_consensus_payload_value_header( + reply: T, + consensus_payload_value: Option, +) -> Response { + reply::with_header( + reply, + CONSENSUS_PAYLOAD_VALUE_HEADER, + consensus_payload_value.unwrap_or_default().to_string(), ) .into_response() } diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index a4c082a404c..ab32d76d4d0 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -631,7 +631,6 @@ pub async fn proposer_boost_re_org_test( panic!("Should not be a blinded block"); } }; - // let block_c = harness.sign_beacon_block(unsigned_block_c, &state_b); if should_re_org { // Block C should build on A. diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 1071ec14d03..71892ab3778 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -43,6 +43,7 @@ pub const V3: EndpointVersion = EndpointVersion(3); pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version"; pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded"; pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value"; +pub const CONSENSUS_PAYLOAD_VALUE_HEADER: &str = "Eth-Consensus-Payload-Value"; #[derive(Debug)] pub enum Error { From 6878abe0fff5aa8715d09814331a6eb2098af4fc Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 28 Sep 2023 17:03:45 +0300 Subject: [PATCH 29/62] lint --- beacon_node/beacon_chain/src/beacon_chain.rs | 11 +++++++++-- beacon_node/http_api/src/version.rs | 3 ++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index a0d613c4920..f4b71c8a9ac 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -58,6 +58,7 @@ use crate::validator_monitor::{ }; use crate::validator_pubkey_cache::ValidatorPubkeyCache; use crate::{metrics, BeaconChainError, BeaconForkChoiceStore, BeaconSnapshot, CachedHead}; +use eth2::lighthouse::StandardBlockReward; use eth2::types::{EventKind, SseBlock, SseExtendedPayloadAttributes, SyncDuty}; use execution_layer::{ BlockProposalContents, BlockProposalContentsType, BuilderParams, ChainHealth, ExecutionLayer, @@ -4746,9 +4747,15 @@ impl BeaconChain { let consensus_block_value = self .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state.clone()) - .unwrap() + .unwrap_or(StandardBlockReward { + proposer_index: 0, + total: 0, + attestations: 0, + sync_aggregate: 0, + proposer_slashings: 0, + attester_slashings: 0, + }) .total; - per_block_processing( &mut state, diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index 460dc0ed33e..cb56d37dab6 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -1,7 +1,8 @@ use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse; use crate::api_types::EndpointVersion; use eth2::{ - CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, CONSENSUS_PAYLOAD_VALUE_HEADER, + CONSENSUS_PAYLOAD_VALUE_HEADER, CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, + EXECUTION_PAYLOAD_VALUE_HEADER, }; use serde::Serialize; use types::{ForkName, ForkVersionedResponse, InconsistentFork, Uint256}; From 8a674dda718981dc76f26d59b3313919f8c58b5e Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 1 Oct 2023 17:34:17 +0300 Subject: [PATCH 30/62] update header name to consensus block value --- beacon_node/beacon_chain/src/beacon_chain.rs | 14 +++++++------- beacon_node/http_api/src/validator.rs | 10 +++++----- beacon_node/http_api/src/version.rs | 6 +++--- common/eth2/src/lib.rs | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index f4b71c8a9ac..6ab3cc54e81 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -439,7 +439,7 @@ pub enum BeaconBlockResponseType { pub struct BeaconBlockResponse> { pub block: BeaconBlock, pub state: BeaconState, - pub execution_block_value: Option, + pub execution_payload_value: Option, pub consensus_block_value: Option, } @@ -4610,7 +4610,7 @@ impl BeaconChain { bls_to_execution_changes, } = partial_beacon_block; - let (inner_block, execution_block_value) = match &state { + let (inner_block, execution_payload_value) = match &state { BeaconState::Base(_) => ( BeaconBlock::Base(BeaconBlockBase { slot, @@ -4656,7 +4656,7 @@ impl BeaconChain { BeaconState::Merge(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let execution_block_value = block_proposal_contents.block_value().to_owned(); + let execution_payload_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Merge(BeaconBlockMerge { @@ -4681,13 +4681,13 @@ impl BeaconChain { .map_err(|_| BlockProductionError::InvalidPayloadFork)?, }, }), - execution_block_value, + execution_payload_value, ) } BeaconState::Capella(_) => { let block_proposal_contents = block_contents.ok_or(BlockProductionError::MissingExecutionPayload)?; - let execution_block_value = block_proposal_contents.block_value().to_owned(); + let execution_payload_value = block_proposal_contents.block_value().to_owned(); ( BeaconBlock::Capella(BeaconBlockCapella { @@ -4713,7 +4713,7 @@ impl BeaconChain { bls_to_execution_changes: bls_to_execution_changes.into(), }, }), - execution_block_value, + execution_payload_value, ) } }; @@ -4788,7 +4788,7 @@ impl BeaconChain { Ok(BeaconBlockResponse { block, state, - execution_block_value: Some(execution_block_value), + execution_payload_value: Some(execution_payload_value), consensus_block_value: Some(consensus_block_value), }) } diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index bb8e63469d3..9d0890f2f91 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -14,7 +14,7 @@ use warp::{ }; use crate::version::{ - add_consensus_payload_value_header, add_consensus_version_header, + add_consensus_block_value_header, add_consensus_version_header, add_execution_payload_blinded_header, add_execution_payload_value_header, fork_versioned_response, inconsistent_fork_rejection, }; @@ -184,7 +184,7 @@ pub async fn determine_and_produce_block_ssz( ( block_response.block.as_ssz_bytes(), fork_name, - block_response.execution_block_value, + block_response.execution_payload_value, false, ) } @@ -198,7 +198,7 @@ pub async fn determine_and_produce_block_ssz( ( block_response.block.as_ssz_bytes(), fork_name, - block_response.execution_block_value, + block_response.execution_payload_value, true, ) } @@ -237,10 +237,10 @@ pub fn generate_json_response_v3< .map(|res| add_consensus_version_header(res, fork_name)) .map(|res| add_execution_payload_blinded_header(res, blinded_payload_flag)) .map(|res| { - add_execution_payload_value_header(res, beacon_block_response.execution_block_value) + add_execution_payload_value_header(res, beacon_block_response.execution_payload_value) }) .map(|res| { - add_consensus_payload_value_header(res, beacon_block_response.consensus_block_value) + add_consensus_block_value_header(res, beacon_block_response.consensus_block_value) }) } diff --git a/beacon_node/http_api/src/version.rs b/beacon_node/http_api/src/version.rs index cb56d37dab6..d38152a95d7 100644 --- a/beacon_node/http_api/src/version.rs +++ b/beacon_node/http_api/src/version.rs @@ -1,7 +1,7 @@ use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse; use crate::api_types::EndpointVersion; use eth2::{ - CONSENSUS_PAYLOAD_VALUE_HEADER, CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, + CONSENSUS_BLOCK_VALUE_HEADER, CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER, EXECUTION_PAYLOAD_VALUE_HEADER, }; use serde::Serialize; @@ -84,13 +84,13 @@ pub fn add_execution_payload_value_header( } /// Add the `Eth-Execution-Payload-Value` header to a response. -pub fn add_consensus_payload_value_header( +pub fn add_consensus_block_value_header( reply: T, consensus_payload_value: Option, ) -> Response { reply::with_header( reply, - CONSENSUS_PAYLOAD_VALUE_HEADER, + CONSENSUS_BLOCK_VALUE_HEADER, consensus_payload_value.unwrap_or_default().to_string(), ) .into_response() diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index 71892ab3778..c8b820f6388 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -43,7 +43,7 @@ pub const V3: EndpointVersion = EndpointVersion(3); pub const CONSENSUS_VERSION_HEADER: &str = "Eth-Consensus-Version"; pub const EXECUTION_PAYLOAD_BLINDED_HEADER: &str = "Eth-Execution-Payload-Blinded"; pub const EXECUTION_PAYLOAD_VALUE_HEADER: &str = "Eth-Execution-Payload-Value"; -pub const CONSENSUS_PAYLOAD_VALUE_HEADER: &str = "Eth-Consensus-Payload-Value"; +pub const CONSENSUS_BLOCK_VALUE_HEADER: &str = "Eth-Consensus-Block-Value"; #[derive(Debug)] pub enum Error { From 4b1f396f2ae999e5d092fdd205fddca6e00bd413 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 5 Oct 2023 23:14:37 +0300 Subject: [PATCH 31/62] prevent setting the participation flag --- .../beacon_chain/src/beacon_block_reward.rs | 28 ++++++++++++------- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- .../http_api/src/standard_block_rewards.rs | 2 +- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index 786402c9978..1e34372da8d 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -25,6 +25,7 @@ impl BeaconChain { block: BeaconBlockRef<'_, T::EthSpec, Payload>, block_root: Hash256, state: &mut BeaconState, + set_participation_flag: bool, ) -> Result { if block.slot() != state.slot() { return Err(BeaconChainError::BlockRewardSlotError); @@ -71,15 +72,19 @@ impl BeaconChain { BeaconChainError::BlockRewardAttestationError })? } else { - self.compute_beacon_block_attestation_reward_altair(block, state) - .map_err(|e| { - error!( - self.log, - "Error calculating altair block attestation reward"; - "error" => ?e - ); - BeaconChainError::BlockRewardAttestationError - })? + self.compute_beacon_block_attestation_reward_altair( + block, + state, + set_participation_flag, + ) + .map_err(|e| { + error!( + self.log, + "Error calculating altair block attestation reward"; + "error" => ?e + ); + BeaconChainError::BlockRewardAttestationError + })? }; let total_reward = sync_aggregate_reward @@ -177,6 +182,7 @@ impl BeaconChain { &self, block: BeaconBlockRef<'_, T::EthSpec, Payload>, state: &mut BeaconState, + set_participation_flag: bool, ) -> Result { let total_active_balance = state.get_total_active_balance()?; let base_reward_per_increment = @@ -214,7 +220,9 @@ impl BeaconChain { if participation_flag_indices.contains(&flag_index) && !validator_participation.has_flag(flag_index)? { - validator_participation.add_flag(flag_index)?; + if set_participation_flag { + validator_participation.add_flag(flag_index)?; + } proposer_reward_numerator.safe_add_assign( altair::get_base_reward( state, diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 6ab3cc54e81..2dda8579636 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4746,7 +4746,7 @@ impl BeaconChain { let mut ctxt = ConsensusContext::new(block.slot()); let consensus_block_value = self - .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state.clone()) + .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state, false) .unwrap_or(StandardBlockReward { proposer_index: 0, total: 0, diff --git a/beacon_node/http_api/src/standard_block_rewards.rs b/beacon_node/http_api/src/standard_block_rewards.rs index de7e5eb7d3b..d6e8fc91a61 100644 --- a/beacon_node/http_api/src/standard_block_rewards.rs +++ b/beacon_node/http_api/src/standard_block_rewards.rs @@ -20,7 +20,7 @@ pub fn compute_beacon_block_rewards( let mut state = get_state_before_applying_block(chain.clone(), &block)?; let rewards = chain - .compute_beacon_block_reward(block_ref, block_root, &mut state) + .compute_beacon_block_reward(block_ref, block_root, &mut state, true) .map_err(beacon_chain_error)?; Ok((rewards, execution_optimistic, finalized)) From 518c6a003f981b423f921a1dfdf4870f532153df Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 6 Oct 2023 01:57:04 +0300 Subject: [PATCH 32/62] clone get_epoch_participation result --- .../beacon_chain/src/beacon_block_reward.rs | 14 ++++------- beacon_node/beacon_chain/src/beacon_chain.rs | 2 +- .../http_api/src/standard_block_rewards.rs | 2 +- consensus/types/src/beacon_state.rs | 24 +++++++++++++++++++ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index 1e34372da8d..cf746c12447 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -25,7 +25,6 @@ impl BeaconChain { block: BeaconBlockRef<'_, T::EthSpec, Payload>, block_root: Hash256, state: &mut BeaconState, - set_participation_flag: bool, ) -> Result { if block.slot() != state.slot() { return Err(BeaconChainError::BlockRewardSlotError); @@ -75,7 +74,6 @@ impl BeaconChain { self.compute_beacon_block_attestation_reward_altair( block, state, - set_participation_flag, ) .map_err(|e| { error!( @@ -181,8 +179,7 @@ impl BeaconChain { fn compute_beacon_block_attestation_reward_altair>( &self, block: BeaconBlockRef<'_, T::EthSpec, Payload>, - state: &mut BeaconState, - set_participation_flag: bool, + state: &BeaconState, ) -> Result { let total_active_balance = state.get_total_active_balance()?; let base_reward_per_increment = @@ -211,8 +208,9 @@ impl BeaconChain { for index in attesting_indices { let index = index as usize; for (flag_index, &weight) in PARTICIPATION_FLAG_WEIGHTS.iter().enumerate() { - let epoch_participation = - state.get_epoch_participation_mut(data.target.epoch)?; + let mut epoch_participation = + state.get_epoch_participation(data.target.epoch)?.clone(); + let validator_participation = epoch_participation .get_mut(index) .ok_or(BeaconStateError::ParticipationOutOfBounds(index))?; @@ -220,9 +218,7 @@ impl BeaconChain { if participation_flag_indices.contains(&flag_index) && !validator_participation.has_flag(flag_index)? { - if set_participation_flag { - validator_participation.add_flag(flag_index)?; - } + validator_participation.add_flag(flag_index)?; proposer_reward_numerator.safe_add_assign( altair::get_base_reward( state, diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 2dda8579636..c7bfd195b09 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -4746,7 +4746,7 @@ impl BeaconChain { let mut ctxt = ConsensusContext::new(block.slot()); let consensus_block_value = self - .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state, false) + .compute_beacon_block_reward(inner_block.to_ref(), Hash256::zero(), &mut state) .unwrap_or(StandardBlockReward { proposer_index: 0, total: 0, diff --git a/beacon_node/http_api/src/standard_block_rewards.rs b/beacon_node/http_api/src/standard_block_rewards.rs index d6e8fc91a61..de7e5eb7d3b 100644 --- a/beacon_node/http_api/src/standard_block_rewards.rs +++ b/beacon_node/http_api/src/standard_block_rewards.rs @@ -20,7 +20,7 @@ pub fn compute_beacon_block_rewards( let mut state = get_state_before_applying_block(chain.clone(), &block)?; let rewards = chain - .compute_beacon_block_reward(block_ref, block_root, &mut state, true) + .compute_beacon_block_reward(block_ref, block_root, &mut state) .map_err(beacon_chain_error)?; Ok((rewards, execution_optimistic, finalized)) diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 6a205e307ad..3c784aec389 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -1398,6 +1398,30 @@ impl BeaconState { } } + /// Get a reference to the epoch participation flags for `epoch`. + pub fn get_epoch_participation( + &self, + epoch: Epoch, + ) -> Result<&VariableList, Error> { + if epoch == self.current_epoch() { + match self { + BeaconState::Base(_) => Err(BeaconStateError::IncorrectStateVariant), + BeaconState::Altair(state) => Ok(&state.current_epoch_participation), + BeaconState::Merge(state) => Ok(&state.current_epoch_participation), + BeaconState::Capella(state) => Ok(&state.current_epoch_participation), + } + } else if epoch == self.previous_epoch() { + match self { + BeaconState::Base(_) => Err(BeaconStateError::IncorrectStateVariant), + BeaconState::Altair(state) => Ok(&state.previous_epoch_participation), + BeaconState::Merge(state) => Ok(&state.previous_epoch_participation), + BeaconState::Capella(state) => Ok(&state.previous_epoch_participation), + } + } else { + Err(BeaconStateError::EpochOutOfBounds) + } + } + /// Get the number of outstanding deposits. /// /// Returns `Err` if the state is invalid. From 0a70967c5e3c61d7288c5249d4f084b0d6144fad Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 6 Oct 2023 01:57:28 +0300 Subject: [PATCH 33/62] fmt --- .../beacon_chain/src/beacon_block_reward.rs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index cf746c12447..f693d5b3dc3 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -71,18 +71,15 @@ impl BeaconChain { BeaconChainError::BlockRewardAttestationError })? } else { - self.compute_beacon_block_attestation_reward_altair( - block, - state, - ) - .map_err(|e| { - error!( - self.log, - "Error calculating altair block attestation reward"; - "error" => ?e - ); - BeaconChainError::BlockRewardAttestationError - })? + self.compute_beacon_block_attestation_reward_altair(block, state) + .map_err(|e| { + error!( + self.log, + "Error calculating altair block attestation reward"; + "error" => ?e + ); + BeaconChainError::BlockRewardAttestationError + })? }; let total_reward = sync_aggregate_reward @@ -210,7 +207,7 @@ impl BeaconChain { for (flag_index, &weight) in PARTICIPATION_FLAG_WEIGHTS.iter().enumerate() { let mut epoch_participation = state.get_epoch_participation(data.target.epoch)?.clone(); - + let validator_participation = epoch_participation .get_mut(index) .ok_or(BeaconStateError::ParticipationOutOfBounds(index))?; From 1d7cbf01ccb4c9b3b3c3c681dda50ac7835cd98f Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 6 Oct 2023 11:26:24 +0300 Subject: [PATCH 34/62] clone epoch participation outside of the loop --- .../beacon_chain/src/beacon_block_reward.rs | 10 +++++--- consensus/types/src/beacon_state.rs | 24 ------------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_block_reward.rs b/beacon_node/beacon_chain/src/beacon_block_reward.rs index f693d5b3dc3..80a90fd3e51 100644 --- a/beacon_node/beacon_chain/src/beacon_block_reward.rs +++ b/beacon_node/beacon_chain/src/beacon_block_reward.rs @@ -200,13 +200,17 @@ impl BeaconChain { )?; let attesting_indices = get_attesting_indices_from_state(state, attestation)?; - + let mut current_epoch_participation = state.current_epoch_participation()?.clone(); + let mut previous_epoch_participation = state.previous_epoch_participation()?.clone(); let mut proposer_reward_numerator = 0; for index in attesting_indices { let index = index as usize; for (flag_index, &weight) in PARTICIPATION_FLAG_WEIGHTS.iter().enumerate() { - let mut epoch_participation = - state.get_epoch_participation(data.target.epoch)?.clone(); + let epoch_participation = if data.target.epoch == state.current_epoch() { + &mut current_epoch_participation + } else { + &mut previous_epoch_participation + }; let validator_participation = epoch_participation .get_mut(index) diff --git a/consensus/types/src/beacon_state.rs b/consensus/types/src/beacon_state.rs index 3c784aec389..6a205e307ad 100644 --- a/consensus/types/src/beacon_state.rs +++ b/consensus/types/src/beacon_state.rs @@ -1398,30 +1398,6 @@ impl BeaconState { } } - /// Get a reference to the epoch participation flags for `epoch`. - pub fn get_epoch_participation( - &self, - epoch: Epoch, - ) -> Result<&VariableList, Error> { - if epoch == self.current_epoch() { - match self { - BeaconState::Base(_) => Err(BeaconStateError::IncorrectStateVariant), - BeaconState::Altair(state) => Ok(&state.current_epoch_participation), - BeaconState::Merge(state) => Ok(&state.current_epoch_participation), - BeaconState::Capella(state) => Ok(&state.current_epoch_participation), - } - } else if epoch == self.previous_epoch() { - match self { - BeaconState::Base(_) => Err(BeaconStateError::IncorrectStateVariant), - BeaconState::Altair(state) => Ok(&state.previous_epoch_participation), - BeaconState::Merge(state) => Ok(&state.previous_epoch_participation), - BeaconState::Capella(state) => Ok(&state.previous_epoch_participation), - } - } else { - Err(BeaconStateError::EpochOutOfBounds) - } - } - /// Get the number of outstanding deposits. /// /// Returns `Err` if the state is invalid. From d2c7dba1cefe4a007bde21802915d473f020873b Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sat, 7 Oct 2023 18:23:49 +0300 Subject: [PATCH 35/62] add block v3 to vc --- validator_client/src/block_service.rs | 243 +++++++++++++++++++++++++- 1 file changed, 241 insertions(+), 2 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 094b85bf810..00112d1705f 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -22,8 +22,8 @@ use std::time::Duration; use tokio::sync::mpsc; use tokio::time::sleep; use types::{ - AbstractExecPayload, BlindedPayload, BlockType, EthSpec, FullPayload, Graffiti, PublicKeyBytes, - Slot, + AbstractExecPayload, BeaconBlock, BlindedPayload, BlockType, EthSpec, FullPayload, Graffiti, + PublicKeyBytes, Slot, }; #[derive(Debug)] @@ -407,6 +407,245 @@ impl BlockService { Ok(()) } + async fn handle_block_response>( + &self, + log: &Logger, + proposer_fallback: ProposerFallback, + slot: Slot, + current_slot: Slot, + graffiti: Option, + validator_pubkey: PublicKeyBytes, + proposer_index: Option, + block: BeaconBlock, + ) -> Result<(), BlockError> { + info!( + log, + "Received unsigned block"; + "slot" => slot.as_u64(), + ); + + info!( + log, + "Received unsigned block"; + "slot" => slot.as_u64(), + ); + + if proposer_index != Some(block.proposer_index()) { + return Err(BlockError::Recoverable( + "Proposer index does not match block proposer. Beacon chain re-orged".to_string(), + )); + } + + let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); + let signed_block = match self + .validator_store + .sign_block::(validator_pubkey, block, current_slot) + .await + { + Ok(block) => block, + Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { + // A pubkey can be missing when a validator was recently removed + // via the API. + warn!( + log, + "Missing pubkey for block"; + "info" => "a validator may have recently been removed from this VC", + "pubkey" => ?pubkey, + "slot" => ?slot + ); + return Ok(()); + } + Err(e) => { + return Err(BlockError::Recoverable(format!( + "Unable to sign block: {:?}", + e + ))) + } + }; + + let signing_time_ms = + Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); + + info!( + log, + "Publishing signed block"; + "slot" => slot.as_u64(), + "signing_time_ms" => signing_time_ms, + ); + + proposer_fallback + .first_success_try_proposers_first( + RequireSynced::No, + OfflineOnFailure::Yes, + |beacon_node| async { + let _post_timer = metrics::start_timer_vec( + &metrics::BLOCK_SERVICE_TIMES, + &[metrics::BEACON_BLOCK_HTTP_POST], + ); + match Payload::block_type() { + BlockType::Blinded => { + beacon_node + .post_beacon_blinded_blocks(&signed_block) + .await + .or_else(|e| handle_block_post_error(e, slot, log))?; + Ok::<_, BlockError>(()) + } + BlockType::Full => { + beacon_node + .post_beacon_blocks(&signed_block) + .await + .or_else(|e| handle_block_post_error(e, slot, log))?; + Ok::<_, BlockError>(()) + } + } + }, + ) + .await?; + + info!( + log, + "Successfully published block"; + "block_type" => ?Payload::block_type(), + "deposits" => signed_block.message().body().deposits().len(), + "attestations" => signed_block.message().body().attestations().len(), + "graffiti" => ?graffiti.map(|g| g.as_utf8_lossy()), + "slot" => signed_block.slot().as_u64(), + ); + + Ok(()) + } + + async fn publish_block_v3( + self, + slot: Slot, + validator_pubkey: PublicKeyBytes, + ) -> Result<(), BlockError> { + let log = self.context.log(); + let _timer = + metrics::start_timer_vec(&metrics::BLOCK_SERVICE_TIMES, &[metrics::BEACON_BLOCK]); + + let current_slot = self.slot_clock.now().ok_or_else(|| { + BlockError::Recoverable("Unable to determine current slot from clock".to_string()) + })?; + + let randao_reveal = match self + .validator_store + .randao_reveal(validator_pubkey, slot.epoch(E::slots_per_epoch())) + .await + { + Ok(signature) => signature.into(), + Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { + // A pubkey can be missing when a validator was recently removed + // via the API. + warn!( + log, + "Missing pubkey for block randao"; + "info" => "a validator may have recently been removed from this VC", + "pubkey" => ?pubkey, + "slot" => ?slot + ); + return Ok(()); + } + Err(e) => { + return Err(BlockError::Recoverable(format!( + "Unable to produce randao reveal signature: {:?}", + e + ))) + } + }; + + let graffiti = determine_graffiti( + &validator_pubkey, + log, + self.graffiti_file.clone(), + self.validator_store.graffiti(&validator_pubkey), + self.graffiti, + ); + + let randao_reveal_ref = &randao_reveal; + let proposer_index = self.validator_store.validator_index(&validator_pubkey); + let proposer_fallback = ProposerFallback { + beacon_nodes: self.beacon_nodes.clone(), + proposer_nodes: self.proposer_nodes.clone(), + }; + + info!( + log, + "Requesting unsigned block"; + "slot" => slot.as_u64(), + ); + + let deneb_fork_activated = self + .context + .eth2_config + .spec + .altair_fork_epoch + .and_then(|fork_epoch| { + let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); + Some(current_epoch >= fork_epoch) + }) + .unwrap_or(false); + + // Request block from first responsive beacon node. + // + // Try the proposer nodes last, since it's likely that they don't have a + // great view of attestations on the network. + let block_response = proposer_fallback + .first_success_try_proposers_last( + RequireSynced::No, + OfflineOnFailure::Yes, + |beacon_node| async move { + let _get_timer = metrics::start_timer_vec( + &metrics::BLOCK_SERVICE_TIMES, + &[metrics::BEACON_BLOCK_HTTP_GET], + ); + beacon_node + .get_validator_blocks_v3::(slot, randao_reveal_ref, graffiti.as_ref()) + .await + .map_err(|e| { + BlockError::Recoverable(format!( + "Error from beacon node when producing block: {:?}", + e + )) + }) + }, + ) + .await?; + + match block_response { + eth2::types::ForkVersionedBeaconBlockType::Full(block_response) => { + let block = block_response.data; + self.handle_block_response::>( + log, + proposer_fallback, + slot, + current_slot, + graffiti, + validator_pubkey, + proposer_index, + block, + ) + .await?; + } + eth2::types::ForkVersionedBeaconBlockType::Blinded(block_response) => { + let block: BeaconBlock> = block_response.data; + self.handle_block_response::>( + log, + proposer_fallback, + slot, + current_slot, + graffiti, + validator_pubkey, + proposer_index, + block, + ) + .await?; + } + } + + Ok(()) + } + /// Produce a block at the given slot for validator_pubkey async fn publish_block>( self, From 33f34116515ab65493382bd1d84767574f7ad007 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sat, 7 Oct 2023 18:52:14 +0300 Subject: [PATCH 36/62] add v3 logic into vc --- validator_client/src/block_service.rs | 161 ++++++++++++++++---------- 1 file changed, 101 insertions(+), 60 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 00112d1705f..d4afb911330 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -334,20 +334,30 @@ impl BlockService { ) } - for validator_pubkey in proposers { - let builder_proposals = self - .validator_store - .get_builder_proposals(&validator_pubkey); - let service = self.clone(); - let log = log.clone(); - self.inner.context.executor.spawn( - async move { - if builder_proposals { + let deneb_fork_activated = self + .context + .eth2_config + .spec + .altair_fork_epoch + .and_then(|fork_epoch| { + let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); + Some(current_epoch >= fork_epoch) + }) + .unwrap_or(false); + + if deneb_fork_activated { + for validator_pubkey in proposers { + let service = self.clone(); + let log = log.clone(); + self.inner.context.executor.spawn( + async move { let result = service .clone() - .publish_block::>(slot, validator_pubkey) + .publish_block_v3(slot, validator_pubkey) .await; + match result { + Ok(_) => {} Err(BlockError::Recoverable(e)) => { error!( log, @@ -356,52 +366,92 @@ impl BlockService { "block_slot" => ?slot, "info" => "blinded proposal failed, attempting full block" ); - if let Err(e) = service - .publish_block::>(slot, validator_pubkey) - .await - { - // Log a `crit` since a full block - // (non-builder) proposal failed. - crit!( + } + Err(BlockError::Irrecoverable(e)) => { + error!( + log, + "Error whilst producing block"; + "error" => ?e, + "block_slot" => ?slot, + "info" => "this error may or may not result in a missed block", + ); + } + } + }, + "block service", + ) + } + } else { + for validator_pubkey in proposers { + let builder_proposals = self + .validator_store + .get_builder_proposals(&validator_pubkey); + let service = self.clone(); + let log = log.clone(); + self.inner.context.executor.spawn( + async move { + if builder_proposals { + let result = service + .clone() + .publish_block::>(slot, validator_pubkey) + .await; + + match result { + Err(BlockError::Recoverable(e)) => { + error!( log, "Error whilst producing block"; "error" => ?e, "block_slot" => ?slot, - "info" => "full block attempted after a blinded failure", + "info" => "blinded proposal failed, attempting full block" ); + if let Err(e) = service + .publish_block::>(slot, validator_pubkey) + .await + { + // Log a `crit` since a full block + // (non-builder) proposal failed. + crit!( + log, + "Error whilst producing block"; + "error" => ?e, + "block_slot" => ?slot, + "info" => "full block attempted after a blinded failure", + ); + } } - } - Err(BlockError::Irrecoverable(e)) => { - // Only log an `error` since it's common for - // builders to timeout on their response, only - // to publish the block successfully themselves. - error!( + Err(BlockError::Irrecoverable(e)) => { + // Only log an `error` since it's common for + // builders to timeout on their response, only + // to publish the block successfully themselves. + error!( + log, + "Error whilst producing block"; + "error" => ?e, + "block_slot" => ?slot, + "info" => "this error may or may not result in a missed block", + ) + } + Ok(_) => {} + }; + } else if let Err(e) = service + .publish_block::>(slot, validator_pubkey) + .await + { + // Log a `crit` since a full block (non-builder) + // proposal failed. + crit!( log, "Error whilst producing block"; - "error" => ?e, + "message" => ?e, "block_slot" => ?slot, - "info" => "this error may or may not result in a missed block", - ) + "info" => "proposal did not use a builder", + ); } - Ok(_) => {} - }; - } else if let Err(e) = service - .publish_block::>(slot, validator_pubkey) - .await - { - // Log a `crit` since a full block (non-builder) - // proposal failed. - crit!( - log, - "Error whilst producing block"; - "message" => ?e, - "block_slot" => ?slot, - "info" => "proposal did not use a builder", - ); - } - }, - "block service", - ); + }, + "block service", + ) + } } Ok(()) @@ -575,17 +625,6 @@ impl BlockService { "slot" => slot.as_u64(), ); - let deneb_fork_activated = self - .context - .eth2_config - .spec - .altair_fork_epoch - .and_then(|fork_epoch| { - let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); - Some(current_epoch >= fork_epoch) - }) - .unwrap_or(false); - // Request block from first responsive beacon node. // // Try the proposer nodes last, since it's likely that they don't have a @@ -599,7 +638,7 @@ impl BlockService { &metrics::BLOCK_SERVICE_TIMES, &[metrics::BEACON_BLOCK_HTTP_GET], ); - beacon_node + let block_response = beacon_node .get_validator_blocks_v3::(slot, randao_reveal_ref, graffiti.as_ref()) .await .map_err(|e| { @@ -607,10 +646,12 @@ impl BlockService { "Error from beacon node when producing block: {:?}", e )) - }) + }); + + Ok::<_, BlockError>(block_response) }, ) - .await?; + .await??; match block_response { eth2::types::ForkVersionedBeaconBlockType::Full(block_response) => { From a8ded56213ba29e2cbffcc96e2021b5401119b28 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 9 Oct 2023 16:34:26 +0300 Subject: [PATCH 37/62] add produce-block-v3 --- lighthouse/tests/validator_client.rs | 15 +++++++++++++++ validator_client/src/block_service.rs | 15 +++------------ validator_client/src/cli.rs | 8 ++++++++ validator_client/src/config.rs | 7 +++++++ validator_client/src/validator_store.rs | 6 ++++++ 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/lighthouse/tests/validator_client.rs b/lighthouse/tests/validator_client.rs index 062b7e7786a..4420a980616 100644 --- a/lighthouse/tests/validator_client.rs +++ b/lighthouse/tests/validator_client.rs @@ -427,6 +427,21 @@ fn no_doppelganger_protection_flag() { .run() .with_config(|config| assert!(!config.enable_doppelganger_protection)); } +#[test] +fn produce_block_v3_flag() { + CommandLineTest::new() + .flag("produce-block-v3", None) + .run() + .with_config(|config| assert!(config.produce_block_v3)); +} + +#[test] +fn no_produce_block_v3_flag() { + CommandLineTest::new() + .run() + .with_config(|config| assert!(!config.produce_block_v3)); +} + #[test] fn block_delay_ms() { CommandLineTest::new() diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index d4afb911330..a05fe3a480c 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -334,18 +334,8 @@ impl BlockService { ) } - let deneb_fork_activated = self - .context - .eth2_config - .spec - .altair_fork_epoch - .and_then(|fork_epoch| { - let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); - Some(current_epoch >= fork_epoch) - }) - .unwrap_or(false); - - if deneb_fork_activated { + // TODO: activate automatically at Deneb + if !self.validator_store.produce_block_v3() { for validator_pubkey in proposers { let service = self.clone(); let log = log.clone(); @@ -457,6 +447,7 @@ impl BlockService { Ok(()) } + #[allow(clippy::too_many_arguments)] async fn handle_block_response>( &self, log: &Logger, diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index 0af92a9e39a..4aa0eb6f987 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -153,6 +153,14 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .value_name("FEE-RECIPIENT") .takes_value(true) ) + .arg( + Arg::with_name("produce-block-v3") + .long("produce-block-v3") + .help("Enable block production via the block v3 endpoint for this validator client. \ + This should only be enabled when paired with a beacon node \ + that has this endpoint implemented.") + .takes_value(false) + ) /* REST API related arguments */ .arg( Arg::with_name("http") diff --git a/validator_client/src/config.rs b/validator_client/src/config.rs index 7c662db9371..a90bc21fcf0 100644 --- a/validator_client/src/config.rs +++ b/validator_client/src/config.rs @@ -79,6 +79,8 @@ pub struct Config { pub enable_latency_measurement_service: bool, /// Defines the number of validators per `validator/register_validator` request sent to the BN. pub validator_registration_batch_size: usize, + /// Enables block production via the block v3 endpoint. This configuration option can be removed post deneb. + pub produce_block_v3: bool, } impl Default for Config { @@ -120,6 +122,7 @@ impl Default for Config { disable_run_on_all: false, enable_latency_measurement_service: true, validator_registration_batch_size: 500, + produce_block_v3: false, } } } @@ -361,6 +364,10 @@ impl Config { config.builder_proposals = true; } + if cli_args.is_present("produce-block-v3") { + config.produce_block_v3 = true; + } + config.gas_limit = cli_args .value_of("gas-limit") .map(|gas_limit| { diff --git a/validator_client/src/validator_store.rs b/validator_client/src/validator_store.rs index 365f7f73474..703b6901b3c 100644 --- a/validator_client/src/validator_store.rs +++ b/validator_client/src/validator_store.rs @@ -97,6 +97,7 @@ pub struct ValidatorStore { fee_recipient_process: Option
, gas_limit: Option, builder_proposals: bool, + produce_block_v3: bool, task_executor: TaskExecutor, _phantom: PhantomData, } @@ -128,6 +129,7 @@ impl ValidatorStore { fee_recipient_process: config.fee_recipient, gas_limit: config.gas_limit, builder_proposals: config.builder_proposals, + produce_block_v3: config.produce_block_v3, task_executor, _phantom: PhantomData, } @@ -336,6 +338,10 @@ impl ValidatorStore { self.spec.fork_at_epoch(epoch) } + pub fn produce_block_v3(&self) -> bool { + self.produce_block_v3 + } + /// Returns a `SigningMethod` for `validator_pubkey` *only if* that validator is considered safe /// by doppelganger protection. fn doppelganger_checked_signing_method( From 1667b32aa82b3e1046a2732c51975040ca7541c7 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sat, 14 Oct 2023 23:23:22 +0300 Subject: [PATCH 38/62] refactor based on feedback --- beacon_node/execution_layer/src/lib.rs | 193 +++++------------- .../src/test_utils/mock_builder.rs | 17 +- .../src/test_utils/mock_execution_layer.rs | 47 ++++- 3 files changed, 108 insertions(+), 149 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index d28e5fbb33d..604ba2dbf29 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -106,6 +106,7 @@ pub enum Error { InvalidForkForPayload, InvalidPayloadBody(String), BeaconStateError(BeaconStateError), + PayloadTypeMismatch, } impl From for Error { @@ -134,6 +135,23 @@ pub enum BlockProposalContents> { }, } +impl From>> + for BlockProposalContents> +{ + fn from(item: BlockProposalContents>) -> Self { + let block_value = item.block_value().to_owned(); + + let blinded_payload: BlockProposalContents> = + BlockProposalContents::Payload { + payload: item.to_payload().execution_payload().into(), + block_value, + _phantom: PhantomData, + }; + + blinded_payload + } +} + impl> BlockProposalContents { pub fn payload(&self) -> &Payload { match self { @@ -703,7 +721,7 @@ impl ExecutionLayer { .await? } BlockProductionVersion::FullV2 => self - .get_full_payload_with_v3( + .get_full_payload_with( parent_hash, payload_attributes, forkchoice_update_params, @@ -729,7 +747,13 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_GET_PAYLOAD_SOURCE, &[metrics::LOCAL], ); - Ok(BlockProposalContentsType::Full(block_proposal_contents)) + if matches!(block_production_version, BlockProductionVersion::BlindedV2) { + Ok(BlockProposalContentsType::Blinded( + block_proposal_contents.into(), + )) + } else { + Ok(BlockProposalContentsType::Full(block_proposal_contents)) + } } BlockProposalContentsType::Blinded(block_proposal_contents) => { metrics::inc_counter_vec( @@ -768,7 +792,7 @@ impl ExecutionLayer { ); // Wait for the builder *and* local EL to produce a payload (or return an error). - let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( + let ((relay_result, relay_duration), (local_result_type, local_duration)) = tokio::join!( timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { builder .get_builder_header::>( @@ -779,7 +803,7 @@ impl ExecutionLayer { .await }), timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { - self.get_full_payload_caching::>( + self.get_full_payload_caching( parent_hash, payload_attributes, forkchoice_update_params, @@ -789,6 +813,11 @@ impl ExecutionLayer { }) ); + let local_result = match local_result_type? { + BlockProposalContentsType::Full(payload) => Ok(payload), + BlockProposalContentsType::Blinded(_) => Err(Error::PayloadTypeMismatch), + }; + info!( self.log(), "Requested blinded execution payload"; @@ -1016,7 +1045,7 @@ impl ExecutionLayer { ), } } - self.get_full_payload_caching_v3( + self.get_full_payload_caching( parent_hash, payload_attributes, forkchoice_update_params, @@ -1050,7 +1079,7 @@ impl ExecutionLayer { ); // Wait for the builder *and* local EL to produce a payload (or return an error). - let ((relay_result, relay_duration), (local_result, local_duration)) = tokio::join!( + let ((relay_result, relay_duration), (local_result_type, local_duration)) = tokio::join!( timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { builder .get_builder_header::>( @@ -1061,7 +1090,7 @@ impl ExecutionLayer { .await }), timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { - self.get_full_payload_caching::>( + self.get_full_payload_caching( parent_hash, payload_attributes, forkchoice_update_params, @@ -1071,6 +1100,12 @@ impl ExecutionLayer { }) ); + let local_result: Result>, Error> = + match local_result_type? { + BlockProposalContentsType::Full(payload) => Ok(payload.into()), + BlockProposalContentsType::Blinded(payload) => Ok(payload), + }; + info!( self.log(), "Requested blinded execution payload"; @@ -1298,46 +1333,32 @@ impl ExecutionLayer { ), } } - println!("YOOOO"); - let payload = self - .get_full_payload_caching::>( + let payload_type = self + .get_full_payload_caching( parent_hash, payload_attributes, forkchoice_update_params, current_fork, ) .await?; - Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(payload), - )) + match payload_type { + BlockProposalContentsType::Full(payload) => Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(payload.into()), + )), + BlockProposalContentsType::Blinded(payload) => Ok(ProvenancedPayload::Local( + BlockProposalContentsType::Blinded(payload), + )), + } } /// Get a full payload and cache its result in the execution layer's payload cache. - async fn get_full_payload_caching_v3( + async fn get_full_payload_caching( &self, parent_hash: ExecutionBlockHash, payload_attributes: &PayloadAttributes, forkchoice_update_params: ForkchoiceUpdateParameters, current_fork: ForkName, ) -> Result, Error> { - self.get_full_payload_with_v3( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - Self::cache_payload, - ) - .await - } - - /// Get a full payload and cache its result in the execution layer's payload cache. - async fn get_full_payload_caching>( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - current_fork: ForkName, - ) -> Result, Error> { self.get_full_payload_with( parent_hash, payload_attributes, @@ -1348,7 +1369,7 @@ impl ExecutionLayer { .await } - async fn get_full_payload_with_v3( + async fn get_full_payload_with( &self, parent_hash: ExecutionBlockHash, payload_attributes: &PayloadAttributes, @@ -1454,112 +1475,6 @@ impl ExecutionLayer { .map_err(Error::EngineError) } - async fn get_full_payload_with>( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - current_fork: ForkName, - f: fn(&ExecutionLayer, ExecutionPayloadRef) -> Option>, - ) -> Result, Error> { - self.engine() - .request(move |engine| async move { - let payload_id = if let Some(id) = engine - .get_payload_id(&parent_hash, payload_attributes) - .await - { - // The payload id has been cached for this engine. - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_PRE_PREPARED_PAYLOAD_ID, - &[metrics::HIT], - ); - id - } else { - // The payload id has *not* been cached. Trigger an artificial - // fork choice update to retrieve a payload ID. - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_PRE_PREPARED_PAYLOAD_ID, - &[metrics::MISS], - ); - let fork_choice_state = ForkchoiceState { - head_block_hash: parent_hash, - safe_block_hash: forkchoice_update_params - .justified_hash - .unwrap_or_else(ExecutionBlockHash::zero), - finalized_block_hash: forkchoice_update_params - .finalized_hash - .unwrap_or_else(ExecutionBlockHash::zero), - }; - - let response = engine - .notify_forkchoice_updated( - fork_choice_state, - Some(payload_attributes.clone()), - self.log(), - ) - .await?; - - match response.payload_id { - Some(payload_id) => payload_id, - None => { - error!( - self.log(), - "Exec engine unable to produce payload"; - "msg" => "No payload ID, the engine is likely syncing. \ - This has the potential to cause a missed block proposal.", - "status" => ?response.payload_status - ); - return Err(ApiError::PayloadIdUnavailable); - } - } - }; - - let payload_fut = async { - debug!( - self.log(), - "Issuing engine_getPayload"; - "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(), - "prev_randao" => ?payload_attributes.prev_randao(), - "timestamp" => payload_attributes.timestamp(), - "parent_hash" => ?parent_hash, - ); - engine.api.get_payload::(current_fork, payload_id).await - }; - let payload_response = payload_fut.await; - let (execution_payload, block_value) = payload_response.map(|payload_response| { - if payload_response.execution_payload_ref().fee_recipient() != payload_attributes.suggested_fee_recipient() { - error!( - self.log(), - "Inconsistent fee recipient"; - "msg" => "The fee recipient returned from the Execution Engine differs \ - from the suggested_fee_recipient set on the beacon node. This could \ - indicate that fees are being diverted to another address. Please \ - ensure that the value of suggested_fee_recipient is set correctly and \ - that the Execution Engine is trusted.", - "fee_recipient" => ?payload_response.execution_payload_ref().fee_recipient(), - "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(), - ); - } - if f(self, payload_response.execution_payload_ref()).is_some() { - warn!( - self.log(), - "Duplicate payload cached, this might indicate redundant proposal \ - attempts." - ); - } - payload_response.into() - })?; - Ok(BlockProposalContents::Payload { - payload: execution_payload.into(), - block_value, - _phantom: PhantomData, - }) - }) - .await - .map_err(Box::new) - .map_err(Error::EngineError) - } - /// Maps to the `engine_newPayload` JSON-RPC call. pub async fn notify_new_payload( &self, diff --git a/beacon_node/execution_layer/src/test_utils/mock_builder.rs b/beacon_node/execution_layer/src/test_utils/mock_builder.rs index 2d3cc27eb1d..3252c0156a7 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_builder.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_builder.rs @@ -455,18 +455,25 @@ pub fn serve( finalized_hash: Some(finalized_execution_hash), }; - let payload = builder + let payload_type = builder .el - .get_full_payload_caching::>( + .get_full_payload_caching( head_execution_hash, &payload_attributes, forkchoice_update_params, fork, ) .await - .map_err(|_| reject("couldn't get payload"))? - .to_payload() - .to_execution_payload_header(); + .map_err(|_| reject("couldn't get payload"))?; + + let payload = match payload_type { + crate::BlockProposalContentsType::Full(payload) => { + payload.to_payload().to_execution_payload_header() + } + crate::BlockProposalContentsType::Blinded(payload) => { + payload.to_payload().to_execution_payload_header() + } + }; let mut message = BuilderBid { header: BlindedPayload::from(payload), diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 7d27838f63a..4f90321ba7a 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -5,6 +5,7 @@ use crate::{ }, Config, *, }; +use keccak_hash::H256; use sensitive_url::SensitiveUrl; use task_executor::TaskExecutor; use tempfile::NamedTempFile; @@ -186,11 +187,49 @@ impl MockExecutionLayer { .await .unwrap(); - let payload_header = match block_proposal_content_type { - BlockProposalContentsType::Full(_) => panic!("Should always be a blinded payload"), - BlockProposalContentsType::Blinded(block) => block.to_payload(), + match block_proposal_content_type { + BlockProposalContentsType::Full(block) => { + let payload_header = block.to_payload(); + self.assert_valid_execution_payload_on_head( + payload, + payload_header, + block_hash, + parent_hash, + block_number, + timestamp, + prev_randao, + ) + .await; + } + BlockProposalContentsType::Blinded(block) => { + let payload_header = block.to_payload(); + self.assert_valid_execution_payload_on_head( + payload, + payload_header, + block_hash, + parent_hash, + block_number, + timestamp, + prev_randao, + ) + .await; + } }; + self + } + + #[allow(clippy::too_many_arguments)] + pub async fn assert_valid_execution_payload_on_head>( + &self, + payload: ExecutionPayload, + payload_header: Payload, + block_hash: ExecutionBlockHash, + parent_hash: ExecutionBlockHash, + block_number: u64, + timestamp: u64, + prev_randao: H256, + ) { assert_eq!(payload_header.block_hash(), block_hash); assert_eq!(payload_header.parent_hash(), parent_hash); assert_eq!(payload_header.block_number(), block_number); @@ -229,8 +268,6 @@ impl MockExecutionLayer { assert_eq!(head_execution_block.block_number(), block_number); assert_eq!(head_execution_block.block_hash(), block_hash); assert_eq!(head_execution_block.parent_hash(), parent_hash); - - self } pub fn move_to_block_prior_to_terminal_block(self) -> Self { From 4d3621e8e0a29b6cc77f6ac2a0da8fda21850ffa Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 15 Oct 2023 00:09:31 +0300 Subject: [PATCH 39/62] update --- beacon_node/execution_layer/src/lib.rs | 298 +------------------------ 1 file changed, 1 insertion(+), 297 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 604ba2dbf29..39aa865dbfd 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -710,7 +710,7 @@ impl ExecutionLayer { &metrics::EXECUTION_LAYER_REQUEST_TIMES, &[metrics::GET_BLINDED_PAYLOAD], ); - self.get_blinded_payload_v2( + self.determine_and_fetch_payload( parent_hash, payload_attributes, forkchoice_update_params, @@ -1055,302 +1055,6 @@ impl ExecutionLayer { .map(ProvenancedPayload::Local) } - async fn get_blinded_payload_v2( - &self, - parent_hash: ExecutionBlockHash, - payload_attributes: &PayloadAttributes, - forkchoice_update_params: ForkchoiceUpdateParameters, - builder_params: BuilderParams, - current_fork: ForkName, - spec: &ChainSpec, - ) -> Result>, Error> { - if let Some(builder) = self.builder() { - let slot = builder_params.slot; - let pubkey = builder_params.pubkey; - - match builder_params.chain_health { - ChainHealth::Healthy => { - info!( - self.log(), - "Requesting blinded header from connected builder"; - "slot" => ?slot, - "pubkey" => ?pubkey, - "parent_hash" => ?parent_hash, - ); - - // Wait for the builder *and* local EL to produce a payload (or return an error). - let ((relay_result, relay_duration), (local_result_type, local_duration)) = tokio::join!( - timed_future(metrics::GET_BLINDED_PAYLOAD_BUILDER, async { - builder - .get_builder_header::>( - slot, - parent_hash, - &pubkey, - ) - .await - }), - timed_future(metrics::GET_BLINDED_PAYLOAD_LOCAL, async { - self.get_full_payload_caching( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await - }) - ); - - let local_result: Result>, Error> = - match local_result_type? { - BlockProposalContentsType::Full(payload) => Ok(payload.into()), - BlockProposalContentsType::Blinded(payload) => Ok(payload), - }; - - info!( - self.log(), - "Requested blinded execution payload"; - "relay_fee_recipient" => match &relay_result { - Ok(Some(r)) => format!("{:?}", r.data.message.header.fee_recipient()), - Ok(None) => "empty response".to_string(), - Err(_) => "request failed".to_string(), - }, - "relay_response_ms" => relay_duration.as_millis(), - "local_fee_recipient" => match &local_result { - Ok(proposal_contents) => format!("{:?}", proposal_contents.payload().fee_recipient()), - Err(_) => "request failed".to_string() - }, - "local_response_ms" => local_duration.as_millis(), - "parent_hash" => ?parent_hash, - ); - - return match (relay_result, local_result) { - (Err(e), Ok(local)) => { - warn!( - self.log(), - "Builder error when requesting payload"; - "info" => "falling back to local execution client", - "relay_error" => ?e, - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(local), - )) - } - (Ok(None), Ok(local)) => { - info!( - self.log(), - "Builder did not return a payload"; - "info" => "falling back to local execution client", - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(local), - )) - } - (Ok(Some(relay)), Ok(local)) => { - let header = &relay.data.message.header; - - info!( - self.log(), - "Received local and builder payloads"; - "relay_block_hash" => ?header.block_hash(), - "local_block_hash" => ?local.payload().block_hash(), - "parent_hash" => ?parent_hash, - ); - - let relay_value = relay.data.message.value; - let local_value = *local.block_value(); - if !self.inner.always_prefer_builder_payload { - if local_value >= relay_value { - info!( - self.log(), - "Local block is more profitable than relay block"; - "local_block_value" => %local_value, - "relay_value" => %relay_value - ); - return Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(local), - )); - } else { - info!( - self.log(), - "Relay block is more profitable than local block"; - "local_block_value" => %local_value, - "relay_value" => %relay_value - ); - } - } - - match verify_builder_bid( - &relay, - parent_hash, - payload_attributes, - Some(local.payload().block_number()), - self.inner.builder_profit_threshold, - current_fork, - spec, - ) { - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - Err(reason) if !reason.payload_invalid() => { - info!( - self.log(), - "Builder payload ignored"; - "info" => "using local payload", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(local), - )) - } - Err(reason) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, - &[reason.as_ref().as_ref()], - ); - warn!( - self.log(), - "Builder returned invalid payload"; - "info" => "using local payload", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(local), - )) - } - } - } - (Ok(Some(relay)), Err(local_error)) => { - let header = &relay.data.message.header; - - info!( - self.log(), - "Received builder payload with local error"; - "relay_block_hash" => ?header.block_hash(), - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - match verify_builder_bid( - &relay, - parent_hash, - payload_attributes, - None, - self.inner.builder_profit_threshold, - current_fork, - spec, - ) { - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - // If the payload is valid then use it. The local EE failed - // to produce a payload so we have no alternative. - Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - Err(reason) => { - metrics::inc_counter_vec( - &metrics::EXECUTION_LAYER_GET_PAYLOAD_BUILDER_REJECTIONS, - &[reason.as_ref().as_ref()], - ); - crit!( - self.log(), - "Builder returned invalid payload"; - "info" => "no local payload either - unable to propose block", - "reason" => %reason, - "relay_block_hash" => ?header.block_hash(), - "parent_hash" => ?parent_hash, - ); - Err(Error::CannotProduceHeader) - } - } - } - (Err(relay_error), Err(local_error)) => { - crit!( - self.log(), - "Unable to produce execution payload"; - "info" => "the local EL and builder both failed - unable to propose block", - "relay_error" => ?relay_error, - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - Err(Error::CannotProduceHeader) - } - (Ok(None), Err(local_error)) => { - crit!( - self.log(), - "Unable to produce execution payload"; - "info" => "the local EL failed and the builder returned nothing - \ - the block proposal will be missed", - "local_error" => ?local_error, - "parent_hash" => ?parent_hash, - ); - - Err(Error::CannotProduceHeader) - } - }; - } - ChainHealth::Unhealthy(condition) => info!( - self.log(), - "Chain is unhealthy, using local payload"; - "info" => "this helps protect the network. the --builder-fallback flags \ - can adjust the expected health conditions.", - "failed_condition" => ?condition - ), - // Intentional no-op, so we never attempt builder API proposals pre-merge. - ChainHealth::PreMerge => (), - ChainHealth::Optimistic => info!( - self.log(), - "Chain is optimistic; can't build payload"; - "info" => "the local execution engine is syncing and the builder network \ - cannot safely be used - unable to propose block" - ), - } - } - let payload_type = self - .get_full_payload_caching( - parent_hash, - payload_attributes, - forkchoice_update_params, - current_fork, - ) - .await?; - match payload_type { - BlockProposalContentsType::Full(payload) => Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(payload.into()), - )), - BlockProposalContentsType::Blinded(payload) => Ok(ProvenancedPayload::Local( - BlockProposalContentsType::Blinded(payload), - )), - } - } - /// Get a full payload and cache its result in the execution layer's payload cache. async fn get_full_payload_caching( &self, From 59e1a18288a10d978f8f4aff932aec835f9461c3 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 22 Oct 2023 00:06:05 +0300 Subject: [PATCH 40/62] remove comments --- beacon_node/execution_layer/src/lib.rs | 35 -------------------------- 1 file changed, 35 deletions(-) diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index d10ce048855..5ff9735a762 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -1085,18 +1085,6 @@ impl ExecutionLayer { current_fork, spec, ) { - /* - // TODO - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - */ Ok(()) => Ok(ProvenancedPayload::try_from(relay.data.message)?), Err(reason) if !reason.payload_invalid() => { info!( @@ -1150,29 +1138,6 @@ impl ExecutionLayer { current_fork, spec, ) { - /* - // TODO - Ok(()) => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - // If the payload is valid then use it. The local EE failed - // to produce a payload so we have no alternative. - Err(e) if !e.payload_invalid() => Ok(ProvenancedPayload::Builder( - BlockProposalContentsType::Blinded( - BlockProposalContents::Payload { - payload: relay.data.message.header, - block_value: relay.data.message.value, - _phantom: PhantomData, - }, - ), - )), - */ Ok(()) => Ok(ProvenancedPayload::try_from(relay.data.message)?), // If the payload is valid then use it. The local EE failed // to produce a payload so we have no alternative. From 34a08a183d210441b4c70cd91b552c4669bb12d6 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 22 Oct 2023 01:24:41 +0300 Subject: [PATCH 41/62] refactor --- .../http_api/src/build_block_contents.rs | 91 +++-- beacon_node/http_api/src/validator.rs | 331 ++++++------------ .../http_api/tests/interactive_tests.rs | 4 +- 3 files changed, 139 insertions(+), 287 deletions(-) diff --git a/beacon_node/http_api/src/build_block_contents.rs b/beacon_node/http_api/src/build_block_contents.rs index c8f28fa9ae3..f59a4b52152 100644 --- a/beacon_node/http_api/src/build_block_contents.rs +++ b/beacon_node/http_api/src/build_block_contents.rs @@ -1,62 +1,51 @@ use beacon_chain::BlockProductionError; use eth2::types::{BeaconBlockAndBlobSidecars, BlindedBeaconBlockAndBlobSidecars, BlockContents}; -use types::{ - BeaconBlock, BlindedBlobSidecarList, BlindedPayload, BlobSidecarList, EthSpec, ForkName, - FullPayload, -}; - +use types::{AbstractExecPayload, BeaconBlock, EthSpec, ForkName, SidecarList}; type Error = warp::reject::Rejection; -type FullBlockContents = BlockContents>; -type BlindedBlockContents = BlockContents>; -pub fn build_block_contents( +pub fn build_block_contents>( fork_name: ForkName, - block: BeaconBlock>, - maybe_blobs: Option>, -) -> Result, Error> { - match fork_name { - ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { - Ok(BlockContents::Block(block)) - } - ForkName::Deneb => { - if let Some(blob_sidecars) = maybe_blobs { - let block_and_blobs = BeaconBlockAndBlobSidecars { - block, - blob_sidecars, - }; - - Ok(BlockContents::BlockAndBlobSidecars(block_and_blobs)) - } else { - Err(warp_utils::reject::block_production_error( - BlockProductionError::MissingBlobs, - )) + block: BeaconBlock, + maybe_blobs: Option>::Sidecar>>, +) -> Result, Error> { + match Payload::block_type() { + types::BlockType::Blinded => match fork_name { + ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { + Ok(BlockContents::Block(block)) } - } - } -} + ForkName::Deneb => { + if let Some(blinded_blob_sidecars) = maybe_blobs { + let block_and_blobs = BlindedBeaconBlockAndBlobSidecars { + blinded_block: block, + blinded_blob_sidecars, + }; -pub fn build_blinded_block_contents( - fork_name: ForkName, - block: BeaconBlock>, - maybe_blobs: Option>, -) -> Result, Error> { - match fork_name { - ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { - Ok(BlockContents::Block(block)) - } - ForkName::Deneb => { - if let Some(blinded_blob_sidecars) = maybe_blobs { - let block_and_blobs = BlindedBeaconBlockAndBlobSidecars { - blinded_block: block, - blinded_blob_sidecars, - }; + Ok(BlockContents::BlindedBlockAndBlobSidecars(block_and_blobs)) + } else { + Err(warp_utils::reject::block_production_error( + BlockProductionError::MissingBlobs, + )) + } + } + }, + types::BlockType::Full => match fork_name { + ForkName::Base | ForkName::Altair | ForkName::Merge | ForkName::Capella => { + Ok(BlockContents::Block(block)) + } + ForkName::Deneb => { + if let Some(blob_sidecars) = maybe_blobs { + let block_and_blobs = BeaconBlockAndBlobSidecars { + block, + blob_sidecars, + }; - Ok(BlockContents::BlindedBlockAndBlobSidecars(block_and_blobs)) - } else { - Err(warp_utils::reject::block_production_error( - BlockProductionError::MissingBlobs, - )) + Ok(BlockContents::BlockAndBlobSidecars(block_and_blobs)) + } else { + Err(warp_utils::reject::block_production_error( + BlockProductionError::MissingBlobs, + )) + } } - } + }, } } diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index eebf20ebb8c..91d4ca37b21 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use types::{payload::BlockProductionVersion, *}; use beacon_chain::{ - BeaconBlockResponseType, BeaconChain, BeaconChainError, BeaconChainTypes, + BeaconBlockResponse, BeaconBlockResponseType, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, }; use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; @@ -58,7 +58,7 @@ pub fn get_randao_verification( Ok(randao_verification) } -pub async fn produce_blinded_block_v2( +pub async fn produce_block_v3( endpoint_version: EndpointVersion, accept_header: Option, chain: Arc>, @@ -73,41 +73,81 @@ pub async fn produce_blinded_block_v2( })?; let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + let block_response_type = chain .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), randao_verification, - BlockProductionVersion::BlindedV2, + BlockProductionVersion::V3, ) .await - .map_err(warp_utils::reject::block_production_error)?; + .map_err(|e| { + warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) + })?; - build_response_v2(chain, block_response_type, endpoint_version, accept_header) + match block_response_type { + BeaconBlockResponseType::Full(block_response) => { + build_response_v3(chain, block_response, endpoint_version, accept_header, true) + } + BeaconBlockResponseType::Blinded(block_response) => build_response_v3( + chain, + block_response, + endpoint_version, + accept_header, + false, + ), + } } -pub async fn produce_block_v3( +pub fn build_response_v3>( + chain: Arc>, + block_response: BeaconBlockResponse, endpoint_version: EndpointVersion, accept_header: Option, - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, + execution_payload_blinded: bool, ) -> Result, warp::Rejection> { - if let Some(accept_header_type) = accept_header { - match accept_header_type { - api_types::Accept::Json | api_types::Accept::Any => { - determine_and_produce_block_json(endpoint_version, chain, slot, query).await - } - api_types::Accept::Ssz => determine_and_produce_block_ssz(chain, slot, query).await, - } - } else { - determine_and_produce_block_json(endpoint_version, chain, slot, query).await + let fork_name = block_response + .block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + let block_contents = build_block_contents::build_block_contents( + fork_name, + block_response.block, + block_response.maybe_side_car, + )?; + + match accept_header { + Some(api_types::Accept::Ssz) => Response::builder() + .status(200) + .header("Content-Type", "application/ssz") + .body(block_contents.as_ssz_bytes().into()) + .map(|res: Response| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded)) + .map(|res: Response| { + add_execution_payload_value_header(res, block_response.execution_payload_value) + }) + .map(|res| add_consensus_block_value_header(res, block_response.consensus_block_value)) + .map_err(|e| -> warp::Rejection { + warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) + }), + _ => fork_versioned_response(endpoint_version, fork_name, block_contents) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)) + .map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded)) + .map(|res| { + add_execution_payload_value_header(res, block_response.execution_payload_value) + }) + .map(|res| add_consensus_block_value_header(res, block_response.consensus_block_value)), } } -pub async fn determine_and_produce_block_json( +pub async fn produce_blinded_block_v2( endpoint_version: EndpointVersion, + accept_header: Option, chain: Arc>, slot: Slot, query: api_types::ValidatorBlocksQuery, @@ -120,168 +160,23 @@ pub async fn determine_and_produce_block_json( })?; let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - let block_response_type = chain .produce_block_with_verification( randao_reveal, slot, query.graffiti.map(Into::into), randao_verification, - BlockProductionVersion::V3, + BlockProductionVersion::BlindedV2, ) .await - .map_err(|e| { - warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) - })?; - - generate_json_response_v3(chain, block_response_type, endpoint_version) -} - -pub async fn determine_and_produce_block_ssz( - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, -) -> Result, warp::Rejection> { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; + .map_err(warp_utils::reject::block_production_error)?; - let (block_ssz, fork_name, block_value, blinded) = match chain - .produce_block_with_verification( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - BlockProductionVersion::V3, - ) - .await - .map_err(|e| { - warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) - })? { + match block_response_type { BeaconBlockResponseType::Full(block_response) => { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - ( - block_contents.as_ssz_bytes(), - fork_name, - block_response.execution_payload_value, - false, - ) + build_response_v2(chain, block_response, endpoint_version, accept_header) } BeaconBlockResponseType::Blinded(block_response) => { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_blinded_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - ( - block_contents.as_ssz_bytes(), - fork_name, - block_response.execution_payload_value, - true, - ) - } - }; - - Response::builder() - .status(200) - .header("Content-Type", "application/ssz") - .body(block_ssz.into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, blinded)) - .map(|res: Response| add_execution_payload_value_header(res, block_value)) - .map_err(|e| -> warp::Rejection { - warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) - }) -} - -pub fn generate_json_response_v3( - chain: Arc>, - beacon_block_response_type: BeaconBlockResponseType, - endpoint_version: EndpointVersion, -) -> Result, warp::Rejection> { - match beacon_block_response_type { - BeaconBlockResponseType::Full(beacon_block_response) => { - let fork_name = beacon_block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_block_contents( - fork_name, - beacon_block_response.block, - beacon_block_response.maybe_side_car, - )?; - - fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, false)) - .map(|res| { - add_execution_payload_value_header( - res, - beacon_block_response.execution_payload_value, - ) - }) - .map(|res| { - add_consensus_block_value_header( - res, - beacon_block_response.consensus_block_value, - ) - }) - } - BeaconBlockResponseType::Blinded(beacon_block_response) => { - let fork_name = beacon_block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_blinded_block_contents( - fork_name, - beacon_block_response.block, - beacon_block_response.maybe_side_car, - )?; - - fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, true)) - .map(|res| { - add_execution_payload_value_header( - res, - beacon_block_response.execution_payload_value, - ) - }) - .map(|res| { - add_consensus_block_value_header( - res, - beacon_block_response.consensus_block_value, - ) - }) + build_response_v2(chain, block_response, endpoint_version, accept_header) } } } @@ -313,75 +208,45 @@ pub async fn produce_block_v2( .await .map_err(warp_utils::reject::block_production_error)?; - build_response_v2(chain, block_response_type, endpoint_version, accept_header) + match block_response_type { + BeaconBlockResponseType::Full(block_response) => { + build_response_v2(chain, block_response, endpoint_version, accept_header) + } + BeaconBlockResponseType::Blinded(block_response) => { + build_response_v2(chain, block_response, endpoint_version, accept_header) + } + } } -pub fn build_response_v2( +pub fn build_response_v2>( chain: Arc>, - block_response_type: BeaconBlockResponseType, + block_response: BeaconBlockResponse, endpoint_version: EndpointVersion, accept_header: Option, ) -> Result, warp::Rejection> { - match block_response_type { - BeaconBlockResponseType::Full(block_response) => { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block_contents.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!( - "failed to create response: {}", - e - )) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } - } - BeaconBlockResponseType::Blinded(block_response) => { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_blinded_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block_contents.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!( - "failed to create response: {}", - e - )) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } - } + let fork_name = block_response + .block + .to_ref() + .fork_name(&chain.spec) + .map_err(inconsistent_fork_rejection)?; + + let block_contents = build_block_contents::build_block_contents( + fork_name, + block_response.block, + block_response.maybe_side_car, + )?; + + match accept_header { + Some(api_types::Accept::Ssz) => Response::builder() + .status(200) + .header("Content-Type", "application/octet-stream") + .body(block_contents.as_ssz_bytes().into()) + .map(|res: Response| add_consensus_version_header(res, fork_name)) + .map_err(|e| { + warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) + }), + _ => fork_versioned_response(endpoint_version, fork_name, block_contents) + .map(|response| warp::reply::json(&response).into_response()) + .map(|res| add_consensus_version_header(res, fork_name)), } } diff --git a/beacon_node/http_api/tests/interactive_tests.rs b/beacon_node/http_api/tests/interactive_tests.rs index ae120e1a047..327215209f2 100644 --- a/beacon_node/http_api/tests/interactive_tests.rs +++ b/beacon_node/http_api/tests/interactive_tests.rs @@ -626,9 +626,7 @@ pub async fn proposer_boost_re_org_test( .unwrap(); let (unsigned_block_c, block_c_blobs) = match unsigned_block_type { - Full(unsigned_block_contents_c) => { - unsigned_block_contents_c.data.deconstruct() - }, + Full(unsigned_block_contents_c) => unsigned_block_contents_c.data.deconstruct(), Blinded(_) => { panic!("Should not be a blinded block"); } From 219ad178c75f4910dc6313df02653e9f0b515d8d Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 26 Oct 2023 19:19:54 +0300 Subject: [PATCH 42/62] header bugfix --- beacon_node/http_api/src/validator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 91d4ca37b21..777ae573b1c 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -89,14 +89,14 @@ pub async fn produce_block_v3( match block_response_type { BeaconBlockResponseType::Full(block_response) => { - build_response_v3(chain, block_response, endpoint_version, accept_header, true) + build_response_v3(chain, block_response, endpoint_version, accept_header, false) } BeaconBlockResponseType::Blinded(block_response) => build_response_v3( chain, block_response, endpoint_version, accept_header, - false, + true, ), } } From cb5f56ec2653a8fe60ec317e6ae25c217013962d Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Thu, 26 Oct 2023 19:23:05 +0300 Subject: [PATCH 43/62] fmt --- beacon_node/http_api/src/validator.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 777ae573b1c..eca6536bb82 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -88,16 +88,16 @@ pub async fn produce_block_v3( })?; match block_response_type { - BeaconBlockResponseType::Full(block_response) => { - build_response_v3(chain, block_response, endpoint_version, accept_header, false) - } - BeaconBlockResponseType::Blinded(block_response) => build_response_v3( + BeaconBlockResponseType::Full(block_response) => build_response_v3( chain, block_response, endpoint_version, accept_header, - true, + false, ), + BeaconBlockResponseType::Blinded(block_response) => { + build_response_v3(chain, block_response, endpoint_version, accept_header, true) + } } } From d2e77901735c23732f81daf5d7cfe94c2f562fdb Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 29 Oct 2023 16:44:27 +0200 Subject: [PATCH 44/62] resolve merge conflicts --- validator_client/src/block_service.rs | 120 ++++++++++++++++++-------- 1 file changed, 83 insertions(+), 37 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 094d6729fff..9d9e0e72776 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -23,8 +23,8 @@ use std::time::Duration; use tokio::sync::mpsc; use tokio::time::sleep; use types::{ - AbstractExecPayload, BeaconBlock, BlindedPayload, BlockType, EthSpec, FullPayload, Graffiti, - PublicKeyBytes, Slot, + AbstractExecPayload, BlindedPayload, BlockType, EthSpec, FullPayload, Graffiti, PublicKeyBytes, + Slot, }; #[derive(Debug)] @@ -335,10 +335,20 @@ impl BlockService { ) } - // TODO: activate automatically at Deneb - if !self.validator_store.produce_block_v3() { + let deneb_fork_activated = self + .context + .eth2_config + .spec + .deneb_fork_epoch + .and_then(|fork_epoch| { + let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); + Some(current_epoch >= fork_epoch) + }) + .unwrap_or(false); + + if !self.validator_store.produce_block_v3() || deneb_fork_activated { for validator_pubkey in proposers { - let service = self.clone(); + let service: BlockService = self.clone(); let log = log.clone(); self.inner.context.executor.spawn( async move { @@ -458,8 +468,10 @@ impl BlockService { graffiti: Option, validator_pubkey: PublicKeyBytes, proposer_index: Option, - block: BeaconBlock, + block_contents: BlockContents, ) -> Result<(), BlockError> { + let (block, maybe_blob_sidecars) = block_contents.deconstruct(); + info!( log, "Received unsigned block"; @@ -477,11 +489,25 @@ impl BlockService { "Proposer index does not match block proposer. Beacon chain re-orged".to_string(), )); } + let validator_pubkey_ref = &validator_pubkey; + let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); + + let signing_time_ms = + Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); + + info!( + log, + "Publishing signed block"; + "slot" => slot.as_u64(), + "signing_time_ms" => signing_time_ms, + ); + let self_ref = &self; let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); - let signed_block = match self + + let signed_block = match self_ref .validator_store - .sign_block::(validator_pubkey, block, current_slot) + .sign_block::(*validator_pubkey_ref, block, current_slot) .await { Ok(block) => block, @@ -505,6 +531,36 @@ impl BlockService { } }; + let maybe_signed_blobs = match maybe_blob_sidecars { + Some(blob_sidecars) => { + match self_ref + .validator_store + .sign_blobs::(*validator_pubkey_ref, blob_sidecars) + .await + { + Ok(signed_blobs) => Some(signed_blobs), + Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { + // A pubkey can be missing when a validator was recently removed + // via the API. + warn!( + log, + "Missing pubkey for blobs"; + "info" => "a validator may have recently been removed from this VC", + "pubkey" => ?pubkey, + "slot" => ?slot + ); + return Ok(()); + } + Err(e) => { + return Err(BlockError::Recoverable(format!( + "Unable to sign blobs: {:?}", + e + ))) + } + } + } + None => None, + }; let signing_time_ms = Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); @@ -515,31 +571,23 @@ impl BlockService { "signing_time_ms" => signing_time_ms, ); + let signed_block_contents = SignedBlockContents::from((signed_block, maybe_signed_blobs)); + + // Publish block with first available beacon node. + // + // Try the proposer nodes first, since we've likely gone to efforts to + // protect them from DoS attacks and they're most likely to successfully + // publish a block. proposer_fallback .first_success_try_proposers_first( RequireSynced::No, OfflineOnFailure::Yes, |beacon_node| async { - let _post_timer = metrics::start_timer_vec( - &metrics::BLOCK_SERVICE_TIMES, - &[metrics::BEACON_BLOCK_HTTP_POST], - ); - match Payload::block_type() { - BlockType::Blinded => { - beacon_node - .post_beacon_blinded_blocks(&signed_block) - .await - .or_else(|e| handle_block_post_error(e, slot, log))?; - Ok::<_, BlockError>(()) - } - BlockType::Full => { - beacon_node - .post_beacon_blocks(&signed_block) - .await - .or_else(|e| handle_block_post_error(e, slot, log))?; - Ok::<_, BlockError>(()) - } - } + self.publish_signed_block_contents::( + &signed_block_contents, + beacon_node, + ) + .await }, ) .await?; @@ -548,10 +596,10 @@ impl BlockService { log, "Successfully published block"; "block_type" => ?Payload::block_type(), - "deposits" => signed_block.message().body().deposits().len(), - "attestations" => signed_block.message().body().attestations().len(), + "deposits" => signed_block_contents.signed_block().message().body().deposits().len(), + "attestations" => signed_block_contents.signed_block().message().body().attestations().len(), "graffiti" => ?graffiti.map(|g| g.as_utf8_lossy()), - "slot" => signed_block.slot().as_u64(), + "slot" => signed_block_contents.signed_block().slot().as_u64(), ); Ok(()) @@ -646,8 +694,7 @@ impl BlockService { .await??; match block_response { - eth2::types::ForkVersionedBeaconBlockType::Full(block_response) => { - let block = block_response.data; + eth2::types::ForkVersionedBeaconBlockType::Full(block_contents) => { self.handle_block_response::>( log, proposer_fallback, @@ -656,12 +703,11 @@ impl BlockService { graffiti, validator_pubkey, proposer_index, - block, + block_contents.data, ) .await?; } - eth2::types::ForkVersionedBeaconBlockType::Blinded(block_response) => { - let block: BeaconBlock> = block_response.data; + eth2::types::ForkVersionedBeaconBlockType::Blinded(block_contents) => { self.handle_block_response::>( log, proposer_fallback, @@ -670,7 +716,7 @@ impl BlockService { graffiti, validator_pubkey, proposer_index, - block, + block_contents.data, ) .await?; } From e2d4fea5de1a27d4078992a0013830de47d16200 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 11:16:12 +0200 Subject: [PATCH 45/62] fix merge --- beacon_node/beacon_chain/src/beacon_chain.rs | 4 +--- beacon_node/beacon_chain/src/errors.rs | 1 - beacon_node/beacon_chain/src/test_utils.rs | 3 +++ beacon_node/execution_layer/src/metrics.rs | 1 + beacon_node/http_api/src/validator.rs | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 522beb8a4a3..f2378b4f9ed 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -70,7 +70,6 @@ use crate::{ kzg_utils, metrics, AvailabilityPendingExecutedBlock, BeaconChainError, BeaconForkChoiceStore, BeaconSnapshot, CachedHead, }; -use eth2::lighthouse::StandardBlockReward; use eth2::types::{EventKind, SseBlobSidecar, SseBlock, SseExtendedPayloadAttributes, SyncDuty}; use execution_layer::{ BlockProposalContents, BlockProposalContentsType, BuilderParams, ChainHealth, ExecutionLayer, @@ -4669,7 +4668,6 @@ impl BeaconChain { } } - fn produce_partial_beacon_block( self: &Arc, mut state: BeaconState, @@ -5096,7 +5094,7 @@ impl BeaconChain { }; let block = SignedBeaconBlock::from_block( - inner_block.clone(), + inner_block, // The block is not signed here, that is the task of a validator client. Signature::empty(), ); diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 408b6840fcc..7c1bb04917d 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -283,7 +283,6 @@ pub enum BlockProductionError { TokioJoin(JoinError), BeaconChain(BeaconChainError), InvalidPayloadFork, - FailedToFetchBlock, TrustedSetupNotInitialized, InvalidBlockVariant(String), KzgError(kzg::Error), diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index 7b84f99720e..333318f52f2 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -996,6 +996,9 @@ where blob.signature.clone(), ); } + (signed_block, Some(signed_blobs)) + } else { + (signed_block, None) } } }; diff --git a/beacon_node/execution_layer/src/metrics.rs b/beacon_node/execution_layer/src/metrics.rs index 79a3ca003ab..3ed99ca6068 100644 --- a/beacon_node/execution_layer/src/metrics.rs +++ b/beacon_node/execution_layer/src/metrics.rs @@ -2,6 +2,7 @@ pub use lighthouse_metrics::*; pub const HIT: &str = "hit"; pub const MISS: &str = "miss"; +pub const GET_PAYLOAD: &str = "get_payload"; pub const GET_BLINDED_PAYLOAD: &str = "get_blinded_payload"; pub const GET_BLINDED_PAYLOAD_LOCAL: &str = "get_blinded_payload_local"; pub const GET_BLINDED_PAYLOAD_BUILDER: &str = "get_blinded_payload_builder"; diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 4a043dff626..f5b61829f12 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,11 +1,11 @@ -use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; -use types::{BeaconState, PublicKeyBytes}; use beacon_chain::{ BeaconBlockResponse, BeaconBlockResponseType, BeaconChain, BeaconChainError, BeaconChainTypes, ProduceBlockVerification, }; +use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; use ssz::Encode; +use types::{BeaconState, PublicKeyBytes}; use warp::{ hyper::{Body, Response}, Reply, From d34635648c340697b7ec883c154fa8ea5090b410 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 11:18:29 +0200 Subject: [PATCH 46/62] fix merge --- beacon_node/http_api/src/validator.rs | 231 +------------------------- 1 file changed, 1 insertion(+), 230 deletions(-) diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index f5b61829f12..18e9dbf636b 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,24 +1,6 @@ -use beacon_chain::{ - BeaconBlockResponse, BeaconBlockResponseType, BeaconChain, BeaconChainError, BeaconChainTypes, - ProduceBlockVerification, -}; use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; -use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification}; -use ssz::Encode; -use types::{BeaconState, PublicKeyBytes}; -use warp::{ - hyper::{Body, Response}, - Reply, -}; +use types::*; -use crate::{ - build_block_contents, - version::{ - add_consensus_block_value_header, add_consensus_version_header, - add_execution_payload_blinded_header, add_execution_payload_value_header, - fork_versioned_response, inconsistent_fork_rejection, - }, -}; /// Uses the `chain.validator_pubkey_cache` to resolve a pubkey to a validator /// index and then ensures that the validator exists in the given `state`. pub fn pubkey_to_validator_index( @@ -37,214 +19,3 @@ pub fn pubkey_to_validator_index( .map(Result::Ok) .transpose() } - -pub fn get_randao_verification( - query: &api_types::ValidatorBlocksQuery, - randao_reveal_infinity: bool, -) -> Result { - let randao_verification = if query.skip_randao_verification == SkipRandaoVerification::Yes { - if !randao_reveal_infinity { - return Err(warp_utils::reject::custom_bad_request( - "randao_reveal must be point-at-infinity if verification is skipped".into(), - )); - } - ProduceBlockVerification::NoVerification - } else { - ProduceBlockVerification::VerifyRandao - }; - - Ok(randao_verification) -} - -pub async fn produce_block_v3( - endpoint_version: EndpointVersion, - accept_header: Option, - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, -) -> Result, warp::Rejection> { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - - let block_response_type = chain - .produce_block_with_verification( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - BlockProductionVersion::V3, - ) - .await - .map_err(|e| { - warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e)) - })?; - - match block_response_type { - BeaconBlockResponseType::Full(block_response) => build_response_v3( - chain, - block_response, - endpoint_version, - accept_header, - false, - ), - BeaconBlockResponseType::Blinded(block_response) => { - build_response_v3(chain, block_response, endpoint_version, accept_header, true) - } - } -} - -pub fn build_response_v3>( - chain: Arc>, - block_response: BeaconBlockResponse, - endpoint_version: EndpointVersion, - accept_header: Option, - execution_payload_blinded: bool, -) -> Result, warp::Rejection> { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/ssz") - .body(block_contents.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded)) - .map(|res: Response| { - add_execution_payload_value_header(res, block_response.execution_payload_value) - }) - .map(|res| add_consensus_block_value_header(res, block_response.consensus_block_value)) - .map_err(|e| -> warp::Rejection { - warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)) - .map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded)) - .map(|res| { - add_execution_payload_value_header(res, block_response.execution_payload_value) - }) - .map(|res| add_consensus_block_value_header(res, block_response.consensus_block_value)), - } -} - -pub async fn produce_blinded_block_v2( - endpoint_version: EndpointVersion, - accept_header: Option, - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, -) -> Result, warp::Rejection> { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - let block_response_type = chain - .produce_block_with_verification( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - BlockProductionVersion::BlindedV2, - ) - .await - .map_err(warp_utils::reject::block_production_error)?; - - match block_response_type { - BeaconBlockResponseType::Full(block_response) => { - build_response_v2(chain, block_response, endpoint_version, accept_header) - } - BeaconBlockResponseType::Blinded(block_response) => { - build_response_v2(chain, block_response, endpoint_version, accept_header) - } - } -} - -pub async fn produce_block_v2( - endpoint_version: EndpointVersion, - accept_header: Option, - chain: Arc>, - slot: Slot, - query: api_types::ValidatorBlocksQuery, -) -> Result, warp::Rejection> { - let randao_reveal = query.randao_reveal.decompress().map_err(|e| { - warp_utils::reject::custom_bad_request(format!( - "randao reveal is not a valid BLS signature: {:?}", - e - )) - })?; - - let randao_verification = get_randao_verification(&query, randao_reveal.is_infinity())?; - - let block_response_type = chain - .produce_block_with_verification( - randao_reveal, - slot, - query.graffiti.map(Into::into), - randao_verification, - BlockProductionVersion::FullV2, - ) - .await - .map_err(warp_utils::reject::block_production_error)?; - - match block_response_type { - BeaconBlockResponseType::Full(block_response) => { - build_response_v2(chain, block_response, endpoint_version, accept_header) - } - BeaconBlockResponseType::Blinded(block_response) => { - build_response_v2(chain, block_response, endpoint_version, accept_header) - } - } -} - -pub fn build_response_v2>( - chain: Arc>, - block_response: BeaconBlockResponse, - endpoint_version: EndpointVersion, - accept_header: Option, -) -> Result, warp::Rejection> { - let fork_name = block_response - .block - .to_ref() - .fork_name(&chain.spec) - .map_err(inconsistent_fork_rejection)?; - - let block_contents = build_block_contents::build_block_contents( - fork_name, - block_response.block, - block_response.maybe_side_car, - )?; - - match accept_header { - Some(api_types::Accept::Ssz) => Response::builder() - .status(200) - .header("Content-Type", "application/octet-stream") - .body(block_contents.as_ssz_bytes().into()) - .map(|res: Response| add_consensus_version_header(res, fork_name)) - .map_err(|e| { - warp_utils::reject::custom_server_error(format!("failed to create response: {}", e)) - }), - _ => fork_versioned_response(endpoint_version, fork_name, block_contents) - .map(|response| warp::reply::json(&response).into_response()) - .map(|res| add_consensus_version_header(res, fork_name)), - } -} From fb5e60b384afa775ae542757ed4022047101ad59 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 11:47:35 +0200 Subject: [PATCH 47/62] refactor --- beacon_node/http_api/src/validator.rs | 2 +- validator_client/src/block_service.rs | 111 +++----------------------- 2 files changed, 13 insertions(+), 100 deletions(-) diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index 18e9dbf636b..7f11ddd8f43 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -1,5 +1,5 @@ use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes}; -use types::*; +use types::{BeaconState, PublicKeyBytes}; /// Uses the `chain.validator_pubkey_cache` to resolve a pubkey to a validator /// index and then ensures that the validator exists in the given `state`. diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 9d9e0e72776..875a86cecee 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -788,6 +788,8 @@ impl BlockService { "slot" => slot.as_u64(), ); + + // Request block from first responsive beacon node. // // Try the proposer nodes last, since it's likely that they don't have a @@ -797,7 +799,7 @@ impl BlockService { RequireSynced::No, OfflineOnFailure::Yes, move |beacon_node| { - Self::get_validator_block( + Self::get_validator_block::( beacon_node, slot, randao_reveal_ref, @@ -809,105 +811,16 @@ impl BlockService { ) .await?; - let (block, maybe_blob_sidecars) = block_contents.deconstruct(); - let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); - - let signed_block = match self_ref - .validator_store - .sign_block::(*validator_pubkey_ref, block, current_slot) - .await - { - Ok(block) => block, - Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { - // A pubkey can be missing when a validator was recently removed - // via the API. - warn!( - log, - "Missing pubkey for block"; - "info" => "a validator may have recently been removed from this VC", - "pubkey" => ?pubkey, - "slot" => ?slot - ); - return Ok(()); - } - Err(e) => { - return Err(BlockError::Recoverable(format!( - "Unable to sign block: {:?}", - e - ))) - } - }; - - let maybe_signed_blobs = match maybe_blob_sidecars { - Some(blob_sidecars) => { - match self_ref - .validator_store - .sign_blobs::(*validator_pubkey_ref, blob_sidecars) - .await - { - Ok(signed_blobs) => Some(signed_blobs), - Err(ValidatorStoreError::UnknownPubkey(pubkey)) => { - // A pubkey can be missing when a validator was recently removed - // via the API. - warn!( - log, - "Missing pubkey for blobs"; - "info" => "a validator may have recently been removed from this VC", - "pubkey" => ?pubkey, - "slot" => ?slot - ); - return Ok(()); - } - Err(e) => { - return Err(BlockError::Recoverable(format!( - "Unable to sign blobs: {:?}", - e - ))) - } - } - } - None => None, - }; - let signing_time_ms = - Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); - - info!( + self.handle_block_response( log, - "Publishing signed block"; - "slot" => slot.as_u64(), - "signing_time_ms" => signing_time_ms, - ); - - let signed_block_contents = SignedBlockContents::from((signed_block, maybe_signed_blobs)); - - // Publish block with first available beacon node. - // - // Try the proposer nodes first, since we've likely gone to efforts to - // protect them from DoS attacks and they're most likely to successfully - // publish a block. - proposer_fallback - .first_success_try_proposers_first( - RequireSynced::No, - OfflineOnFailure::Yes, - |beacon_node| async { - self.publish_signed_block_contents::( - &signed_block_contents, - beacon_node, - ) - .await - }, - ) - .await?; - - info!( - log, - "Successfully published block"; - "block_type" => ?Payload::block_type(), - "deposits" => signed_block_contents.signed_block().message().body().deposits().len(), - "attestations" => signed_block_contents.signed_block().message().body().attestations().len(), - "graffiti" => ?graffiti.map(|g| g.as_utf8_lossy()), - "slot" => signed_block_contents.signed_block().slot().as_u64(), - ); + proposer_fallback, + slot, + current_slot, + graffiti, + validator_pubkey, + proposer_index, + block_contents + ).await?; Ok(()) } From 1a50c7f631e8401548784feccca768d1e1a87166 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 12:04:24 +0200 Subject: [PATCH 48/62] refactor --- validator_client/src/block_service.rs | 51 ++++----------------------- 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 875a86cecee..7736829200a 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -467,45 +467,13 @@ impl BlockService { current_slot: Slot, graffiti: Option, validator_pubkey: PublicKeyBytes, - proposer_index: Option, block_contents: BlockContents, ) -> Result<(), BlockError> { - let (block, maybe_blob_sidecars) = block_contents.deconstruct(); - - info!( - log, - "Received unsigned block"; - "slot" => slot.as_u64(), - ); - - info!( - log, - "Received unsigned block"; - "slot" => slot.as_u64(), - ); - - if proposer_index != Some(block.proposer_index()) { - return Err(BlockError::Recoverable( - "Proposer index does not match block proposer. Beacon chain re-orged".to_string(), - )); - } let validator_pubkey_ref = &validator_pubkey; + let (block, maybe_blob_sidecars) = block_contents.deconstruct(); let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); - let signing_time_ms = - Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); - - info!( - log, - "Publishing signed block"; - "slot" => slot.as_u64(), - "signing_time_ms" => signing_time_ms, - ); - let self_ref = &self; - - let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); - - let signed_block = match self_ref + let signed_block = match self .validator_store .sign_block::(*validator_pubkey_ref, block, current_slot) .await @@ -533,7 +501,7 @@ impl BlockService { let maybe_signed_blobs = match maybe_blob_sidecars { Some(blob_sidecars) => { - match self_ref + match self .validator_store .sign_blobs::(*validator_pubkey_ref, blob_sidecars) .await @@ -561,6 +529,7 @@ impl BlockService { } None => None, }; + let signing_time_ms = Duration::from_secs_f64(signing_timer.map_or(0.0, |t| t.stop_and_record())).as_millis(); @@ -601,7 +570,6 @@ impl BlockService { "graffiti" => ?graffiti.map(|g| g.as_utf8_lossy()), "slot" => signed_block_contents.signed_block().slot().as_u64(), ); - Ok(()) } @@ -653,7 +621,6 @@ impl BlockService { ); let randao_reveal_ref = &randao_reveal; - let proposer_index = self.validator_store.validator_index(&validator_pubkey); let proposer_fallback = ProposerFallback { beacon_nodes: self.beacon_nodes.clone(), proposer_nodes: self.proposer_nodes.clone(), @@ -702,7 +669,6 @@ impl BlockService { current_slot, graffiti, validator_pubkey, - proposer_index, block_contents.data, ) .await?; @@ -715,7 +681,6 @@ impl BlockService { current_slot, graffiti, validator_pubkey, - proposer_index, block_contents.data, ) .await?; @@ -788,8 +753,6 @@ impl BlockService { "slot" => slot.as_u64(), ); - - // Request block from first responsive beacon node. // // Try the proposer nodes last, since it's likely that they don't have a @@ -818,9 +781,9 @@ impl BlockService { current_slot, graffiti, validator_pubkey, - proposer_index, - block_contents - ).await?; + block_contents, + ) + .await?; Ok(()) } From 412d7ca4c07d818115eea9fb2eaf343539d5f19f Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 12:15:32 +0200 Subject: [PATCH 49/62] cleanup --- validator_client/src/block_service.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 7736829200a..9f4890f21b3 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -466,16 +466,15 @@ impl BlockService { slot: Slot, current_slot: Slot, graffiti: Option, - validator_pubkey: PublicKeyBytes, + validator_pubkey: &PublicKeyBytes, block_contents: BlockContents, ) -> Result<(), BlockError> { - let validator_pubkey_ref = &validator_pubkey; let (block, maybe_blob_sidecars) = block_contents.deconstruct(); let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); let signed_block = match self .validator_store - .sign_block::(*validator_pubkey_ref, block, current_slot) + .sign_block::(*validator_pubkey, block, current_slot) .await { Ok(block) => block, @@ -503,7 +502,7 @@ impl BlockService { Some(blob_sidecars) => { match self .validator_store - .sign_blobs::(*validator_pubkey_ref, blob_sidecars) + .sign_blobs::(*validator_pubkey, blob_sidecars) .await { Ok(signed_blobs) => Some(signed_blobs), @@ -668,7 +667,7 @@ impl BlockService { slot, current_slot, graffiti, - validator_pubkey, + &validator_pubkey, block_contents.data, ) .await?; @@ -680,7 +679,7 @@ impl BlockService { slot, current_slot, graffiti, - validator_pubkey, + &validator_pubkey, block_contents.data, ) .await?; @@ -780,7 +779,7 @@ impl BlockService { slot, current_slot, graffiti, - validator_pubkey, + &validator_pubkey, block_contents, ) .await?; From 282f92bf383a1c9083ccafbe0458a51d7cfa1414 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 3 Nov 2023 13:04:11 +0200 Subject: [PATCH 50/62] lint --- validator_client/src/block_service.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 9f4890f21b3..b057246208b 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -738,9 +738,7 @@ impl BlockService { ); let randao_reveal_ref = &randao_reveal; - let self_ref = &self; let proposer_index = self.validator_store.validator_index(&validator_pubkey); - let validator_pubkey_ref = &validator_pubkey; let proposer_fallback = ProposerFallback { beacon_nodes: self.beacon_nodes.clone(), proposer_nodes: self.proposer_nodes.clone(), From d9a50adfebf488ab399ea8b4d3932d711595786a Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 22 Nov 2023 14:22:33 -0800 Subject: [PATCH 51/62] changes based on feedback --- consensus/types/src/light_client_header.rs | 141 +++++++++++++++++++++ validator_client/src/block_service.rs | 31 +++-- 2 files changed, 162 insertions(+), 10 deletions(-) create mode 100644 consensus/types/src/light_client_header.rs diff --git a/consensus/types/src/light_client_header.rs b/consensus/types/src/light_client_header.rs new file mode 100644 index 00000000000..cb1cd126764 --- /dev/null +++ b/consensus/types/src/light_client_header.rs @@ -0,0 +1,141 @@ +use crate::BeaconBlockHeader; +use crate::{test_utils::TestRandom, EthSpec, ExecutionPayloadHeader, SignedBeaconBlock, Hash256}; +use merkle_proof::{verify_merkle_proof, MerkleTree}; +use serde::{Deserialize, Serialize}; +use ssz_derive::{Decode, Encode}; +use test_random_derive::TestRandom; +use tree_hash::TreeHash; +use ssz::Encode; + +const EXECUTION_PAYLOAD_INDEX: u32 = 25; +const FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX: u32 = 4; + +#[derive( + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Encode, + Decode, + TestRandom, + arbitrary::Arbitrary, +)] +pub struct ExecutionBranch(pub [u8; FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX as usize]); + +#[derive( + Debug, + Clone, + PartialEq, + Serialize, + Deserialize, + Encode, + Decode, + TestRandom, + arbitrary::Arbitrary, +)] +#[serde(bound = "E: EthSpec")] +#[arbitrary(bound = "T: EthSpec")] +pub struct LightClientHeader { + pub beacon: BeaconBlockHeader, + pub execution: Option>, + pub execution_branch: Option, +} + +impl From for LightClientHeader { + fn from(beacon: BeaconBlockHeader) -> Self { + LightClientHeader { + beacon, + execution: None, + execution_branch: None, + } + } +} + +impl From> for LightClientHeader { + fn from(block: SignedBeaconBlock) -> Self { + let epoch = block.message().slot().epoch(E::slots_per_epoch()); + + // TODO epoch greater than or equal to capella + if epoch >= 0 { + let payload = block.message().body().execution_payload(); + + // TODO fix unwrap + let header = ExecutionPayloadHeader::::from(payload.unwrap().into()); + + let leaves = block + .message() + .body_capella() + .unwrap() + .as_ssz_bytes() + .iter() + .map(|data| data.tree_hash_root()) + .collect::>(); + + let tree = MerkleTree::create(&leaves, EXECUTION_PAYLOAD_INDEX as usize); + + let execution_branch = tree.generate_proof(index, depth) + + let execution_branch = generate_proof(block.message().body_capella().unwrap().as_ssz_bytes(), EXECUTION_PAYLOAD_INDEX); + }; + + LightClientHeader { + beacon, + execution: None, + execution_branch: None, + } + } +} + +impl LightClientHeader { + fn get_lc_execution_root(&self) -> Option { + let epoch = self.beacon.slot.epoch(E::slots_per_epoch()); + + // TODO greater than or equal to CAPELLA + if epoch >= 0 { + if let Some(execution) = self.execution { + return Some(execution.tree_hash_root()); + } + } + + return None; + } + + fn is_valid_light_client_header(&self) -> bool { + let epoch = self.beacon.slot.epoch(E::slots_per_epoch()); + + // TODO LESS THAN CAPELLA + if epoch < 0 { + return self.execution == None && self.execution_branch == None; + } + + let Some(execution_root) = self.get_lc_execution_root() else { + return false + }; + + let Some(execution_branch) = self.execution_branch else { + return false + }; + + return verify_merkle_proof( + execution_root, + &execution_branch.into(), + FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX, + get_subtree_index(EXECUTION_PAYLOAD_INDEX), + self.beacon.body_root, + ); + } +} + +// TODO move to the relevant place +fn get_subtree_index(generalized_index: u32) -> u32 { + return generalized_index % 2 * (log2_int(generalized_index)); +} + +// TODO move to the relevant place +fn log2_int(x: u32) -> u32 { + if x == 0 { + return 0; + } + 31 - x.leading_zeros() +} diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index b057246208b..496d47b3ee6 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -346,7 +346,7 @@ impl BlockService { }) .unwrap_or(false); - if !self.validator_store.produce_block_v3() || deneb_fork_activated { + if self.validator_store.produce_block_v3() || deneb_fork_activated { for validator_pubkey in proposers { let service: BlockService = self.clone(); let log = log.clone(); @@ -365,8 +365,22 @@ impl BlockService { "Error whilst producing block"; "error" => ?e, "block_slot" => ?slot, - "info" => "blinded proposal failed, attempting full block" + "info" => "block v3 proposal failed, attempting full block v2" ); + if let Err(e) = service + .publish_block::>(slot, validator_pubkey) + .await + { + // Log a `crit` since a full block v2 + // (non-builder) proposal failed. + crit!( + log, + "Error whilst producing block"; + "error" => ?e, + "block_slot" => ?slot, + "info" => "full block v2 attempted after a block v3 failure", + ); + } } Err(BlockError::Irrecoverable(e)) => { error!( @@ -459,9 +473,8 @@ impl BlockService { } #[allow(clippy::too_many_arguments)] - async fn handle_block_response>( + async fn sign_and_publish_block>( &self, - log: &Logger, proposer_fallback: ProposerFallback, slot: Slot, current_slot: Slot, @@ -469,6 +482,7 @@ impl BlockService { validator_pubkey: &PublicKeyBytes, block_contents: BlockContents, ) -> Result<(), BlockError> { + let log = self.context.log(); let (block, maybe_blob_sidecars) = block_contents.deconstruct(); let signing_timer = metrics::start_timer(&metrics::BLOCK_SIGNING_TIMES); @@ -661,8 +675,7 @@ impl BlockService { match block_response { eth2::types::ForkVersionedBeaconBlockType::Full(block_contents) => { - self.handle_block_response::>( - log, + self.sign_and_publish_block::>( proposer_fallback, slot, current_slot, @@ -673,8 +686,7 @@ impl BlockService { .await?; } eth2::types::ForkVersionedBeaconBlockType::Blinded(block_contents) => { - self.handle_block_response::>( - log, + self.sign_and_publish_block::>( proposer_fallback, slot, current_slot, @@ -771,8 +783,7 @@ impl BlockService { ) .await?; - self.handle_block_response( - log, + self.sign_and_publish_block( proposer_fallback, slot, current_slot, From ad978f6b436e089e9cb64b1e5945b72269f0e017 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Wed, 22 Nov 2023 14:24:38 -0800 Subject: [PATCH 52/62] revert --- consensus/types/src/light_client_header.rs | 141 --------------------- 1 file changed, 141 deletions(-) delete mode 100644 consensus/types/src/light_client_header.rs diff --git a/consensus/types/src/light_client_header.rs b/consensus/types/src/light_client_header.rs deleted file mode 100644 index cb1cd126764..00000000000 --- a/consensus/types/src/light_client_header.rs +++ /dev/null @@ -1,141 +0,0 @@ -use crate::BeaconBlockHeader; -use crate::{test_utils::TestRandom, EthSpec, ExecutionPayloadHeader, SignedBeaconBlock, Hash256}; -use merkle_proof::{verify_merkle_proof, MerkleTree}; -use serde::{Deserialize, Serialize}; -use ssz_derive::{Decode, Encode}; -use test_random_derive::TestRandom; -use tree_hash::TreeHash; -use ssz::Encode; - -const EXECUTION_PAYLOAD_INDEX: u32 = 25; -const FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX: u32 = 4; - -#[derive( - Debug, - Clone, - PartialEq, - Serialize, - Deserialize, - Encode, - Decode, - TestRandom, - arbitrary::Arbitrary, -)] -pub struct ExecutionBranch(pub [u8; FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX as usize]); - -#[derive( - Debug, - Clone, - PartialEq, - Serialize, - Deserialize, - Encode, - Decode, - TestRandom, - arbitrary::Arbitrary, -)] -#[serde(bound = "E: EthSpec")] -#[arbitrary(bound = "T: EthSpec")] -pub struct LightClientHeader { - pub beacon: BeaconBlockHeader, - pub execution: Option>, - pub execution_branch: Option, -} - -impl From for LightClientHeader { - fn from(beacon: BeaconBlockHeader) -> Self { - LightClientHeader { - beacon, - execution: None, - execution_branch: None, - } - } -} - -impl From> for LightClientHeader { - fn from(block: SignedBeaconBlock) -> Self { - let epoch = block.message().slot().epoch(E::slots_per_epoch()); - - // TODO epoch greater than or equal to capella - if epoch >= 0 { - let payload = block.message().body().execution_payload(); - - // TODO fix unwrap - let header = ExecutionPayloadHeader::::from(payload.unwrap().into()); - - let leaves = block - .message() - .body_capella() - .unwrap() - .as_ssz_bytes() - .iter() - .map(|data| data.tree_hash_root()) - .collect::>(); - - let tree = MerkleTree::create(&leaves, EXECUTION_PAYLOAD_INDEX as usize); - - let execution_branch = tree.generate_proof(index, depth) - - let execution_branch = generate_proof(block.message().body_capella().unwrap().as_ssz_bytes(), EXECUTION_PAYLOAD_INDEX); - }; - - LightClientHeader { - beacon, - execution: None, - execution_branch: None, - } - } -} - -impl LightClientHeader { - fn get_lc_execution_root(&self) -> Option { - let epoch = self.beacon.slot.epoch(E::slots_per_epoch()); - - // TODO greater than or equal to CAPELLA - if epoch >= 0 { - if let Some(execution) = self.execution { - return Some(execution.tree_hash_root()); - } - } - - return None; - } - - fn is_valid_light_client_header(&self) -> bool { - let epoch = self.beacon.slot.epoch(E::slots_per_epoch()); - - // TODO LESS THAN CAPELLA - if epoch < 0 { - return self.execution == None && self.execution_branch == None; - } - - let Some(execution_root) = self.get_lc_execution_root() else { - return false - }; - - let Some(execution_branch) = self.execution_branch else { - return false - }; - - return verify_merkle_proof( - execution_root, - &execution_branch.into(), - FLOOR_LOG2_EXECUTION_PAYLOAD_INDEX, - get_subtree_index(EXECUTION_PAYLOAD_INDEX), - self.beacon.body_root, - ); - } -} - -// TODO move to the relevant place -fn get_subtree_index(generalized_index: u32) -> u32 { - return generalized_index % 2 * (log2_int(generalized_index)); -} - -// TODO move to the relevant place -fn log2_int(x: u32) -> u32 { - if x == 0 { - return 0; - } - 31 - x.leading_zeros() -} From 13942bf7fe8c6cd4e82271d79e75c83a7cee3deb Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Fri, 24 Nov 2023 07:19:52 -0800 Subject: [PATCH 53/62] remove block v3 fallback to v2 --- validator_client/src/block_service.rs | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 496d47b3ee6..30f53ffe38d 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -359,36 +359,13 @@ impl BlockService { match result { Ok(_) => {} - Err(BlockError::Recoverable(e)) => { + Err(BlockError::Recoverable(e)) | Err(BlockError::Irrecoverable(e)) => { error!( log, "Error whilst producing block"; "error" => ?e, "block_slot" => ?slot, - "info" => "block v3 proposal failed, attempting full block v2" - ); - if let Err(e) = service - .publish_block::>(slot, validator_pubkey) - .await - { - // Log a `crit` since a full block v2 - // (non-builder) proposal failed. - crit!( - log, - "Error whilst producing block"; - "error" => ?e, - "block_slot" => ?slot, - "info" => "full block v2 attempted after a block v3 failure", - ); - } - } - Err(BlockError::Irrecoverable(e)) => { - error!( - log, - "Error whilst producing block"; - "error" => ?e, - "block_slot" => ?slot, - "info" => "this error may or may not result in a missed block", + "info" => "block v3 proposal failed, this error may or may not result in a missed block" ); } } From d108edcc2278c17be9f080a727ad52671ceb044d Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 3 Dec 2023 12:13:55 -0800 Subject: [PATCH 54/62] publish_block_v3 should return irrecoveerable errors --- validator_client/src/block_service.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index aeac9e880f5..cce2219b103 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -366,7 +366,6 @@ impl BlockService { .validator_store .get_builder_proposals(&validator_pubkey); let service = self.clone(); - let log = log.clone(); self.inner.context.executor.spawn( async move { if builder_proposals { @@ -560,7 +559,7 @@ impl BlockService { metrics::start_timer_vec(&metrics::BLOCK_SERVICE_TIMES, &[metrics::BEACON_BLOCK]); let current_slot = self.slot_clock.now().ok_or_else(|| { - BlockError::Recoverable("Unable to determine current slot from clock".to_string()) + BlockError::Irrecoverable("Unable to determine current slot from clock".to_string()) })?; let randao_reveal = match self @@ -582,7 +581,7 @@ impl BlockService { return Ok(()); } Err(e) => { - return Err(BlockError::Recoverable(format!( + return Err(BlockError::Irrecoverable(format!( "Unable to produce randao reveal signature: {:?}", e ))) @@ -626,7 +625,7 @@ impl BlockService { .get_validator_blocks_v3::(slot, randao_reveal_ref, graffiti.as_ref()) .await .map_err(|e| { - BlockError::Recoverable(format!( + BlockError::Irrecoverable(format!( "Error from beacon node when producing block: {:?}", e )) From f0f2442c2dcbc641a2b4bfe1172940f43ee22712 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 3 Dec 2023 13:47:50 -0800 Subject: [PATCH 55/62] comments --- validator_client/src/block_service.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index cce2219b103..083ab3560e3 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -360,7 +360,7 @@ impl BlockService { ) } } else { - // TODO this can be deprecated post deneb + // TODO block v2 endpoint usage can be deprecated post deneb for validator_pubkey in proposers { let builder_proposals = self .validator_store From bc1a5943676e970211dbe1f0e56ea3a6780643d8 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Sun, 3 Dec 2023 13:49:33 -0800 Subject: [PATCH 56/62] comments --- validator_client/src/block_service.rs | 2 +- validator_client/src/cli.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 083ab3560e3..bf7a062495d 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -730,7 +730,7 @@ impl BlockService { // Try the proposer nodes last, since it's likely that they don't have a // great view of attestations on the network. let block_contents = proposer_fallback - .request_proposers_last( + .first_success_try_proposers_last( RequireSynced::No, OfflineOnFailure::Yes, move |beacon_node| { diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index d3325e2b05b..301b26ba088 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -141,7 +141,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .long("produce-block-v3") .help("Enable block production via the block v3 endpoint for this validator client. \ This should only be enabled when paired with a beacon node \ - that has this endpoint implemented.") + that has this endpoint implemented. This flag will be ignored \ + after the Deneb fork.") .takes_value(false) ) /* REST API related arguments */ From 8d5d5a109bda09c0327aeec35647e51d7462ac35 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Mon, 4 Dec 2023 14:44:35 -0800 Subject: [PATCH 57/62] fixed issues from merge --- lighthouse/tests/validator_client.rs | 18 ------------------ validator_client/src/block_service.rs | 18 +++++++++++------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/lighthouse/tests/validator_client.rs b/lighthouse/tests/validator_client.rs index 2fb2ff09a74..025188fed4e 100644 --- a/lighthouse/tests/validator_client.rs +++ b/lighthouse/tests/validator_client.rs @@ -436,24 +436,6 @@ fn no_produce_block_v3_flag() { .with_config(|config| assert!(!config.produce_block_v3)); } -#[test] -fn block_delay_ms() { - CommandLineTest::new() - .flag("block-delay-ms", Some("2000")) - .run() - .with_config(|config| { - assert_eq!( - config.block_delay, - Some(std::time::Duration::from_millis(2000)) - ) - }); -} -#[test] -fn no_block_delay_ms() { - CommandLineTest::new() - .run() - .with_config(|config| assert_eq!(config.block_delay, None)); -} #[test] fn no_gas_limit_flag() { CommandLineTest::new() diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index bf7a062495d..8f6bb9d085a 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -334,7 +334,8 @@ impl BlockService { // TODO produce_block_v3 should be deprecated post deneb if self.validator_store.produce_block_v3() || deneb_fork_activated { for validator_pubkey in proposers { - let service: BlockService = self.clone(); + + let service = self.clone(); let log = log.clone(); self.inner.context.executor.spawn( async move { @@ -366,6 +367,7 @@ impl BlockService { .validator_store .get_builder_proposals(&validator_pubkey); let service = self.clone(); + let log = log.clone(); self.inner.context.executor.spawn( async move { if builder_proposals { @@ -524,7 +526,7 @@ impl BlockService { // protect them from DoS attacks and they're most likely to successfully // publish a block. proposer_fallback - .first_success_try_proposers_first( + .request_proposers_first( RequireSynced::No, OfflineOnFailure::Yes, |beacon_node| async { @@ -597,6 +599,7 @@ impl BlockService { ); let randao_reveal_ref = &randao_reveal; + let self_ref = &self; let proposer_fallback = ProposerFallback { beacon_nodes: self.beacon_nodes.clone(), proposer_nodes: self.proposer_nodes.clone(), @@ -613,7 +616,7 @@ impl BlockService { // Try the proposer nodes last, since it's likely that they don't have a // great view of attestations on the network. let block_response = proposer_fallback - .first_success_try_proposers_last( + .request_proposers_last( RequireSynced::No, OfflineOnFailure::Yes, |beacon_node| async move { @@ -638,7 +641,7 @@ impl BlockService { match block_response { eth2::types::ForkVersionedBeaconBlockType::Full(block_contents) => { - self.sign_and_publish_block::>( + self_ref.sign_and_publish_block::>( proposer_fallback, slot, current_slot, @@ -649,7 +652,7 @@ impl BlockService { .await?; } eth2::types::ForkVersionedBeaconBlockType::Blinded(block_contents) => { - self.sign_and_publish_block::>( + self_ref.sign_and_publish_block::>( proposer_fallback, slot, current_slot, @@ -713,6 +716,7 @@ impl BlockService { ); let randao_reveal_ref = &randao_reveal; + let self_ref = &self; let proposer_index = self.validator_store.validator_index(&validator_pubkey); let proposer_fallback = ProposerFallback { beacon_nodes: self.beacon_nodes.clone(), @@ -730,7 +734,7 @@ impl BlockService { // Try the proposer nodes last, since it's likely that they don't have a // great view of attestations on the network. let block_contents = proposer_fallback - .first_success_try_proposers_last( + .request_proposers_last( RequireSynced::No, OfflineOnFailure::Yes, move |beacon_node| { @@ -746,7 +750,7 @@ impl BlockService { ) .await?; - self.sign_and_publish_block( + self_ref.sign_and_publish_block( proposer_fallback, slot, current_slot, From 3f86e3d6b31a0cc565ad57909540b3ca0f5e9e03 Mon Sep 17 00:00:00 2001 From: Eitan Seri-Levi Date: Tue, 2 Jan 2024 15:08:40 +0200 Subject: [PATCH 58/62] merge conflicts --- validator_client/src/block_service.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 53afb92916f..d4ff9cc46ce 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -659,7 +659,7 @@ impl BlockService { // via the API. warn!( log, - "Missing pubkey for block randao"; + "Missing pubkey for block"; "info" => "a validator may have recently been removed from this VC", "pubkey" => ?pubkey, "slot" => ?slot @@ -668,7 +668,7 @@ impl BlockService { } Err(e) => { return Err(BlockError::Recoverable(format!( - "Unable to produce randao reveal signature: {:?}", + "Unable to sign block: {:?}", e ))) } @@ -793,7 +793,7 @@ impl BlockService { "slot" => slot.as_u64(), ); if proposer_index != Some(unsigned_block.proposer_index()) { - return Err(BlockError::Recoverable( + return Err(BlockError::Irrecoverable( "Proposer index does not match block proposer. Beacon chain re-orged".to_string(), )); } From a9304c00fddb6108730c0642146c9c8d993b07f8 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Mon, 8 Jan 2024 12:36:45 +1100 Subject: [PATCH 59/62] Don't activate at fork; support builder_proposals --- validator_client/src/block_service.rs | 35 +++++++++++++++------------ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index d4ff9cc46ce..b90c8a2cac2 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -320,27 +320,23 @@ impl BlockService { ) } - let deneb_fork_activated = self - .context - .eth2_config - .spec - .deneb_fork_epoch - .and_then(|fork_epoch| { - let current_epoch = self.slot_clock.now()?.epoch(E::slots_per_epoch()); - Some(current_epoch >= fork_epoch) - }) - .unwrap_or(false); - - // TODO produce_block_v3 should be deprecated post deneb - if self.validator_store.produce_block_v3() || deneb_fork_activated { + if self.validator_store.produce_block_v3() { for validator_pubkey in proposers { + let builder_proposals = self + .validator_store + .get_builder_proposals(&validator_pubkey); + // Translate `builder_proposals` to a boost factor. Builder proposals set to `true` + // requires no boost factor, it just means "use a builder proposal if the BN returns + // one". On the contrary, `builder_proposals: false` indicates a preference for + // local payloads, so we set the builder boost factor to 0. + let builder_boost_factor = if !builder_proposals { Some(0) } else { None }; let service = self.clone(); let log = log.clone(); self.inner.context.executor.spawn( async move { let result = service .clone() - .publish_block_v3(slot, validator_pubkey) + .publish_block_v3(slot, validator_pubkey, builder_boost_factor) .await; match result { @@ -360,7 +356,6 @@ impl BlockService { ) } } else { - // TODO block v2 endpoint usage can be deprecated post deneb for validator_pubkey in proposers { let builder_proposals = self .validator_store @@ -528,6 +523,7 @@ impl BlockService { self, slot: Slot, validator_pubkey: PublicKeyBytes, + builder_boost_factor: Option, ) -> Result<(), BlockError> { let log = self.context.log(); let _timer = @@ -604,6 +600,7 @@ impl BlockService { randao_reveal_ref, graffiti, proposer_index, + builder_boost_factor, log, ) .await @@ -770,10 +767,16 @@ impl BlockService { randao_reveal_ref: &SignatureBytes, graffiti: Option, proposer_index: Option, + builder_boost_factor: Option, log: &Logger, ) -> Result, BlockError> { let (block_response, _) = beacon_node - .get_validator_blocks_v3::(slot, randao_reveal_ref, graffiti.as_ref()) + .get_validator_blocks_v3::( + slot, + randao_reveal_ref, + graffiti.as_ref(), + builder_boost_factor, + ) .await .map_err(|e| { BlockError::Irrecoverable(format!( From b93f16d282edac636739252dd7af6111a2c3e2d6 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Mon, 8 Jan 2024 12:59:28 +1100 Subject: [PATCH 60/62] Update CLI flags & book --- book/src/help_vc.md | 4 ++++ validator_client/src/block_service.rs | 1 - validator_client/src/cli.rs | 8 +++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/book/src/help_vc.md b/book/src/help_vc.md index 4471b0e1044..62b64efd411 100644 --- a/book/src/help_vc.md +++ b/book/src/help_vc.md @@ -56,6 +56,10 @@ FLAGS: machine. Note that logs can often contain sensitive information about your validator and so this flag should be used with caution. For Windows users, the log file permissions will be inherited from the parent folder. --metrics Enable the Prometheus metrics HTTP server. Disabled by default. + --produce-block-v3 + Enable block production via the block v3 endpoint for this validator client. This should only be enabled + when paired with a beacon node that has this endpoint implemented. This flag will be enabled by default in + future. --unencrypted-http-transport This is a safety flag to ensure that the user is aware that the http transport is unencrypted and using a custom HTTP address is unsafe. diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index b90c8a2cac2..f05ef70a9a2 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -335,7 +335,6 @@ impl BlockService { self.inner.context.executor.spawn( async move { let result = service - .clone() .publish_block_v3(slot, validator_pubkey, builder_boost_factor) .await; diff --git a/validator_client/src/cli.rs b/validator_client/src/cli.rs index 301b26ba088..cd3ad494dad 100644 --- a/validator_client/src/cli.rs +++ b/validator_client/src/cli.rs @@ -141,8 +141,8 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { .long("produce-block-v3") .help("Enable block production via the block v3 endpoint for this validator client. \ This should only be enabled when paired with a beacon node \ - that has this endpoint implemented. This flag will be ignored \ - after the Deneb fork.") + that has this endpoint implemented. This flag will be enabled by default in \ + future.") .takes_value(false) ) /* REST API related arguments */ @@ -303,15 +303,13 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { immediately.") .takes_value(false), ) - // TODO deprecate this flag post Deneb .arg( Arg::with_name("builder-proposals") .long("builder-proposals") .alias("private-tx-proposals") .help("If this flag is set, Lighthouse will query the Beacon Node for only block \ headers during proposals and will sign over headers. Useful for outsourcing \ - execution payload construction during proposals. If the produce-block-v3 flag is present \ - this flag will be ignored. This flag will also be ignored after the Deneb fork.") + execution payload construction during proposals.") .takes_value(false), ) .arg( From 32cad117601a47b52807f77ad418515f252f1a88 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Jan 2024 15:06:42 +1100 Subject: [PATCH 61/62] Remove duplicate `current_slot` parameter in `publish_block` function, and remove unnecessary clone. --- validator_client/src/block_service.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index f05ef70a9a2..5d2370f775e 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -365,7 +365,6 @@ impl BlockService { async move { if builder_proposals { let result = service - .clone() .publish_block(slot, validator_pubkey, true) .await; @@ -435,7 +434,6 @@ impl BlockService { &self, proposer_fallback: ProposerFallback, slot: Slot, - current_slot: Slot, graffiti: Option, validator_pubkey: &PublicKeyBytes, unsigned_block: UnsignedBlock, @@ -447,13 +445,13 @@ impl BlockService { UnsignedBlock::Full(block_contents) => { let (block, maybe_blobs) = block_contents.deconstruct(); self.validator_store - .sign_block(*validator_pubkey, block, current_slot) + .sign_block(*validator_pubkey, block, slot) .await .map(|b| SignedBlock::Full(PublishBlockRequest::new(b, maybe_blobs))) } UnsignedBlock::Blinded(block) => self .validator_store - .sign_block(*validator_pubkey, block, current_slot) + .sign_block(*validator_pubkey, block, slot) .await .map(SignedBlock::Blinded), }; @@ -528,10 +526,6 @@ impl BlockService { let _timer = metrics::start_timer_vec(&metrics::BLOCK_SERVICE_TIMES, &[metrics::BEACON_BLOCK]); - let current_slot = self.slot_clock.now().ok_or_else(|| { - BlockError::Irrecoverable("Unable to determine current slot from clock".to_string()) - })?; - let randao_reveal = match self .validator_store .randao_reveal(validator_pubkey, slot.epoch(E::slots_per_epoch())) @@ -619,7 +613,6 @@ impl BlockService { .sign_and_publish_block( proposer_fallback, slot, - current_slot, graffiti, &validator_pubkey, unsigned_block, @@ -640,10 +633,6 @@ impl BlockService { let _timer = metrics::start_timer_vec(&metrics::BLOCK_SERVICE_TIMES, &[metrics::BEACON_BLOCK]); - let current_slot = self.slot_clock.now().ok_or_else(|| { - BlockError::Recoverable("Unable to determine current slot from clock".to_string()) - })?; - let randao_reveal = match self .validator_store .randao_reveal(validator_pubkey, slot.epoch(E::slots_per_epoch())) @@ -718,7 +707,6 @@ impl BlockService { .sign_and_publish_block( proposer_fallback, slot, - current_slot, graffiti, &validator_pubkey, unsigned_block, From f579a043067eec26072baba2bf3a8505c33f8159 Mon Sep 17 00:00:00 2001 From: Jimmy Chen Date: Mon, 8 Jan 2024 15:46:10 +1100 Subject: [PATCH 62/62] Revert changes on making block errors irrecoverable. --- validator_client/src/block_service.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/validator_client/src/block_service.rs b/validator_client/src/block_service.rs index 5d2370f775e..b65e301de86 100644 --- a/validator_client/src/block_service.rs +++ b/validator_client/src/block_service.rs @@ -28,7 +28,10 @@ use types::{ #[derive(Debug)] pub enum BlockError { + /// A recoverable error that can be retried, as the validator has not signed anything. Recoverable(String), + /// An irrecoverable error has occurred during block proposal and should not be retried, as a + /// block may have already been signed. Irrecoverable(String), } @@ -545,7 +548,7 @@ impl BlockService { return Ok(()); } Err(e) => { - return Err(BlockError::Irrecoverable(format!( + return Err(BlockError::Recoverable(format!( "Unable to produce randao reveal signature: {:?}", e ))) @@ -598,7 +601,7 @@ impl BlockService { ) .await .map_err(|e| { - BlockError::Irrecoverable(format!( + BlockError::Recoverable(format!( "Error from beacon node when producing block: {:?}", e )) @@ -766,7 +769,7 @@ impl BlockService { ) .await .map_err(|e| { - BlockError::Irrecoverable(format!( + BlockError::Recoverable(format!( "Error from beacon node when producing block: {:?}", e )) @@ -783,7 +786,7 @@ impl BlockService { "slot" => slot.as_u64(), ); if proposer_index != Some(unsigned_block.proposer_index()) { - return Err(BlockError::Irrecoverable( + return Err(BlockError::Recoverable( "Proposer index does not match block proposer. Beacon chain re-orged".to_string(), )); }