Refactored Execution Layer & Fixed Some Tests

This commit is contained in:
Mark Mackey 2022-11-29 18:01:47 -06:00
parent 36170ec428
commit f5e6a54f05
11 changed files with 133 additions and 207 deletions

View File

@ -59,7 +59,7 @@ use crate::{metrics, BeaconChainError};
use eth2::types::{EventKind, SseBlock, SyncDuty}; use eth2::types::{EventKind, SseBlock, SyncDuty};
use execution_layer::{ use execution_layer::{
BlockProposalContents, BuilderParams, ChainHealth, ExecutionLayer, FailedCondition, BlockProposalContents, BuilderParams, ChainHealth, ExecutionLayer, FailedCondition,
PayloadAttributes, PayloadAttributesV1, PayloadAttributesV2, PayloadStatus, PayloadAttributes, PayloadStatus,
}; };
pub use fork_choice::CountUnrealized; pub use fork_choice::CountUnrealized;
use fork_choice::{ use fork_choice::{
@ -4179,21 +4179,20 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.map(|withdrawals_opt| withdrawals_opt.map(|w| w.into())) .map(|withdrawals_opt| withdrawals_opt.map(|w| w.into()))
.map_err(Error::PrepareProposerFailed)?; .map_err(Error::PrepareProposerFailed)?;
let payload_attributes = PayloadAttributes::V2(PayloadAttributesV2 { let payload_attributes = PayloadAttributes::new(
timestamp: self self.slot_clock
.slot_clock
.start_of(prepare_slot) .start_of(prepare_slot)
.ok_or(Error::InvalidSlot(prepare_slot))? .ok_or(Error::InvalidSlot(prepare_slot))?
.as_secs(), .as_secs(),
prev_randao: head_random, head_random,
suggested_fee_recipient: execution_layer execution_layer
.get_suggested_fee_recipient(proposer as u64) .get_suggested_fee_recipient(proposer as u64)
.await, .await,
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
withdrawals, withdrawals,
#[cfg(not(feature = "withdrawals"))] #[cfg(not(feature = "withdrawals"))]
withdrawals: None, None,
}); );
debug!( debug!(
self.log, self.log,

View File

@ -12,7 +12,7 @@ use crate::{
BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, BlockProductionError, BeaconChain, BeaconChainError, BeaconChainTypes, BlockError, BlockProductionError,
ExecutionPayloadError, ExecutionPayloadError,
}; };
use execution_layer::{BlockProposalContents, BuilderParams, PayloadStatus}; use execution_layer::{BlockProposalContents, BuilderParams, PayloadAttributes, PayloadStatus};
use fork_choice::{InvalidationOperation, PayloadVerificationStatus}; use fork_choice::{InvalidationOperation, PayloadVerificationStatus};
use proto_array::{Block as ProtoBlock, ExecutionStatus}; use proto_array::{Block as ProtoBlock, ExecutionStatus};
use slog::debug; use slog::debug;
@ -483,20 +483,29 @@ where
.await .await
.map_err(BlockProductionError::BeaconChain)?; .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,
#[cfg(feature = "withdrawals")]
withdrawals,
#[cfg(not(feature = "withdrawals"))]
None,
);
// Note: the suggested_fee_recipient is stored in the `execution_layer`, it will add this parameter. // 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. // This future is not executed here, it's up to the caller to await it.
let block_contents = execution_layer let block_contents = execution_layer
.get_payload::<Payload>( .get_payload::<Payload>(
parent_hash, parent_hash,
timestamp, &payload_attributes,
random,
proposer_index,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
fork, fork,
#[cfg(feature = "withdrawals")]
withdrawals,
&chain.spec, &chain.spec,
) )
.await .await

View File

@ -14,7 +14,7 @@ use beacon_chain::{
use execution_layer::{ use execution_layer::{
json_structures::{JsonForkchoiceStateV1, JsonPayloadAttributes, JsonPayloadAttributesV1}, json_structures::{JsonForkchoiceStateV1, JsonPayloadAttributes, JsonPayloadAttributesV1},
test_utils::ExecutionBlockGenerator, test_utils::ExecutionBlockGenerator,
ExecutionLayer, ForkchoiceState, PayloadAttributes, PayloadAttributesV1, ExecutionLayer, ForkchoiceState, PayloadAttributes,
}; };
use fork_choice::{ use fork_choice::{
CountUnrealized, Error as ForkChoiceError, InvalidationOperation, PayloadVerificationStatus, CountUnrealized, Error as ForkChoiceError, InvalidationOperation, PayloadVerificationStatus,
@ -985,20 +985,22 @@ async fn payload_preparation() {
.await .await
.unwrap(); .unwrap();
let payload_attributes = PayloadAttributes::V1(PayloadAttributesV1 { let payload_attributes = PayloadAttributes::new(
timestamp: rig rig.harness
.harness
.chain .chain
.slot_clock .slot_clock
.start_of(next_slot) .start_of(next_slot)
.unwrap() .unwrap()
.as_secs(), .as_secs(),
prev_randao: *head *head
.beacon_state .beacon_state
.get_randao_mix(head.beacon_state.current_epoch()) .get_randao_mix(head.beacon_state.current_epoch())
.unwrap(), .unwrap(),
suggested_fee_recipient: fee_recipient, fee_recipient,
}); None,
)
.downgrade_to_v1()
.unwrap();
assert_eq!(rig.previous_payload_attributes(), payload_attributes); assert_eq!(rig.previous_payload_attributes(), payload_attributes);
} }

View File

@ -243,11 +243,11 @@ impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T>
#[superstruct( #[superstruct(
variants(V1, V2), variants(V1, V2),
variant_attributes(derive(Clone, Debug, PartialEq),), variant_attributes(derive(Clone, Debug, Eq, Hash, PartialEq),),
cast_error(ty = "Error", expr = "Error::IncorrectStateVariant"), cast_error(ty = "Error", expr = "Error::IncorrectStateVariant"),
partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant") partial_getter_error(ty = "Error", expr = "Error::IncorrectStateVariant")
)] )]
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct PayloadAttributes { pub struct PayloadAttributes {
#[superstruct(getter(copy))] #[superstruct(getter(copy))]
pub timestamp: u64, pub timestamp: u64,
@ -260,14 +260,28 @@ pub struct PayloadAttributes {
} }
impl PayloadAttributes { impl PayloadAttributes {
pub fn new(
timestamp: u64,
prev_randao: Hash256,
suggested_fee_recipient: Address,
withdrawals: Option<Vec<Withdrawal>>,
) -> Self {
// this should always return the highest version
PayloadAttributes::V2(PayloadAttributesV2 {
timestamp,
prev_randao,
suggested_fee_recipient,
withdrawals,
})
}
pub fn downgrade_to_v1(self) -> Result<Self, Error> { pub fn downgrade_to_v1(self) -> Result<Self, Error> {
match self { match self {
PayloadAttributes::V1(_) => Ok(self), PayloadAttributes::V1(_) => Ok(self),
PayloadAttributes::V2(v2) => { PayloadAttributes::V2(v2) => {
#[cfg(features = "withdrawals")]
if v2.withdrawals.is_some() { if v2.withdrawals.is_some() {
return Err(Error::BadConversion( return Err(Error::BadConversion(
"Downgrading from PayloadAttributesV2 with non-null withdrawaals" "Downgrading from PayloadAttributesV2 with non-null withdrawals"
.to_string(), .to_string(),
)); ));
} }

View File

@ -16,6 +16,7 @@ use types::{Address, ExecutionBlockHash, Hash256};
/// The number of payload IDs that will be stored for each `Engine`. /// The number of payload IDs that will be stored for each `Engine`.
/// ///
/// Since the size of each value is small (~100 bytes) a large number is used for safety. /// Since the size of each value is small (~100 bytes) a large number is used for safety.
/// FIXME: check this assumption now that the key includes entire payload attributes which now includes withdrawals
const PAYLOAD_ID_LRU_CACHE_SIZE: usize = 512; const PAYLOAD_ID_LRU_CACHE_SIZE: usize = 512;
/// Stores the remembered state of a engine. /// Stores the remembered state of a engine.
@ -97,9 +98,7 @@ pub struct ForkchoiceState {
#[derive(Hash, PartialEq, std::cmp::Eq)] #[derive(Hash, PartialEq, std::cmp::Eq)]
struct PayloadIdCacheKey { struct PayloadIdCacheKey {
pub head_block_hash: ExecutionBlockHash, pub head_block_hash: ExecutionBlockHash,
pub timestamp: u64, pub payload_attributes: PayloadAttributes,
pub prev_randao: Hash256,
pub suggested_fee_recipient: Address,
} }
#[derive(Debug)] #[derive(Debug)]
@ -142,20 +141,13 @@ impl Engine {
pub async fn get_payload_id( pub async fn get_payload_id(
&self, &self,
head_block_hash: ExecutionBlockHash, head_block_hash: &ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
suggested_fee_recipient: Address,
) -> Option<PayloadId> { ) -> Option<PayloadId> {
self.payload_id_cache self.payload_id_cache
.lock() .lock()
.await .await
.get(&PayloadIdCacheKey { .get(&PayloadIdCacheKey::new(head_block_hash, payload_attributes))
head_block_hash,
timestamp,
prev_randao,
suggested_fee_recipient,
})
.cloned() .cloned()
} }
@ -171,8 +163,8 @@ impl Engine {
.await?; .await?;
if let Some(payload_id) = response.payload_id { if let Some(payload_id) = response.payload_id {
if let Some(key) = if let Some(key) = payload_attributes
payload_attributes.map(|pa| PayloadIdCacheKey::new(&forkchoice_state, &pa)) .map(|pa| PayloadIdCacheKey::new(&forkchoice_state.head_block_hash, &pa))
{ {
self.payload_id_cache.lock().await.put(key, payload_id); self.payload_id_cache.lock().await.put(key, payload_id);
} else { } else {
@ -347,14 +339,11 @@ impl Engine {
} }
} }
// TODO: revisit this - do we need to key on withdrawals as well here?
impl PayloadIdCacheKey { impl PayloadIdCacheKey {
fn new(state: &ForkchoiceState, attributes: &PayloadAttributes) -> Self { fn new(head_block_hash: &ExecutionBlockHash, attributes: &PayloadAttributes) -> Self {
Self { Self {
head_block_hash: state.head_block_hash, head_block_hash: head_block_hash.clone(),
timestamp: attributes.timestamp(), payload_attributes: attributes.clone(),
prev_randao: attributes.prev_randao(),
suggested_fee_recipient: attributes.suggested_fee_recipient(),
} }
} }
} }

View File

@ -606,21 +606,15 @@ impl<T: EthSpec> ExecutionLayer<T> {
/// ///
/// The result will be returned from the first node that returns successfully. No more nodes /// The result will be returned from the first node that returns successfully. No more nodes
/// will be contacted. /// will be contacted.
#[allow(clippy::too_many_arguments)]
pub async fn get_payload<Payload: AbstractExecPayload<T>>( pub async fn get_payload<Payload: AbstractExecPayload<T>>(
&self, &self,
parent_hash: ExecutionBlockHash, parent_hash: ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
proposer_index: u64,
forkchoice_update_params: ForkchoiceUpdateParameters, forkchoice_update_params: ForkchoiceUpdateParameters,
builder_params: BuilderParams, builder_params: BuilderParams,
current_fork: ForkName, current_fork: ForkName,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<BlockProposalContents<T, Payload>, Error> { ) -> Result<BlockProposalContents<T, Payload>, Error> {
let suggested_fee_recipient = self.get_suggested_fee_recipient(proposer_index).await;
match Payload::block_type() { match Payload::block_type() {
BlockType::Blinded => { BlockType::Blinded => {
let _timer = metrics::start_timer_vec( let _timer = metrics::start_timer_vec(
@ -629,14 +623,10 @@ impl<T: EthSpec> ExecutionLayer<T> {
); );
self.get_blinded_payload( self.get_blinded_payload(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
spec, spec,
) )
.await .await
@ -648,30 +638,22 @@ impl<T: EthSpec> ExecutionLayer<T> {
); );
self.get_full_payload( self.get_full_payload(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
) )
.await .await
} }
} }
} }
#[allow(clippy::too_many_arguments)]
async fn get_blinded_payload<Payload: AbstractExecPayload<T>>( async fn get_blinded_payload<Payload: AbstractExecPayload<T>>(
&self, &self,
parent_hash: ExecutionBlockHash, parent_hash: ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
suggested_fee_recipient: Address,
forkchoice_update_params: ForkchoiceUpdateParameters, forkchoice_update_params: ForkchoiceUpdateParameters,
builder_params: BuilderParams, builder_params: BuilderParams,
current_fork: ForkName, current_fork: ForkName,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>,
spec: &ChainSpec, spec: &ChainSpec,
) -> Result<BlockProposalContents<T, Payload>, Error> { ) -> Result<BlockProposalContents<T, Payload>, Error> {
if let Some(builder) = self.builder() { if let Some(builder) = self.builder() {
@ -691,13 +673,9 @@ impl<T: EthSpec> ExecutionLayer<T> {
builder.get_builder_header::<T, Payload>(slot, parent_hash, &pubkey), builder.get_builder_header::<T, Payload>(slot, parent_hash, &pubkey),
self.get_full_payload_caching( self.get_full_payload_caching(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
) )
); );
@ -746,7 +724,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
falling back to local execution engine." falling back to local execution engine."
); );
Ok(local) Ok(local)
} else if header.prev_randao() != prev_randao { } else if header.prev_randao() != payload_attributes.prev_randao() {
warn!( warn!(
self.log(), self.log(),
"Invalid prev randao from connected builder, \ "Invalid prev randao from connected builder, \
@ -784,7 +762,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
bid from connected builder, falling back to local execution engine."); bid from connected builder, falling back to local execution engine.");
Ok(local) Ok(local)
} else { } else {
if header.fee_recipient() != suggested_fee_recipient { if header.fee_recipient() != payload_attributes.suggested_fee_recipient() {
info!( info!(
self.log(), self.log(),
"Fee recipient from connected builder does \ "Fee recipient from connected builder does \
@ -823,13 +801,9 @@ impl<T: EthSpec> ExecutionLayer<T> {
} }
self.get_full_payload_caching( self.get_full_payload_caching(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
) )
.await .await
} }
@ -838,22 +812,15 @@ impl<T: EthSpec> ExecutionLayer<T> {
async fn get_full_payload<Payload: AbstractExecPayload<T>>( async fn get_full_payload<Payload: AbstractExecPayload<T>>(
&self, &self,
parent_hash: ExecutionBlockHash, parent_hash: ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
suggested_fee_recipient: Address,
forkchoice_update_params: ForkchoiceUpdateParameters, forkchoice_update_params: ForkchoiceUpdateParameters,
current_fork: ForkName, current_fork: ForkName,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>,
) -> Result<BlockProposalContents<T, Payload>, Error> { ) -> Result<BlockProposalContents<T, Payload>, Error> {
self.get_full_payload_with( self.get_full_payload_with(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
noop, noop,
) )
.await .await
@ -863,22 +830,15 @@ impl<T: EthSpec> ExecutionLayer<T> {
async fn get_full_payload_caching<Payload: AbstractExecPayload<T>>( async fn get_full_payload_caching<Payload: AbstractExecPayload<T>>(
&self, &self,
parent_hash: ExecutionBlockHash, parent_hash: ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
suggested_fee_recipient: Address,
forkchoice_update_params: ForkchoiceUpdateParameters, forkchoice_update_params: ForkchoiceUpdateParameters,
current_fork: ForkName, current_fork: ForkName,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>,
) -> Result<BlockProposalContents<T, Payload>, Error> { ) -> Result<BlockProposalContents<T, Payload>, Error> {
self.get_full_payload_with( self.get_full_payload_with(
parent_hash, parent_hash,
timestamp, payload_attributes,
prev_randao,
suggested_fee_recipient,
forkchoice_update_params, forkchoice_update_params,
current_fork, current_fork,
#[cfg(feature = "withdrawals")]
withdrawals,
Self::cache_payload, Self::cache_payload,
) )
.await .await
@ -887,20 +847,15 @@ impl<T: EthSpec> ExecutionLayer<T> {
async fn get_full_payload_with<Payload: AbstractExecPayload<T>>( async fn get_full_payload_with<Payload: AbstractExecPayload<T>>(
&self, &self,
parent_hash: ExecutionBlockHash, parent_hash: ExecutionBlockHash,
timestamp: u64, payload_attributes: &PayloadAttributes,
prev_randao: Hash256,
suggested_fee_recipient: Address,
forkchoice_update_params: ForkchoiceUpdateParameters, forkchoice_update_params: ForkchoiceUpdateParameters,
current_fork: ForkName, current_fork: ForkName,
#[cfg(feature = "withdrawals")] withdrawals: Option<Vec<Withdrawal>>,
f: fn(&ExecutionLayer<T>, &ExecutionPayload<T>) -> Option<ExecutionPayload<T>>, f: fn(&ExecutionLayer<T>, &ExecutionPayload<T>) -> Option<ExecutionPayload<T>>,
) -> Result<BlockProposalContents<T, Payload>, Error> { ) -> Result<BlockProposalContents<T, Payload>, Error> {
#[cfg(feature = "withdrawals")]
let withdrawals_ref = &withdrawals;
self.engine() self.engine()
.request(move |engine| async move { .request(move |engine| async move {
let payload_id = if let Some(id) = engine let payload_id = if let Some(id) = engine
.get_payload_id(parent_hash, timestamp, prev_randao, suggested_fee_recipient) .get_payload_id(&parent_hash, payload_attributes)
.await .await
{ {
// The payload id has been cached for this engine. // The payload id has been cached for this engine.
@ -925,22 +880,11 @@ impl<T: EthSpec> ExecutionLayer<T> {
.finalized_hash .finalized_hash
.unwrap_or_else(ExecutionBlockHash::zero), .unwrap_or_else(ExecutionBlockHash::zero),
}; };
// This must always be the latest PayloadAttributes
// FIXME: How to non-capella EIP4844 testnets handle this?
let payload_attributes = PayloadAttributes::V2(PayloadAttributesV2 {
timestamp,
prev_randao,
suggested_fee_recipient,
#[cfg(feature = "withdrawals")]
withdrawals: withdrawals_ref.clone(),
#[cfg(not(feature = "withdrawals"))]
withdrawals: None,
});
let response = engine let response = engine
.notify_forkchoice_updated( .notify_forkchoice_updated(
fork_choice_state, fork_choice_state,
Some(payload_attributes), Some(payload_attributes.clone()),
self.log(), self.log(),
) )
.await?; .await?;
@ -969,9 +913,9 @@ impl<T: EthSpec> ExecutionLayer<T> {
debug!( debug!(
self.log(), self.log(),
"Issuing engine_getBlobsBundle"; "Issuing engine_getBlobsBundle";
"suggested_fee_recipient" => ?suggested_fee_recipient, "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(),
"prev_randao" => ?prev_randao, "prev_randao" => ?payload_attributes.prev_randao(),
"timestamp" => timestamp, "timestamp" => payload_attributes.timestamp(),
"parent_hash" => ?parent_hash, "parent_hash" => ?parent_hash,
); );
Some(engine.api.get_blobs_bundle_v1::<T>(payload_id).await) Some(engine.api.get_blobs_bundle_v1::<T>(payload_id).await)
@ -982,16 +926,16 @@ impl<T: EthSpec> ExecutionLayer<T> {
debug!( debug!(
self.log(), self.log(),
"Issuing engine_getPayload"; "Issuing engine_getPayload";
"suggested_fee_recipient" => ?suggested_fee_recipient, "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(),
"prev_randao" => ?prev_randao, "prev_randao" => ?payload_attributes.prev_randao(),
"timestamp" => timestamp, "timestamp" => payload_attributes.timestamp(),
"parent_hash" => ?parent_hash, "parent_hash" => ?parent_hash,
); );
engine.api.get_payload::<T>(current_fork, payload_id).await engine.api.get_payload::<T>(current_fork, payload_id).await
}; };
let (blob, payload) = tokio::join!(blob_fut, payload_fut); let (blob, payload) = tokio::join!(blob_fut, payload_fut);
let payload = payload.map(|full_payload| { let payload = payload.map(|full_payload| {
if full_payload.fee_recipient() != suggested_fee_recipient { if full_payload.fee_recipient() != payload_attributes.suggested_fee_recipient() {
error!( error!(
self.log(), self.log(),
"Inconsistent fee recipient"; "Inconsistent fee recipient";
@ -1001,7 +945,7 @@ impl<T: EthSpec> ExecutionLayer<T> {
ensure that the value of suggested_fee_recipient is set correctly and \ ensure that the value of suggested_fee_recipient is set correctly and \
that the Execution Engine is trusted.", that the Execution Engine is trusted.",
"fee_recipient" => ?full_payload.fee_recipient(), "fee_recipient" => ?full_payload.fee_recipient(),
"suggested_fee_recipient" => ?suggested_fee_recipient, "suggested_fee_recipient" => ?payload_attributes.suggested_fee_recipient(),
); );
} }
if f(self, &full_payload).is_some() { if f(self, &full_payload).is_some() {

View File

@ -1,5 +1,5 @@
use crate::test_utils::DEFAULT_JWT_SECRET; use crate::test_utils::DEFAULT_JWT_SECRET;
use crate::{Config, ExecutionLayer, PayloadAttributes, PayloadAttributesV1}; use crate::{Config, ExecutionLayer, PayloadAttributes};
use async_trait::async_trait; use async_trait::async_trait;
use eth2::types::{BlockId, StateId, ValidatorId}; use eth2::types::{BlockId, StateId, ValidatorId};
use eth2::{BeaconNodeHttpClient, Timeouts}; use eth2::{BeaconNodeHttpClient, Timeouts};
@ -289,11 +289,8 @@ impl<E: EthSpec> mev_build_rs::BlindedBlockProvider for MockBuilder<E> {
.map_err(convert_err)?; .map_err(convert_err)?;
// FIXME: think about proper fork here // FIXME: think about proper fork here
let payload_attributes = PayloadAttributes::V1(PayloadAttributesV1 { let payload_attributes =
timestamp, PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, None);
prev_randao: *prev_randao,
suggested_fee_recipient: fee_recipient,
});
self.el self.el
.insert_proposer(slot, head_block_root, val_index, payload_attributes) .insert_proposer(slot, head_block_root, val_index, payload_attributes)
@ -306,18 +303,17 @@ impl<E: EthSpec> mev_build_rs::BlindedBlockProvider for MockBuilder<E> {
finalized_hash: Some(finalized_execution_hash), finalized_hash: Some(finalized_execution_hash),
}; };
let payload_attributes =
PayloadAttributes::new(timestamp, *prev_randao, fee_recipient, None);
let payload = self let payload = self
.el .el
.get_full_payload_caching::<BlindedPayload<E>>( .get_full_payload_caching::<BlindedPayload<E>>(
head_execution_hash, head_execution_hash,
timestamp, &payload_attributes,
*prev_randao,
fee_recipient,
forkchoice_update_params, forkchoice_update_params,
// TODO: do we need to write a test for this if this is Capella fork? // TODO: do we need to write a test for this if this is Capella fork?
ForkName::Merge, ForkName::Merge,
#[cfg(feature = "withdrawals")]
None,
) )
.await .await
.map_err(convert_err)? .map_err(convert_err)?

View File

@ -98,35 +98,16 @@ impl<T: EthSpec> MockExecutionLayer<T> {
justified_hash: None, justified_hash: None,
finalized_hash: None, finalized_hash: None,
}; };
let payload_attributes = PayloadAttributes::new(
// FIXME: this is just best guess for how to deal with forks here.. timestamp,
let payload_attributes = match &latest_execution_block { prev_randao,
&Block::PoS(ref pos_block) => match pos_block { Address::repeat_byte(42),
&ExecutionPayload::Merge(_) => PayloadAttributes::V1(PayloadAttributesV1 { // FIXME: think about how to handle different forks / withdrawals here..
timestamp, #[cfg(feature = "withdrawals")]
prev_randao, Some(vec![]),
suggested_fee_recipient: Address::repeat_byte(42), #[cfg(not(feature = "withdrawals"))]
}), None,
&ExecutionPayload::Capella(_) | &ExecutionPayload::Eip4844(_) => { );
PayloadAttributes::V2(PayloadAttributesV2 {
timestamp,
prev_randao,
suggested_fee_recipient: Address::repeat_byte(42),
// FIXME: think about adding withdrawals here..
#[cfg(feature = "withdrawals")]
withdrawals: Some(vec![]),
#[cfg(not(feature = "withdrawals"))]
withdrawals: None,
})
}
},
// I guess a PoW blocks means we should use Merge?
&Block::PoW(_) => PayloadAttributes::V1(PayloadAttributesV1 {
timestamp,
prev_randao,
suggested_fee_recipient: Address::repeat_byte(42),
}),
};
// Insert a proposer to ensure the fork choice updated command works. // Insert a proposer to ensure the fork choice updated command works.
let slot = Slot::new(0); let slot = Slot::new(0);
@ -152,19 +133,18 @@ impl<T: EthSpec> MockExecutionLayer<T> {
slot, slot,
chain_health: ChainHealth::Healthy, chain_health: ChainHealth::Healthy,
}; };
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<T> = self let payload: ExecutionPayload<T> = self
.el .el
.get_payload::<FullPayload<T>>( .get_payload::<FullPayload<T>>(
parent_hash, parent_hash,
timestamp, &payload_attributes,
prev_randao,
validator_index,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
// FIXME: do we need to consider other forks somehow? What about withdrawals? // FIXME: do we need to consider other forks somehow? What about withdrawals?
ForkName::Merge, ForkName::Merge,
#[cfg(feature = "withdrawals")]
Some(vec![]),
&self.spec, &self.spec,
) )
.await .await
@ -188,19 +168,18 @@ impl<T: EthSpec> MockExecutionLayer<T> {
slot, slot,
chain_health: ChainHealth::Healthy, chain_health: ChainHealth::Healthy,
}; };
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 payload_header = self
.el .el
.get_payload::<BlindedPayload<T>>( .get_payload::<BlindedPayload<T>>(
parent_hash, parent_hash,
timestamp, &payload_attributes,
prev_randao,
validator_index,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
// FIXME: do we need to consider other forks somehow? What about withdrawals? // FIXME: do we need to consider other forks somehow? What about withdrawals?
ForkName::Merge, ForkName::Merge,
#[cfg(feature = "withdrawals")]
Some(vec![]),
&self.spec, &self.spec,
) )
.await .await

View File

@ -167,15 +167,9 @@ impl<'a, T: EthSpec> From<FullPayloadRef<'a, T>> for ExecutionPayload<T> {
impl<'a, T: EthSpec> From<FullPayloadRef<'a, T>> for FullPayload<T> { impl<'a, T: EthSpec> From<FullPayloadRef<'a, T>> for FullPayload<T> {
fn from(full_payload_ref: FullPayloadRef<'a, T>) -> Self { fn from(full_payload_ref: FullPayloadRef<'a, T>) -> Self {
match full_payload_ref { match full_payload_ref {
FullPayloadRef::Merge(payload_ref) => { FullPayloadRef::Merge(payload_ref) => FullPayload::Merge(payload_ref.clone()),
FullPayload::Merge(payload_ref.clone()) FullPayloadRef::Capella(payload_ref) => FullPayload::Capella(payload_ref.clone()),
} FullPayloadRef::Eip4844(payload_ref) => FullPayload::Eip4844(payload_ref.clone()),
FullPayloadRef::Capella(payload_ref) => {
FullPayload::Capella(payload_ref.clone())
}
FullPayloadRef::Eip4844(payload_ref) => {
FullPayload::Eip4844(payload_ref.clone())
}
} }
} }
} }

View File

@ -10,7 +10,7 @@ use tree_hash_derive::TreeHash;
/// Spec v0.12.1 /// Spec v0.12.1
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive( #[derive(
Debug, PartialEq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom,
)] )]
pub struct Withdrawal { pub struct Withdrawal {
#[serde(with = "eth2_serde_utils::quoted_u64")] #[serde(with = "eth2_serde_utils::quoted_u64")]

View File

@ -4,8 +4,7 @@ use crate::execution_engine::{
use crate::transactions::transactions; use crate::transactions::transactions;
use ethers_providers::Middleware; use ethers_providers::Middleware;
use execution_layer::{ use execution_layer::{
BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, PayloadAttributesV1, BuilderParams, ChainHealth, ExecutionLayer, PayloadAttributes, PayloadStatus,
PayloadStatus,
}; };
use fork_choice::ForkchoiceUpdateParameters; use fork_choice::ForkchoiceUpdateParameters;
use reqwest::{header::CONTENT_TYPE, Client}; use reqwest::{header::CONTENT_TYPE, Client};
@ -279,11 +278,8 @@ impl<E: GenericExecutionEngine> TestRig<E> {
Slot::new(1), // Insert proposer for the next slot Slot::new(1), // Insert proposer for the next slot
head_root, head_root,
proposer_index, proposer_index,
PayloadAttributes::V1(PayloadAttributesV1 { // TODO: think about how to test different forks
timestamp, PayloadAttributes::new(timestamp, prev_randao, Address::zero(), None),
prev_randao,
suggested_fee_recipient: Address::zero(),
}),
) )
.await; .await;
@ -316,20 +312,23 @@ impl<E: GenericExecutionEngine> TestRig<E> {
slot: Slot::new(0), slot: Slot::new(0),
chain_health: ChainHealth::Healthy, chain_health: ChainHealth::Healthy,
}; };
let suggested_fee_recipient = self
.ee_a
.execution_layer
.get_suggested_fee_recipient(proposer_index)
.await;
let payload_attributes =
PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None);
let valid_payload = self let valid_payload = self
.ee_a .ee_a
.execution_layer .execution_layer
.get_payload::<FullPayload<MainnetEthSpec>>( .get_payload::<FullPayload<MainnetEthSpec>>(
parent_hash, parent_hash,
timestamp, &payload_attributes,
prev_randao,
proposer_index,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
// FIXME: think about how to test other forks // FIXME: think about how to test other forks
ForkName::Merge, ForkName::Merge,
#[cfg(feature = "withdrawals")]
None,
&self.spec, &self.spec,
) )
.await .await
@ -444,20 +443,23 @@ impl<E: GenericExecutionEngine> TestRig<E> {
slot: Slot::new(0), slot: Slot::new(0),
chain_health: ChainHealth::Healthy, chain_health: ChainHealth::Healthy,
}; };
let suggested_fee_recipient = self
.ee_a
.execution_layer
.get_suggested_fee_recipient(proposer_index)
.await;
let payload_attributes =
PayloadAttributes::new(timestamp, prev_randao, suggested_fee_recipient, None);
let second_payload = self let second_payload = self
.ee_a .ee_a
.execution_layer .execution_layer
.get_payload::<FullPayload<MainnetEthSpec>>( .get_payload::<FullPayload<MainnetEthSpec>>(
parent_hash, parent_hash,
timestamp, &payload_attributes,
prev_randao,
proposer_index,
forkchoice_update_params, forkchoice_update_params,
builder_params, builder_params,
// FIXME: think about how to test other forks // FIXME: think about how to test other forks
ForkName::Merge, ForkName::Merge,
#[cfg(feature = "withdrawals")]
None,
&self.spec, &self.spec,
) )
.await .await
@ -487,11 +489,9 @@ impl<E: GenericExecutionEngine> TestRig<E> {
*/ */
let head_block_hash = valid_payload.block_hash(); let head_block_hash = valid_payload.block_hash();
let finalized_block_hash = ExecutionBlockHash::zero(); let finalized_block_hash = ExecutionBlockHash::zero();
let payload_attributes = PayloadAttributes::V1(PayloadAttributesV1 { // TODO: think about how to handle different forks
timestamp: second_payload.timestamp() + 1, let payload_attributes =
prev_randao: Hash256::zero(), PayloadAttributes::new(timestamp, prev_randao, Address::zero(), None);
suggested_fee_recipient: Address::zero(),
});
let slot = Slot::new(42); let slot = Slot::new(42);
let head_block_root = Hash256::repeat_byte(100); let head_block_root = Hash256::repeat_byte(100);
let validator_index = 0; let validator_index = 0;