Refactored Execution Layer & Fixed Some Tests
This commit is contained in:
parent
36170ec428
commit
f5e6a54f05
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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)?
|
||||||
|
@ -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
|
||||||
|
@ -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())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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")]
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user