Simplify payload traits and reduce cloning (#3976)
* Simplify payload traits and reduce cloning * Fix self limiter
This commit is contained in:
parent
10d32ee04c
commit
918b688f72
@ -985,11 +985,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
})?
|
})?
|
||||||
.ok_or(Error::BlockHashMissingFromExecutionLayer(exec_block_hash))?;
|
.ok_or(Error::BlockHashMissingFromExecutionLayer(exec_block_hash))?;
|
||||||
|
|
||||||
//FIXME(sean) avoid the clone by comparing refs to headers (`as_execution_payload_header` method ?)
|
|
||||||
let full_payload: FullPayload<T::EthSpec> = execution_payload.clone().into();
|
|
||||||
|
|
||||||
// Verify payload integrity.
|
// Verify payload integrity.
|
||||||
let header_from_payload = full_payload.to_execution_payload_header();
|
let header_from_payload = ExecutionPayloadHeader::from(execution_payload.to_ref());
|
||||||
if header_from_payload != execution_payload_header {
|
if header_from_payload != execution_payload_header {
|
||||||
for txn in execution_payload.transactions() {
|
for txn in execution_payload.transactions() {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -67,6 +67,7 @@ pub struct OutboundRateLimiterConfig {
|
|||||||
pub(super) goodbye_quota: Quota,
|
pub(super) goodbye_quota: Quota,
|
||||||
pub(super) blocks_by_range_quota: Quota,
|
pub(super) blocks_by_range_quota: Quota,
|
||||||
pub(super) blocks_by_root_quota: Quota,
|
pub(super) blocks_by_root_quota: Quota,
|
||||||
|
pub(super) blobs_by_range_quota: Quota,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutboundRateLimiterConfig {
|
impl OutboundRateLimiterConfig {
|
||||||
@ -77,6 +78,8 @@ impl OutboundRateLimiterConfig {
|
|||||||
pub const DEFAULT_BLOCKS_BY_RANGE_QUOTA: Quota =
|
pub const DEFAULT_BLOCKS_BY_RANGE_QUOTA: Quota =
|
||||||
Quota::n_every(methods::MAX_REQUEST_BLOCKS, 10);
|
Quota::n_every(methods::MAX_REQUEST_BLOCKS, 10);
|
||||||
pub const DEFAULT_BLOCKS_BY_ROOT_QUOTA: Quota = Quota::n_every(128, 10);
|
pub const DEFAULT_BLOCKS_BY_ROOT_QUOTA: Quota = Quota::n_every(128, 10);
|
||||||
|
pub const DEFAULT_BLOBS_BY_RANGE_QUOTA: Quota =
|
||||||
|
Quota::n_every(methods::MAX_REQUEST_BLOBS_SIDECARS, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for OutboundRateLimiterConfig {
|
impl Default for OutboundRateLimiterConfig {
|
||||||
@ -88,6 +91,7 @@ impl Default for OutboundRateLimiterConfig {
|
|||||||
goodbye_quota: Self::DEFAULT_GOODBYE_QUOTA,
|
goodbye_quota: Self::DEFAULT_GOODBYE_QUOTA,
|
||||||
blocks_by_range_quota: Self::DEFAULT_BLOCKS_BY_RANGE_QUOTA,
|
blocks_by_range_quota: Self::DEFAULT_BLOCKS_BY_RANGE_QUOTA,
|
||||||
blocks_by_root_quota: Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA,
|
blocks_by_root_quota: Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA,
|
||||||
|
blobs_by_range_quota: Self::DEFAULT_BLOBS_BY_RANGE_QUOTA,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,6 +115,7 @@ impl Debug for OutboundRateLimiterConfig {
|
|||||||
.field("goodbye", fmt_q!(&self.goodbye_quota))
|
.field("goodbye", fmt_q!(&self.goodbye_quota))
|
||||||
.field("blocks_by_range", fmt_q!(&self.blocks_by_range_quota))
|
.field("blocks_by_range", fmt_q!(&self.blocks_by_range_quota))
|
||||||
.field("blocks_by_root", fmt_q!(&self.blocks_by_root_quota))
|
.field("blocks_by_root", fmt_q!(&self.blocks_by_root_quota))
|
||||||
|
.field("blobs_by_range", fmt_q!(&self.blobs_by_range_quota))
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +134,6 @@ impl FromStr for OutboundRateLimiterConfig {
|
|||||||
let mut goodbye_quota = None;
|
let mut goodbye_quota = None;
|
||||||
let mut blocks_by_range_quota = None;
|
let mut blocks_by_range_quota = None;
|
||||||
let mut blocks_by_root_quota = None;
|
let mut blocks_by_root_quota = None;
|
||||||
// TODO(eip4844): use this blob quota
|
|
||||||
let mut blobs_by_range_quota = None;
|
let mut blobs_by_range_quota = None;
|
||||||
for proto_def in s.split(';') {
|
for proto_def in s.split(';') {
|
||||||
let ProtocolQuota { protocol, quota } = proto_def.parse()?;
|
let ProtocolQuota { protocol, quota } = proto_def.parse()?;
|
||||||
@ -154,6 +158,8 @@ impl FromStr for OutboundRateLimiterConfig {
|
|||||||
.unwrap_or(Self::DEFAULT_BLOCKS_BY_RANGE_QUOTA),
|
.unwrap_or(Self::DEFAULT_BLOCKS_BY_RANGE_QUOTA),
|
||||||
blocks_by_root_quota: blocks_by_root_quota
|
blocks_by_root_quota: blocks_by_root_quota
|
||||||
.unwrap_or(Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA),
|
.unwrap_or(Self::DEFAULT_BLOCKS_BY_ROOT_QUOTA),
|
||||||
|
blobs_by_range_quota: blobs_by_range_quota
|
||||||
|
.unwrap_or(Self::DEFAULT_BLOBS_BY_RANGE_QUOTA),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
|||||||
goodbye_quota,
|
goodbye_quota,
|
||||||
blocks_by_range_quota,
|
blocks_by_range_quota,
|
||||||
blocks_by_root_quota,
|
blocks_by_root_quota,
|
||||||
|
blobs_by_range_quota,
|
||||||
} = config;
|
} = config;
|
||||||
|
|
||||||
let limiter = RateLimiter::builder()
|
let limiter = RateLimiter::builder()
|
||||||
@ -69,6 +70,7 @@ impl<Id: ReqId, TSpec: EthSpec> SelfRateLimiter<Id, TSpec> {
|
|||||||
.set_quota(Protocol::Goodbye, goodbye_quota)
|
.set_quota(Protocol::Goodbye, goodbye_quota)
|
||||||
.set_quota(Protocol::BlocksByRange, blocks_by_range_quota)
|
.set_quota(Protocol::BlocksByRange, blocks_by_range_quota)
|
||||||
.set_quota(Protocol::BlocksByRoot, blocks_by_root_quota)
|
.set_quota(Protocol::BlocksByRoot, blocks_by_root_quota)
|
||||||
|
.set_quota(Protocol::BlobsByRange, blobs_by_range_quota)
|
||||||
// Manually set the LightClientBootstrap quota, since we use the same rate limiter for
|
// Manually set the LightClientBootstrap quota, since we use the same rate limiter for
|
||||||
// inbound and outbound requests, and the LightClientBootstrap is an only inbound
|
// inbound and outbound requests, and the LightClientBootstrap is an only inbound
|
||||||
// protocol.
|
// protocol.
|
||||||
|
@ -348,8 +348,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
block: &'a SignedBeaconBlock<T, Payload>,
|
block: &'a SignedBeaconBlock<T, Payload>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// FIXME(capella): to improve performance we might want to decompress the withdrawal pubkeys
|
// To improve performance we might want to decompress the withdrawal pubkeys in parallel.
|
||||||
// in parallel.
|
|
||||||
if let Ok(bls_to_execution_changes) = block.message().body().bls_to_execution_changes() {
|
if let Ok(bls_to_execution_changes) = block.message().body().bls_to_execution_changes() {
|
||||||
for bls_to_execution_change in bls_to_execution_changes {
|
for bls_to_execution_change in bls_to_execution_changes {
|
||||||
self.sets.push(bls_execution_change_signature_set(
|
self.sets.push(bls_execution_change_signature_set(
|
||||||
|
@ -37,10 +37,9 @@ pub fn verify_bls_to_execution_change<T: EthSpec>(
|
|||||||
Invalid::NonBlsWithdrawalCredentials
|
Invalid::NonBlsWithdrawalCredentials
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Re-hashing the pubkey isn't necessary during block replay, so we may want to skip that in
|
||||||
|
// future.
|
||||||
let pubkey_hash = hash(address_change.from_bls_pubkey.as_serialized());
|
let pubkey_hash = hash(address_change.from_bls_pubkey.as_serialized());
|
||||||
|
|
||||||
// FIXME: Should this check be put inside the verify_signatures.is_true() condition?
|
|
||||||
// I believe that's used for fuzzing so this is a Mehdi question..
|
|
||||||
verify!(
|
verify!(
|
||||||
validator.withdrawal_credentials.as_bytes().get(1..) == pubkey_hash.get(1..),
|
validator.withdrawal_credentials.as_bytes().get(1..) == pubkey_hash.get(1..),
|
||||||
Invalid::WithdrawalCredentialsMismatch
|
Invalid::WithdrawalCredentialsMismatch
|
||||||
|
@ -279,7 +279,7 @@ impl<E: EthSpec> From<BeaconBlockBodyMerge<E, FullPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
execution_payload: BlindedPayloadMerge {
|
execution_payload: BlindedPayloadMerge {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: From::from(&execution_payload),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Some(execution_payload),
|
Some(execution_payload),
|
||||||
@ -320,7 +320,7 @@ impl<E: EthSpec> From<BeaconBlockBodyCapella<E, FullPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
execution_payload: BlindedPayloadCapella {
|
execution_payload: BlindedPayloadCapella {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: From::from(&execution_payload),
|
||||||
},
|
},
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
},
|
},
|
||||||
@ -363,7 +363,7 @@ impl<E: EthSpec> From<BeaconBlockBodyEip4844<E, FullPayload<E>>>
|
|||||||
voluntary_exits,
|
voluntary_exits,
|
||||||
sync_aggregate,
|
sync_aggregate,
|
||||||
execution_payload: BlindedPayloadEip4844 {
|
execution_payload: BlindedPayloadEip4844 {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: From::from(&execution_payload),
|
||||||
},
|
},
|
||||||
bls_to_execution_changes,
|
bls_to_execution_changes,
|
||||||
blob_kzg_commitments,
|
blob_kzg_commitments,
|
||||||
@ -414,7 +414,7 @@ impl<E: EthSpec> BeaconBlockBodyMerge<E, FullPayload<E>> {
|
|||||||
voluntary_exits: voluntary_exits.clone(),
|
voluntary_exits: voluntary_exits.clone(),
|
||||||
sync_aggregate: sync_aggregate.clone(),
|
sync_aggregate: sync_aggregate.clone(),
|
||||||
execution_payload: BlindedPayloadMerge {
|
execution_payload: BlindedPayloadMerge {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: execution_payload.into(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,7 +447,7 @@ impl<E: EthSpec> BeaconBlockBodyCapella<E, FullPayload<E>> {
|
|||||||
voluntary_exits: voluntary_exits.clone(),
|
voluntary_exits: voluntary_exits.clone(),
|
||||||
sync_aggregate: sync_aggregate.clone(),
|
sync_aggregate: sync_aggregate.clone(),
|
||||||
execution_payload: BlindedPayloadCapella {
|
execution_payload: BlindedPayloadCapella {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: execution_payload.into(),
|
||||||
},
|
},
|
||||||
bls_to_execution_changes: bls_to_execution_changes.clone(),
|
bls_to_execution_changes: bls_to_execution_changes.clone(),
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ impl<E: EthSpec> BeaconBlockBodyEip4844<E, FullPayload<E>> {
|
|||||||
voluntary_exits: voluntary_exits.clone(),
|
voluntary_exits: voluntary_exits.clone(),
|
||||||
sync_aggregate: sync_aggregate.clone(),
|
sync_aggregate: sync_aggregate.clone(),
|
||||||
execution_payload: BlindedPayloadEip4844 {
|
execution_payload: BlindedPayloadEip4844 {
|
||||||
execution_payload_header: From::from(execution_payload.clone()),
|
execution_payload_header: execution_payload.into(),
|
||||||
},
|
},
|
||||||
bls_to_execution_changes: bls_to_execution_changes.clone(),
|
bls_to_execution_changes: bls_to_execution_changes.clone(),
|
||||||
blob_kzg_commitments: blob_kzg_commitments.clone(),
|
blob_kzg_commitments: blob_kzg_commitments.clone(),
|
||||||
|
@ -35,7 +35,9 @@ pub type Withdrawals<T> = VariableList<Withdrawal, <T as EthSpec>::MaxWithdrawal
|
|||||||
arbitrary(bound = "T: EthSpec")
|
arbitrary(bound = "T: EthSpec")
|
||||||
),
|
),
|
||||||
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||||
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
|
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
|
||||||
|
map_into(FullPayload, BlindedPayload),
|
||||||
|
map_ref_into(ExecutionPayloadHeader)
|
||||||
)]
|
)]
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug, Clone, Serialize, Encode, Deserialize, TreeHash, Derivative, arbitrary::Arbitrary,
|
Debug, Clone, Serialize, Encode, Deserialize, TreeHash, Derivative, arbitrary::Arbitrary,
|
||||||
|
@ -159,40 +159,40 @@ impl<T: EthSpec> ExecutionPayloadHeaderCapella<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayloadMerge<T>> for ExecutionPayloadHeaderMerge<T> {
|
impl<'a, T: EthSpec> From<&'a ExecutionPayloadMerge<T>> for ExecutionPayloadHeaderMerge<T> {
|
||||||
fn from(payload: ExecutionPayloadMerge<T>) -> Self {
|
fn from(payload: &'a ExecutionPayloadMerge<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parent_hash: payload.parent_hash,
|
parent_hash: payload.parent_hash,
|
||||||
fee_recipient: payload.fee_recipient,
|
fee_recipient: payload.fee_recipient,
|
||||||
state_root: payload.state_root,
|
state_root: payload.state_root,
|
||||||
receipts_root: payload.receipts_root,
|
receipts_root: payload.receipts_root,
|
||||||
logs_bloom: payload.logs_bloom,
|
logs_bloom: payload.logs_bloom.clone(),
|
||||||
prev_randao: payload.prev_randao,
|
prev_randao: payload.prev_randao,
|
||||||
block_number: payload.block_number,
|
block_number: payload.block_number,
|
||||||
gas_limit: payload.gas_limit,
|
gas_limit: payload.gas_limit,
|
||||||
gas_used: payload.gas_used,
|
gas_used: payload.gas_used,
|
||||||
timestamp: payload.timestamp,
|
timestamp: payload.timestamp,
|
||||||
extra_data: payload.extra_data,
|
extra_data: payload.extra_data.clone(),
|
||||||
base_fee_per_gas: payload.base_fee_per_gas,
|
base_fee_per_gas: payload.base_fee_per_gas,
|
||||||
block_hash: payload.block_hash,
|
block_hash: payload.block_hash,
|
||||||
transactions_root: payload.transactions.tree_hash_root(),
|
transactions_root: payload.transactions.tree_hash_root(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: EthSpec> From<ExecutionPayloadCapella<T>> for ExecutionPayloadHeaderCapella<T> {
|
impl<'a, T: EthSpec> From<&'a ExecutionPayloadCapella<T>> for ExecutionPayloadHeaderCapella<T> {
|
||||||
fn from(payload: ExecutionPayloadCapella<T>) -> Self {
|
fn from(payload: &'a ExecutionPayloadCapella<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parent_hash: payload.parent_hash,
|
parent_hash: payload.parent_hash,
|
||||||
fee_recipient: payload.fee_recipient,
|
fee_recipient: payload.fee_recipient,
|
||||||
state_root: payload.state_root,
|
state_root: payload.state_root,
|
||||||
receipts_root: payload.receipts_root,
|
receipts_root: payload.receipts_root,
|
||||||
logs_bloom: payload.logs_bloom,
|
logs_bloom: payload.logs_bloom.clone(),
|
||||||
prev_randao: payload.prev_randao,
|
prev_randao: payload.prev_randao,
|
||||||
block_number: payload.block_number,
|
block_number: payload.block_number,
|
||||||
gas_limit: payload.gas_limit,
|
gas_limit: payload.gas_limit,
|
||||||
gas_used: payload.gas_used,
|
gas_used: payload.gas_used,
|
||||||
timestamp: payload.timestamp,
|
timestamp: payload.timestamp,
|
||||||
extra_data: payload.extra_data,
|
extra_data: payload.extra_data.clone(),
|
||||||
base_fee_per_gas: payload.base_fee_per_gas,
|
base_fee_per_gas: payload.base_fee_per_gas,
|
||||||
block_hash: payload.block_hash,
|
block_hash: payload.block_hash,
|
||||||
transactions_root: payload.transactions.tree_hash_root(),
|
transactions_root: payload.transactions.tree_hash_root(),
|
||||||
@ -200,20 +200,21 @@ impl<T: EthSpec> From<ExecutionPayloadCapella<T>> for ExecutionPayloadHeaderCape
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: EthSpec> From<ExecutionPayloadEip4844<T>> for ExecutionPayloadHeaderEip4844<T> {
|
|
||||||
fn from(payload: ExecutionPayloadEip4844<T>) -> Self {
|
impl<'a, T: EthSpec> From<&'a ExecutionPayloadEip4844<T>> for ExecutionPayloadHeaderEip4844<T> {
|
||||||
|
fn from(payload: &'a ExecutionPayloadEip4844<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
parent_hash: payload.parent_hash,
|
parent_hash: payload.parent_hash,
|
||||||
fee_recipient: payload.fee_recipient,
|
fee_recipient: payload.fee_recipient,
|
||||||
state_root: payload.state_root,
|
state_root: payload.state_root,
|
||||||
receipts_root: payload.receipts_root,
|
receipts_root: payload.receipts_root,
|
||||||
logs_bloom: payload.logs_bloom,
|
logs_bloom: payload.logs_bloom.clone(),
|
||||||
prev_randao: payload.prev_randao,
|
prev_randao: payload.prev_randao,
|
||||||
block_number: payload.block_number,
|
block_number: payload.block_number,
|
||||||
gas_limit: payload.gas_limit,
|
gas_limit: payload.gas_limit,
|
||||||
gas_used: payload.gas_used,
|
gas_used: payload.gas_used,
|
||||||
timestamp: payload.timestamp,
|
timestamp: payload.timestamp,
|
||||||
extra_data: payload.extra_data,
|
extra_data: payload.extra_data.clone(),
|
||||||
base_fee_per_gas: payload.base_fee_per_gas,
|
base_fee_per_gas: payload.base_fee_per_gas,
|
||||||
excess_data_gas: payload.excess_data_gas,
|
excess_data_gas: payload.excess_data_gas,
|
||||||
block_hash: payload.block_hash,
|
block_hash: payload.block_hash,
|
||||||
@ -223,31 +224,33 @@ impl<T: EthSpec> From<ExecutionPayloadEip4844<T>> for ExecutionPayloadHeaderEip4
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayloadMerge<T>> for ExecutionPayloadHeader<T> {
|
// These impls are required to work around an inelegance in `to_execution_payload_header`.
|
||||||
fn from(payload: ExecutionPayloadMerge<T>) -> Self {
|
// They only clone headers so they should be relatively cheap.
|
||||||
Self::Merge(ExecutionPayloadHeaderMerge::from(payload))
|
impl<'a, T: EthSpec> From<&'a Self> for ExecutionPayloadHeaderMerge<T> {
|
||||||
|
fn from(payload: &'a Self) -> Self {
|
||||||
|
payload.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayloadCapella<T>> for ExecutionPayloadHeader<T> {
|
impl<'a, T: EthSpec> From<&'a Self> for ExecutionPayloadHeaderCapella<T> {
|
||||||
fn from(payload: ExecutionPayloadCapella<T>) -> Self {
|
fn from(payload: &'a Self) -> Self {
|
||||||
Self::Capella(ExecutionPayloadHeaderCapella::from(payload))
|
payload.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayloadEip4844<T>> for ExecutionPayloadHeader<T> {
|
impl<'a, T: EthSpec> From<&'a Self> for ExecutionPayloadHeaderEip4844<T> {
|
||||||
fn from(payload: ExecutionPayloadEip4844<T>) -> Self {
|
fn from(payload: &'a Self) -> Self {
|
||||||
Self::Eip4844(ExecutionPayloadHeaderEip4844::from(payload))
|
payload.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionPayloadHeader<T> {
|
impl<'a, T: EthSpec> From<ExecutionPayloadRef<'a, T>> for ExecutionPayloadHeader<T> {
|
||||||
fn from(payload: ExecutionPayload<T>) -> Self {
|
fn from(payload: ExecutionPayloadRef<'a, T>) -> Self {
|
||||||
match payload {
|
map_execution_payload_ref_into_execution_payload_header!(
|
||||||
ExecutionPayload::Merge(payload) => Self::from(payload),
|
&'a _,
|
||||||
ExecutionPayload::Capella(payload) => Self::from(payload),
|
payload,
|
||||||
ExecutionPayload::Eip4844(payload) => Self::from(payload),
|
|inner, cons| cons(inner.into())
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use serde::de::DeserializeOwned;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ssz::{Decode, Encode};
|
use ssz::{Decode, Encode};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
@ -90,15 +91,15 @@ pub trait AbstractExecPayload<T: EthSpec>:
|
|||||||
|
|
||||||
type Merge: OwnedExecPayload<T>
|
type Merge: OwnedExecPayload<T>
|
||||||
+ Into<Self>
|
+ Into<Self>
|
||||||
+ From<ExecutionPayloadMerge<T>>
|
+ for<'a> From<Cow<'a, ExecutionPayloadMerge<T>>>
|
||||||
+ TryFrom<ExecutionPayloadHeaderMerge<T>>;
|
+ TryFrom<ExecutionPayloadHeaderMerge<T>>;
|
||||||
type Capella: OwnedExecPayload<T>
|
type Capella: OwnedExecPayload<T>
|
||||||
+ Into<Self>
|
+ Into<Self>
|
||||||
+ From<ExecutionPayloadCapella<T>>
|
+ for<'a> From<Cow<'a, ExecutionPayloadCapella<T>>>
|
||||||
+ TryFrom<ExecutionPayloadHeaderCapella<T>>;
|
+ TryFrom<ExecutionPayloadHeaderCapella<T>>;
|
||||||
type Eip4844: OwnedExecPayload<T>
|
type Eip4844: OwnedExecPayload<T>
|
||||||
+ Into<Self>
|
+ Into<Self>
|
||||||
+ From<ExecutionPayloadEip4844<T>>
|
+ for<'a> From<Cow<'a, ExecutionPayloadEip4844<T>>>
|
||||||
+ TryFrom<ExecutionPayloadHeaderEip4844<T>>;
|
+ TryFrom<ExecutionPayloadHeaderEip4844<T>>;
|
||||||
|
|
||||||
fn default_at_fork(fork_name: ForkName) -> Result<Self, Error>;
|
fn default_at_fork(fork_name: ForkName) -> Result<Self, Error>;
|
||||||
@ -150,31 +151,21 @@ pub struct FullPayload<T: EthSpec> {
|
|||||||
|
|
||||||
impl<T: EthSpec> From<FullPayload<T>> for ExecutionPayload<T> {
|
impl<T: EthSpec> From<FullPayload<T>> for ExecutionPayload<T> {
|
||||||
fn from(full_payload: FullPayload<T>) -> Self {
|
fn from(full_payload: FullPayload<T>) -> Self {
|
||||||
match full_payload {
|
map_full_payload_into_execution_payload!(full_payload, move |payload, cons| {
|
||||||
FullPayload::Merge(payload) => ExecutionPayload::Merge(payload.execution_payload),
|
cons(payload.execution_payload)
|
||||||
FullPayload::Capella(payload) => ExecutionPayload::Capella(payload.execution_payload),
|
})
|
||||||
FullPayload::Eip4844(payload) => ExecutionPayload::Eip4844(payload.execution_payload),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec> From<FullPayloadRef<'a, T>> for ExecutionPayload<T> {
|
impl<'a, T: EthSpec> From<FullPayloadRef<'a, T>> for ExecutionPayload<T> {
|
||||||
fn from(full_payload_ref: FullPayloadRef<'a, T>) -> Self {
|
fn from(full_payload_ref: FullPayloadRef<'a, T>) -> Self {
|
||||||
match full_payload_ref {
|
map_full_payload_ref!(&'a _, full_payload_ref, move |payload, cons| {
|
||||||
FullPayloadRef::Merge(payload) => {
|
cons(payload);
|
||||||
ExecutionPayload::Merge(payload.execution_payload.clone())
|
payload.execution_payload.clone().into()
|
||||||
}
|
})
|
||||||
FullPayloadRef::Capella(payload) => {
|
|
||||||
ExecutionPayload::Capella(payload.execution_payload.clone())
|
|
||||||
}
|
|
||||||
FullPayloadRef::Eip4844(payload) => {
|
|
||||||
ExecutionPayload::Eip4844(payload.execution_payload.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: can this be implemented as Deref or Clone somehow?
|
|
||||||
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 {
|
||||||
map_full_payload_ref!(&'a _, full_payload_ref, move |payload, cons| {
|
map_full_payload_ref!(&'a _, full_payload_ref, move |payload, cons| {
|
||||||
@ -189,11 +180,12 @@ impl<T: EthSpec> ExecPayload<T> for FullPayload<T> {
|
|||||||
BlockType::Full
|
BlockType::Full
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_execution_payload_header(&self) -> ExecutionPayloadHeader<T> {
|
fn to_execution_payload_header<'a>(&'a self) -> ExecutionPayloadHeader<T> {
|
||||||
let payload = map_full_payload_into_execution_payload!(self.clone(), |inner, cons| {
|
map_full_payload_ref!(&'a _, self.to_ref(), move |inner, cons| {
|
||||||
cons(inner.execution_payload)
|
cons(inner);
|
||||||
});
|
let exec_payload_ref: ExecutionPayloadRef<'a, T> = From::from(&inner.execution_payload);
|
||||||
ExecutionPayloadHeader::from(payload)
|
ExecutionPayloadHeader::from(exec_payload_ref)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent_hash<'a>(&'a self) -> ExecutionBlockHash {
|
fn parent_hash<'a>(&'a self) -> ExecutionBlockHash {
|
||||||
@ -404,17 +396,9 @@ impl<T: EthSpec> AbstractExecPayload<T> for FullPayload<T> {
|
|||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayload<T>> for FullPayload<T> {
|
impl<T: EthSpec> From<ExecutionPayload<T>> for FullPayload<T> {
|
||||||
fn from(execution_payload: ExecutionPayload<T>) -> Self {
|
fn from(execution_payload: ExecutionPayload<T>) -> Self {
|
||||||
match execution_payload {
|
map_execution_payload_into_full_payload!(execution_payload, |inner, cons| {
|
||||||
ExecutionPayload::Merge(execution_payload) => {
|
cons(inner.into())
|
||||||
Self::Merge(FullPayloadMerge { execution_payload })
|
})
|
||||||
}
|
|
||||||
ExecutionPayload::Capella(execution_payload) => {
|
|
||||||
Self::Capella(FullPayloadCapella { execution_payload })
|
|
||||||
}
|
|
||||||
ExecutionPayload::Eip4844(execution_payload) => {
|
|
||||||
Self::Eip4844(FullPayloadEip4844 { execution_payload })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +650,7 @@ macro_rules! impl_exec_payload_common {
|
|||||||
$wrapped_field:ident, // execution_payload_header | execution_payload
|
$wrapped_field:ident, // execution_payload_header | execution_payload
|
||||||
$fork_variant:ident, // Merge | Merge
|
$fork_variant:ident, // Merge | Merge
|
||||||
$block_type_variant:ident, // Blinded | Full
|
$block_type_variant:ident, // Blinded | Full
|
||||||
|
$is_default_with_empty_roots:block,
|
||||||
$f:block,
|
$f:block,
|
||||||
$g:block) => {
|
$g:block) => {
|
||||||
impl<T: EthSpec> ExecPayload<T> for $wrapper_type<T> {
|
impl<T: EthSpec> ExecPayload<T> for $wrapper_type<T> {
|
||||||
@ -675,7 +660,7 @@ macro_rules! impl_exec_payload_common {
|
|||||||
|
|
||||||
fn to_execution_payload_header(&self) -> ExecutionPayloadHeader<T> {
|
fn to_execution_payload_header(&self) -> ExecutionPayloadHeader<T> {
|
||||||
ExecutionPayloadHeader::$fork_variant($wrapped_type_header::from(
|
ExecutionPayloadHeader::$fork_variant($wrapped_type_header::from(
|
||||||
self.$wrapped_field.clone(),
|
&self.$wrapped_field,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,15 +697,8 @@ macro_rules! impl_exec_payload_common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_default_with_empty_roots(&self) -> bool {
|
fn is_default_with_empty_roots(&self) -> bool {
|
||||||
// FIXME: is there a better way than ignoring this lint?
|
let f = $is_default_with_empty_roots;
|
||||||
// This is necessary because the first invocation of this macro might expand to:
|
f(self)
|
||||||
// self.execution_payload_header == ExecutionPayloadHeaderMerge::from(ExecutionPayloadMerge::default())
|
|
||||||
// but the second invocation might expand to:
|
|
||||||
// self.execution_payload == ExecutionPayloadMerge::from(ExecutionPayloadMerge::default())
|
|
||||||
#[allow(clippy::cmp_owned)]
|
|
||||||
{
|
|
||||||
self.$wrapped_field == $wrapped_type::from($wrapped_type_full::default())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transactions(&self) -> Option<&Transactions<T>> {
|
fn transactions(&self) -> Option<&Transactions<T>> {
|
||||||
@ -755,6 +733,12 @@ macro_rules! impl_exec_payload_for_fork {
|
|||||||
execution_payload_header,
|
execution_payload_header,
|
||||||
$fork_variant, // Merge
|
$fork_variant, // Merge
|
||||||
Blinded,
|
Blinded,
|
||||||
|
{
|
||||||
|
|wrapper: &$wrapper_type_header<T>| {
|
||||||
|
wrapper.execution_payload_header
|
||||||
|
== $wrapped_type_header::from(&$wrapped_type_full::default())
|
||||||
|
}
|
||||||
|
},
|
||||||
{ |_| { None } },
|
{ |_| { None } },
|
||||||
{
|
{
|
||||||
let c: for<'a> fn(&'a $wrapper_type_header<T>) -> Result<Hash256, Error> =
|
let c: for<'a> fn(&'a $wrapper_type_header<T>) -> Result<Hash256, Error> =
|
||||||
@ -788,7 +772,7 @@ macro_rules! impl_exec_payload_for_fork {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
execution_payload_header: $wrapped_type_header::from(
|
execution_payload_header: $wrapped_type_header::from(
|
||||||
$wrapped_type_full::default(),
|
&$wrapped_type_full::default(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -806,11 +790,11 @@ macro_rules! impl_exec_payload_for_fork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(sproul): consider adding references to these From impls
|
// BlindedPayload* from CoW reference to ExecutionPayload* (hopefully just a reference).
|
||||||
impl<T: EthSpec> From<$wrapped_type_full<T>> for $wrapper_type_header<T> {
|
impl<'a, T: EthSpec> From<Cow<'a, $wrapped_type_full<T>>> for $wrapper_type_header<T> {
|
||||||
fn from(execution_payload: $wrapped_type_full<T>) -> Self {
|
fn from(execution_payload: Cow<'a, $wrapped_type_full<T>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
execution_payload_header: $wrapped_type_header::from(execution_payload),
|
execution_payload_header: $wrapped_type_header::from(&*execution_payload),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -825,6 +809,11 @@ macro_rules! impl_exec_payload_for_fork {
|
|||||||
execution_payload,
|
execution_payload,
|
||||||
$fork_variant, // Merge
|
$fork_variant, // Merge
|
||||||
Full,
|
Full,
|
||||||
|
{
|
||||||
|
|wrapper: &$wrapper_type_full<T>| {
|
||||||
|
wrapper.execution_payload == $wrapped_type_full::default()
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
let c: for<'a> fn(&'a $wrapper_type_full<T>) -> Option<&'a Transactions<T>> =
|
let c: for<'a> fn(&'a $wrapper_type_full<T>) -> Option<&'a Transactions<T>> =
|
||||||
|payload: &$wrapper_type_full<T>| Some(&payload.execution_payload.transactions);
|
|payload: &$wrapper_type_full<T>| Some(&payload.execution_payload.transactions);
|
||||||
@ -848,6 +837,15 @@ macro_rules! impl_exec_payload_for_fork {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FullPayload * from CoW reference to ExecutionPayload* (hopefully already owned).
|
||||||
|
impl<'a, T: EthSpec> From<Cow<'a, $wrapped_type_full<T>>> for $wrapper_type_full<T> {
|
||||||
|
fn from(execution_payload: Cow<'a, $wrapped_type_full<T>>) -> Self {
|
||||||
|
Self {
|
||||||
|
execution_payload: $wrapped_type_full::from(execution_payload.into_owned()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> TryFrom<ExecutionPayloadHeader<T>> for $wrapper_type_full<T> {
|
impl<T: EthSpec> TryFrom<ExecutionPayloadHeader<T>> for $wrapper_type_full<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(_: ExecutionPayloadHeader<T>) -> Result<Self, Self::Error> {
|
fn try_from(_: ExecutionPayloadHeader<T>) -> Result<Self, Self::Error> {
|
||||||
@ -915,11 +913,12 @@ impl<T: EthSpec> AbstractExecPayload<T> for BlindedPayload<T> {
|
|||||||
|
|
||||||
impl<T: EthSpec> From<ExecutionPayload<T>> for BlindedPayload<T> {
|
impl<T: EthSpec> From<ExecutionPayload<T>> for BlindedPayload<T> {
|
||||||
fn from(payload: ExecutionPayload<T>) -> Self {
|
fn from(payload: ExecutionPayload<T>) -> Self {
|
||||||
match payload {
|
// This implementation is a bit wasteful in that it discards the payload body.
|
||||||
ExecutionPayload::Merge(payload) => BlindedPayload::Merge(payload.into()),
|
// Required by the top-level constraint on AbstractExecPayload but could maybe be loosened
|
||||||
ExecutionPayload::Capella(payload) => BlindedPayload::Capella(payload.into()),
|
// in future.
|
||||||
ExecutionPayload::Eip4844(payload) => BlindedPayload::Eip4844(payload.into()),
|
map_execution_payload_into_blinded_payload!(payload, |inner, cons| cons(From::from(
|
||||||
}
|
Cow::Owned(inner)
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user