mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 12:47:05 +00:00
Many fixes
This commit is contained in:
@@ -13,8 +13,7 @@ use crate::{
|
||||
execution::{
|
||||
ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
ExecutionRequests,
|
||||
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut, ExecutionRequests,
|
||||
},
|
||||
fork::{ForkName, ForkVersionDecode},
|
||||
kzg_ext::KzgCommitments,
|
||||
@@ -22,7 +21,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu),
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
|
||||
variant_attributes(
|
||||
derive(
|
||||
PartialEq,
|
||||
@@ -53,13 +52,11 @@ pub struct BuilderBid<E: EthSpec> {
|
||||
pub header: ExecutionPayloadHeaderDeneb<E>,
|
||||
#[superstruct(only(Electra), partial_getter(rename = "header_electra"))]
|
||||
pub header: ExecutionPayloadHeaderElectra<E>,
|
||||
#[superstruct(only(Heze), partial_getter(rename = "header_heze"))]
|
||||
pub header: ExecutionPayloadHeaderHeze<E>,
|
||||
#[superstruct(only(Fulu), partial_getter(rename = "header_fulu"))]
|
||||
pub header: ExecutionPayloadHeaderFulu<E>,
|
||||
#[superstruct(only(Deneb, Electra, Heze, Fulu))]
|
||||
#[superstruct(only(Deneb, Electra, Fulu))]
|
||||
pub blob_kzg_commitments: KzgCommitments<E>,
|
||||
#[superstruct(only(Electra, Heze, Fulu))]
|
||||
#[superstruct(only(Electra, Fulu))]
|
||||
pub execution_requests: ExecutionRequests<E>,
|
||||
#[serde(with = "serde_utils::quoted_u256")]
|
||||
pub value: Uint256,
|
||||
@@ -92,7 +89,7 @@ impl<E: EthSpec> ForkVersionDecode for BuilderBid<E> {
|
||||
/// SSZ decode with explicit fork variant.
|
||||
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError> {
|
||||
let builder_bid = match fork_name {
|
||||
ForkName::Altair | ForkName::Base | ForkName::Gloas => {
|
||||
ForkName::Altair | ForkName::Base | ForkName::Gloas | ForkName::Heze => {
|
||||
return Err(ssz::DecodeError::BytesInvalid(format!(
|
||||
"unsupported fork for ExecutionPayloadHeader: {fork_name}",
|
||||
)));
|
||||
@@ -103,7 +100,6 @@ impl<E: EthSpec> ForkVersionDecode for BuilderBid<E> {
|
||||
ForkName::Capella => BuilderBid::Capella(BuilderBidCapella::from_ssz_bytes(bytes)?),
|
||||
ForkName::Deneb => BuilderBid::Deneb(BuilderBidDeneb::from_ssz_bytes(bytes)?),
|
||||
ForkName::Electra => BuilderBid::Electra(BuilderBidElectra::from_ssz_bytes(bytes)?),
|
||||
ForkName::Heze => BuilderBid::Heze(BuilderBidHeze::from_ssz_bytes(bytes)?),
|
||||
ForkName::Fulu => BuilderBid::Fulu(BuilderBidFulu::from_ssz_bytes(bytes)?),
|
||||
};
|
||||
Ok(builder_bid)
|
||||
@@ -160,10 +156,7 @@ impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for BuilderBid<E> {
|
||||
ForkName::Fulu => {
|
||||
Self::Fulu(Deserialize::deserialize(deserializer).map_err(convert_err)?)
|
||||
}
|
||||
ForkName::Heze => {
|
||||
Self::Heze(Deserialize::deserialize(deserializer).map_err(convert_err)?)
|
||||
}
|
||||
ForkName::Base | ForkName::Altair | ForkName::Gloas => {
|
||||
ForkName::Base | ForkName::Altair | ForkName::Gloas | ForkName::Heze => {
|
||||
return Err(serde::de::Error::custom(format!(
|
||||
"BuilderBid failed to deserialize: unsupported fork '{}'",
|
||||
context
|
||||
|
||||
@@ -7,7 +7,7 @@ mod proposer_preferences;
|
||||
pub use builder::{Builder, BuilderIndex};
|
||||
pub use builder_bid::{
|
||||
BuilderBid, BuilderBidBellatrix, BuilderBidCapella, BuilderBidDeneb, BuilderBidElectra,
|
||||
BuilderBidFulu, BuilderBidHeze, SignedBuilderBid,
|
||||
BuilderBidFulu, SignedBuilderBid,
|
||||
};
|
||||
pub use builder_pending_payment::BuilderPendingPayment;
|
||||
pub use builder_pending_withdrawal::BuilderPendingWithdrawal;
|
||||
|
||||
@@ -29,10 +29,8 @@ macro_rules! map_execution_payload_into_full_payload {
|
||||
let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f;
|
||||
f(inner, FullPayload::Fulu)
|
||||
}
|
||||
ExecutionPayload::Gloas(_) => panic!("FullPayload::Gloas does not exist!"),
|
||||
ExecutionPayload::Heze(inner) => {
|
||||
let f: fn(ExecutionPayloadHeze<_>, fn(_) -> _) -> _ = $f;
|
||||
f(inner, FullPayload::Heze)
|
||||
ExecutionPayload::Gloas(_) | ExecutionPayload::Heze(_) => {
|
||||
panic!("FullPayload::Gloas does not exist!")
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -62,10 +60,8 @@ macro_rules! map_execution_payload_into_blinded_payload {
|
||||
let f: fn(ExecutionPayloadFulu<_>, fn(_) -> _) -> _ = $f;
|
||||
f(inner, BlindedPayload::Fulu)
|
||||
}
|
||||
ExecutionPayload::Gloas(_) => panic!("BlindedPayload::Gloas does not exist!"),
|
||||
ExecutionPayload::Heze(inner) => {
|
||||
let f: fn(ExecutionPayloadHeze<_>, fn(_) -> _) -> _ = $f;
|
||||
f(inner, BlindedPayload::Heze)
|
||||
ExecutionPayload::Gloas(_) | ExecutionPayload::Heze(_) => {
|
||||
panic!("BlindedPayload::Gloas does not exist!")
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -110,14 +106,7 @@ macro_rules! map_execution_payload_ref_into_execution_payload_header {
|
||||
) -> _ = $f;
|
||||
f(inner, ExecutionPayloadHeader::Fulu)
|
||||
}
|
||||
ExecutionPayloadRef::Gloas(_) => panic!("ExecutionPayloadHeader::Gloas does not exist!"),
|
||||
ExecutionPayloadRef::Heze(inner) => {
|
||||
let f: fn(
|
||||
&$lifetime ExecutionPayloadHeze<_>,
|
||||
fn(_) -> _,
|
||||
) -> _ = $f;
|
||||
f(inner, ExecutionPayloadHeader::Heze)
|
||||
}
|
||||
ExecutionPayloadRef::Gloas(_) | ExecutionPayloadRef::Heze(_) => panic!("ExecutionPayloadHeader::Gloas does not exist!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +1,135 @@
|
||||
use crate::execution::{ExecutionPayloadGloas, ExecutionRequests};
|
||||
use crate::execution::{
|
||||
ExecutionPayloadGloas, ExecutionPayloadHeze, ExecutionPayloadRef, ExecutionRequests,
|
||||
};
|
||||
use crate::fork::ForkVersionDecode;
|
||||
use crate::state::BeaconStateError;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{EthSpec, ForkName, Hash256, SignedRoot, Slot};
|
||||
use context_deserialize::context_deserialize;
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use fixed_bytes::FixedBytesExtended;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::{BYTES_PER_LENGTH_OFFSET, Encode as SszEncode};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Encode, Decode, Deserialize, TestRandom, TreeHash, Educe)]
|
||||
#[superstruct(
|
||||
variants(Gloas, Heze),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Default,
|
||||
Debug,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TreeHash,
|
||||
TestRandom,
|
||||
Educe,
|
||||
),
|
||||
educe(PartialEq, Hash(bound(E: EthSpec))),
|
||||
serde(bound = "E: EthSpec", deny_unknown_fields),
|
||||
cfg_attr(
|
||||
feature = "arbitrary",
|
||||
derive(arbitrary::Arbitrary),
|
||||
arbitrary(bound = "E: EthSpec"),
|
||||
),
|
||||
context_deserialize(ForkName),
|
||||
),
|
||||
ref_attributes(
|
||||
derive(PartialEq, TreeHash, Debug),
|
||||
tree_hash(enum_behaviour = "transparent")
|
||||
),
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "arbitrary",
|
||||
derive(arbitrary::Arbitrary),
|
||||
arbitrary(bound = "E: EthSpec")
|
||||
)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Encode, TreeHash, Educe)]
|
||||
#[educe(PartialEq, Hash(bound(E: EthSpec)))]
|
||||
#[context_deserialize(ForkName)]
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
#[serde(bound = "E: EthSpec", untagged)]
|
||||
#[tree_hash(enum_behaviour = "transparent")]
|
||||
#[ssz(enum_behaviour = "transparent")]
|
||||
pub struct ExecutionPayloadEnvelope<E: EthSpec> {
|
||||
#[superstruct(only(Gloas), partial_getter(rename = "payload_gloas"))]
|
||||
pub payload: ExecutionPayloadGloas<E>,
|
||||
#[superstruct(only(Heze), partial_getter(rename = "payload_heze"))]
|
||||
pub payload: ExecutionPayloadHeze<E>,
|
||||
pub execution_requests: ExecutionRequests<E>,
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
#[superstruct(getter(copy))]
|
||||
pub builder_index: u64,
|
||||
#[superstruct(getter(copy))]
|
||||
pub beacon_block_root: Hash256,
|
||||
#[superstruct(getter(copy))]
|
||||
pub parent_beacon_block_root: Hash256,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
|
||||
/// Returns an empty envelope with all fields zeroed. Used for SSZ size calculations.
|
||||
pub fn slot(&self) -> Slot {
|
||||
match self {
|
||||
Self::Gloas(env) => env.payload.slot_number,
|
||||
Self::Heze(env) => env.payload.slot_number,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn payload(&self) -> ExecutionPayloadRef<'_, E> {
|
||||
match self {
|
||||
Self::Gloas(env) => ExecutionPayloadRef::Gloas(&env.payload),
|
||||
Self::Heze(env) => ExecutionPayloadRef::Heze(&env.payload),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> ExecutionPayloadEnvelopeRef<'a, E> {
|
||||
pub fn slot(&self) -> Slot {
|
||||
match self {
|
||||
Self::Gloas(env) => env.payload.slot_number,
|
||||
Self::Heze(env) => env.payload.slot_number,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn payload(&self) -> ExecutionPayloadRef<'_, E> {
|
||||
match self {
|
||||
Self::Gloas(env) => ExecutionPayloadRef::Gloas(&env.payload),
|
||||
Self::Heze(env) => ExecutionPayloadRef::Heze(&env.payload),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ExecutionPayloadEnvelopeGloas<E> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
payload: ExecutionPayloadGloas::default(),
|
||||
execution_requests: ExecutionRequests::default(),
|
||||
builder_index: 0,
|
||||
beacon_block_root: Hash256::zero(),
|
||||
parent_beacon_block_root: Hash256::zero(),
|
||||
beacon_block_root: Hash256::ZERO,
|
||||
parent_beacon_block_root: Hash256::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the minimum SSZ-encoded size (all variable-length fields empty).
|
||||
pub fn min_size() -> usize {
|
||||
Self::empty().as_ssz_bytes().len()
|
||||
}
|
||||
|
||||
/// Returns the maximum SSZ-encoded size.
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn max_size() -> usize {
|
||||
Self::min_size()
|
||||
// ExecutionPayloadGloas variable-length fields:
|
||||
+ (E::max_extra_data_bytes() * <u8 as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_transactions_per_payload()
|
||||
* (BYTES_PER_LENGTH_OFFSET + E::max_bytes_per_transaction()))
|
||||
+ (E::max_withdrawals_per_payload()
|
||||
* <crate::Withdrawal as SszEncode>::ssz_fixed_len())
|
||||
// ExecutionRequests variable-length fields:
|
||||
+ (E::max_withdrawals_per_payload() * <crate::Withdrawal as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_deposit_requests_per_payload()
|
||||
* <crate::DepositRequest as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_withdrawal_requests_per_payload()
|
||||
@@ -58,18 +137,99 @@ impl<E: EthSpec> ExecutionPayloadEnvelope<E> {
|
||||
+ (E::max_consolidation_requests_per_payload()
|
||||
* <crate::ConsolidationRequest as SszEncode>::ssz_fixed_len())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn slot(&self) -> Slot {
|
||||
self.payload.slot_number
|
||||
impl<E: EthSpec> ExecutionPayloadEnvelopeHeze<E> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
payload: ExecutionPayloadHeze::default(),
|
||||
execution_requests: ExecutionRequests::default(),
|
||||
builder_index: 0,
|
||||
beacon_block_root: Hash256::ZERO,
|
||||
parent_beacon_block_root: Hash256::ZERO,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn min_size() -> usize {
|
||||
Self::empty().as_ssz_bytes().len()
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn max_size() -> usize {
|
||||
Self::min_size()
|
||||
+ (E::max_extra_data_bytes() * <u8 as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_transactions_per_payload()
|
||||
* (BYTES_PER_LENGTH_OFFSET + E::max_bytes_per_transaction()))
|
||||
+ (E::max_withdrawals_per_payload() * <crate::Withdrawal as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_deposit_requests_per_payload()
|
||||
* <crate::DepositRequest as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_withdrawal_requests_per_payload()
|
||||
* <crate::WithdrawalRequest as SszEncode>::ssz_fixed_len())
|
||||
+ (E::max_consolidation_requests_per_payload()
|
||||
* <crate::ConsolidationRequest as SszEncode>::ssz_fixed_len())
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ForkVersionDecode for ExecutionPayloadEnvelope<E> {
|
||||
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError> {
|
||||
match fork_name {
|
||||
ForkName::Gloas => {
|
||||
<ExecutionPayloadEnvelopeGloas<E> as ssz::Decode>::from_ssz_bytes(bytes)
|
||||
.map(Self::Gloas)
|
||||
}
|
||||
ForkName::Heze => {
|
||||
<ExecutionPayloadEnvelopeHeze<E> as ssz::Decode>::from_ssz_bytes(bytes)
|
||||
.map(Self::Heze)
|
||||
}
|
||||
_ => Err(ssz::DecodeError::BytesInvalid(format!(
|
||||
"unsupported fork for ExecutionPayloadEnvelope: {fork_name}",
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelope<E> {}
|
||||
impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelopeGloas<E> {}
|
||||
impl<E: EthSpec> SignedRoot for ExecutionPayloadEnvelopeHeze<E> {}
|
||||
impl<'a, E: EthSpec> SignedRoot for ExecutionPayloadEnvelopeRef<'a, E> {}
|
||||
|
||||
impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for ExecutionPayloadEnvelope<E> {
|
||||
fn context_deserialize<D>(deserializer: D, context: ForkName) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let convert_err = |e| {
|
||||
serde::de::Error::custom(format!(
|
||||
"ExecutionPayloadEnvelope failed to deserialize: {:?}",
|
||||
e
|
||||
))
|
||||
};
|
||||
match context {
|
||||
ForkName::Heze => Ok(Self::Heze(
|
||||
Deserialize::deserialize(deserializer).map_err(convert_err)?,
|
||||
)),
|
||||
ForkName::Gloas => Ok(Self::Gloas(
|
||||
Deserialize::deserialize(deserializer).map_err(convert_err)?,
|
||||
)),
|
||||
_ => Err(serde::de::Error::custom(format!(
|
||||
"ExecutionPayloadEnvelope failed to deserialize: unsupported fork '{}'",
|
||||
context
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::MainnetEthSpec;
|
||||
|
||||
ssz_and_tree_hash_tests!(ExecutionPayloadEnvelope<MainnetEthSpec>);
|
||||
mod gloas {
|
||||
use super::*;
|
||||
ssz_and_tree_hash_tests!(ExecutionPayloadEnvelopeGloas<MainnetEthSpec>);
|
||||
}
|
||||
mod heze {
|
||||
use super::*;
|
||||
ssz_and_tree_hash_tests!(ExecutionPayloadEnvelopeHeze<MainnetEthSpec>);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ use crate::{
|
||||
core::{Address, EthSpec, ExecutionBlockHash, Hash256, Uint256},
|
||||
execution::{
|
||||
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadHeze, ExecutionPayloadRef,
|
||||
Transactions,
|
||||
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadRef, Transactions,
|
||||
},
|
||||
fork::ForkName,
|
||||
map_execution_payload_ref_into_execution_payload_header,
|
||||
@@ -24,7 +23,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu),
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Default,
|
||||
@@ -106,12 +105,12 @@ pub struct ExecutionPayloadHeader<E: EthSpec> {
|
||||
pub block_hash: ExecutionBlockHash,
|
||||
#[superstruct(getter(copy))]
|
||||
pub transactions_root: Hash256,
|
||||
#[superstruct(only(Capella, Deneb, Electra, Heze, Fulu), partial_getter(copy))]
|
||||
#[superstruct(only(Capella, Deneb, Electra, Fulu), partial_getter(copy))]
|
||||
pub withdrawals_root: Hash256,
|
||||
#[superstruct(only(Deneb, Electra, Heze, Fulu), partial_getter(copy))]
|
||||
#[superstruct(only(Deneb, Electra, Fulu), partial_getter(copy))]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub blob_gas_used: u64,
|
||||
#[superstruct(only(Deneb, Electra, Heze, Fulu), partial_getter(copy))]
|
||||
#[superstruct(only(Deneb, Electra, Fulu), partial_getter(copy))]
|
||||
#[serde(with = "serde_utils::quoted_u64")]
|
||||
pub excess_blob_gas: u64,
|
||||
}
|
||||
@@ -166,7 +165,6 @@ impl<E: EthSpec> ExecutionPayloadHeader<E> {
|
||||
ExecutionPayloadHeader::Capella(_) => ForkName::Capella,
|
||||
ExecutionPayloadHeader::Deneb(_) => ForkName::Deneb,
|
||||
ExecutionPayloadHeader::Electra(_) => ForkName::Electra,
|
||||
ExecutionPayloadHeader::Heze(_) => ForkName::Heze,
|
||||
ExecutionPayloadHeader::Fulu(_) => ForkName::Fulu,
|
||||
}
|
||||
}
|
||||
@@ -251,30 +249,6 @@ impl<E: EthSpec> ExecutionPayloadHeaderDeneb<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ExecutionPayloadHeaderFulu<E> {
|
||||
pub fn upgrade_to_heze(&self) -> ExecutionPayloadHeaderHeze<E> {
|
||||
ExecutionPayloadHeaderHeze {
|
||||
parent_hash: self.parent_hash,
|
||||
fee_recipient: self.fee_recipient,
|
||||
state_root: self.state_root,
|
||||
receipts_root: self.receipts_root,
|
||||
logs_bloom: self.logs_bloom.clone(),
|
||||
prev_randao: self.prev_randao,
|
||||
block_number: self.block_number,
|
||||
gas_limit: self.gas_limit,
|
||||
gas_used: self.gas_used,
|
||||
timestamp: self.timestamp,
|
||||
extra_data: self.extra_data.clone(),
|
||||
base_fee_per_gas: self.base_fee_per_gas,
|
||||
block_hash: self.block_hash,
|
||||
transactions_root: self.transactions_root,
|
||||
withdrawals_root: self.withdrawals_root,
|
||||
blob_gas_used: self.blob_gas_used,
|
||||
excess_blob_gas: self.excess_blob_gas,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ExecutionPayloadHeaderElectra<E> {
|
||||
pub fn upgrade_to_fulu(&self) -> ExecutionPayloadHeaderFulu<E> {
|
||||
ExecutionPayloadHeaderFulu {
|
||||
@@ -390,30 +364,6 @@ impl<'a, E: EthSpec> From<&'a ExecutionPayloadElectra<E>> for ExecutionPayloadHe
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> From<&'a ExecutionPayloadHeze<E>> for ExecutionPayloadHeaderHeze<E> {
|
||||
fn from(payload: &'a ExecutionPayloadHeze<E>) -> Self {
|
||||
Self {
|
||||
parent_hash: payload.parent_hash,
|
||||
fee_recipient: payload.fee_recipient,
|
||||
state_root: payload.state_root,
|
||||
receipts_root: payload.receipts_root,
|
||||
logs_bloom: payload.logs_bloom.clone(),
|
||||
prev_randao: payload.prev_randao,
|
||||
block_number: payload.block_number,
|
||||
gas_limit: payload.gas_limit,
|
||||
gas_used: payload.gas_used,
|
||||
timestamp: payload.timestamp,
|
||||
extra_data: payload.extra_data.clone(),
|
||||
base_fee_per_gas: payload.base_fee_per_gas,
|
||||
block_hash: payload.block_hash,
|
||||
transactions_root: payload.transactions.tree_hash_root(),
|
||||
withdrawals_root: payload.withdrawals.tree_hash_root(),
|
||||
blob_gas_used: payload.blob_gas_used,
|
||||
excess_blob_gas: payload.excess_blob_gas,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> From<&'a ExecutionPayloadFulu<E>> for ExecutionPayloadHeaderFulu<E> {
|
||||
fn from(payload: &'a ExecutionPayloadFulu<E>) -> Self {
|
||||
Self {
|
||||
@@ -464,12 +414,6 @@ impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderElectra<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderHeze<E> {
|
||||
fn from(payload: &'a Self) -> Self {
|
||||
payload.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, E: EthSpec> From<&'a Self> for ExecutionPayloadHeaderFulu<E> {
|
||||
fn from(payload: &'a Self) -> Self {
|
||||
payload.clone()
|
||||
@@ -534,9 +478,6 @@ impl<E: EthSpec> ExecutionPayloadHeaderRefMut<'_, E> {
|
||||
ExecutionPayloadHeaderRefMut::Electra(mut_ref) => {
|
||||
*mut_ref = header.try_into()?;
|
||||
}
|
||||
ExecutionPayloadHeaderRefMut::Heze(mut_ref) => {
|
||||
*mut_ref = header.try_into()?;
|
||||
}
|
||||
ExecutionPayloadHeaderRefMut::Fulu(mut_ref) => {
|
||||
*mut_ref = header.try_into()?;
|
||||
}
|
||||
@@ -557,16 +498,6 @@ impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for ExecutionPayloadHeaderEl
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for ExecutionPayloadHeaderHeze<E> {
|
||||
type Error = BeaconStateError;
|
||||
fn try_from(header: ExecutionPayloadHeader<E>) -> Result<Self, Self::Error> {
|
||||
match header {
|
||||
ExecutionPayloadHeader::Heze(execution_payload_header) => Ok(execution_payload_header),
|
||||
_ => Err(BeaconStateError::IncorrectStateVariant),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for ExecutionPayloadHeaderFulu<E> {
|
||||
type Error = BeaconStateError;
|
||||
fn try_from(header: ExecutionPayloadHeader<E>) -> Result<Self, Self::Error> {
|
||||
|
||||
@@ -25,11 +25,14 @@ pub use execution_payload::{
|
||||
pub use execution_payload_bid::{
|
||||
ExecutionPayloadBid, ExecutionPayloadBidGloas, ExecutionPayloadBidHeze, ExecutionPayloadBidRef,
|
||||
};
|
||||
pub use execution_payload_envelope::ExecutionPayloadEnvelope;
|
||||
pub use execution_payload_envelope::{
|
||||
ExecutionPayloadEnvelope, ExecutionPayloadEnvelopeGloas, ExecutionPayloadEnvelopeHeze,
|
||||
ExecutionPayloadEnvelopeRef,
|
||||
};
|
||||
pub use execution_payload_header::{
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderHeze, ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
ExecutionPayloadHeaderRef, ExecutionPayloadHeaderRefMut,
|
||||
};
|
||||
pub use execution_requests::{
|
||||
ConsolidationRequests, DepositRequests, ExecutionRequests, RequestType, WithdrawalRequests,
|
||||
@@ -39,14 +42,17 @@ pub use inclusion_list::{
|
||||
};
|
||||
pub use payload::{
|
||||
AbstractExecPayload, BlindedPayload, BlindedPayloadBellatrix, BlindedPayloadCapella,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadHeze,
|
||||
BlindedPayloadRef, BlockProductionVersion, BlockType, ExecPayload, FullPayload,
|
||||
FullPayloadBellatrix, FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra,
|
||||
FullPayloadFulu, FullPayloadHeze, FullPayloadRef, OwnedExecPayload,
|
||||
BlindedPayloadDeneb, BlindedPayloadElectra, BlindedPayloadFulu, BlindedPayloadRef,
|
||||
BlockProductionVersion, BlockType, ExecPayload, FullPayload, FullPayloadBellatrix,
|
||||
FullPayloadCapella, FullPayloadDeneb, FullPayloadElectra, FullPayloadFulu, FullPayloadRef,
|
||||
OwnedExecPayload,
|
||||
};
|
||||
pub use signed_bls_to_execution_change::SignedBlsToExecutionChange;
|
||||
pub use signed_execution_payload_bid::{
|
||||
SignedExecutionPayloadBid, SignedExecutionPayloadBidGloas, SignedExecutionPayloadBidHeze,
|
||||
SignedExecutionPayloadBidRef,
|
||||
};
|
||||
pub use signed_execution_payload_envelope::SignedExecutionPayloadEnvelope;
|
||||
pub use signed_execution_payload_envelope::{
|
||||
SignedExecutionPayloadEnvelope, SignedExecutionPayloadEnvelopeGloas,
|
||||
SignedExecutionPayloadEnvelopeHeze, SignedExecutionPayloadEnvelopeRef,
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::{
|
||||
ExecutionPayloadDeneb, ExecutionPayloadElectra, ExecutionPayloadFulu,
|
||||
ExecutionPayloadHeader, ExecutionPayloadHeaderBellatrix, ExecutionPayloadHeaderCapella,
|
||||
ExecutionPayloadHeaderDeneb, ExecutionPayloadHeaderElectra, ExecutionPayloadHeaderFulu,
|
||||
ExecutionPayloadHeaderHeze, ExecutionPayloadHeze, ExecutionPayloadRef, Transactions,
|
||||
ExecutionPayloadRef, Transactions,
|
||||
},
|
||||
fork::ForkName,
|
||||
map_execution_payload_into_blinded_payload, map_execution_payload_into_full_payload,
|
||||
@@ -119,7 +119,6 @@ pub trait AbstractExecPayload<E: EthSpec>:
|
||||
+ TryInto<Self::Deneb>
|
||||
+ TryInto<Self::Electra>
|
||||
+ TryInto<Self::Fulu>
|
||||
+ TryInto<Self::Heze>
|
||||
+ Sync
|
||||
{
|
||||
type Ref<'a>: ExecPayload<E>
|
||||
@@ -128,8 +127,7 @@ pub trait AbstractExecPayload<E: EthSpec>:
|
||||
+ From<&'a Self::Capella>
|
||||
+ From<&'a Self::Deneb>
|
||||
+ From<&'a Self::Electra>
|
||||
+ From<&'a Self::Fulu>
|
||||
+ From<&'a Self::Heze>;
|
||||
+ From<&'a Self::Fulu>;
|
||||
|
||||
type Bellatrix: OwnedExecPayload<E>
|
||||
+ Into<Self>
|
||||
@@ -156,15 +154,10 @@ pub trait AbstractExecPayload<E: EthSpec>:
|
||||
+ for<'a> From<Cow<'a, ExecutionPayloadFulu<E>>>
|
||||
+ TryFrom<ExecutionPayloadHeaderFulu<E>>
|
||||
+ Sync;
|
||||
type Heze: OwnedExecPayload<E>
|
||||
+ Into<Self>
|
||||
+ for<'a> From<Cow<'a, ExecutionPayloadHeze<E>>>
|
||||
+ TryFrom<ExecutionPayloadHeaderHeze<E>>
|
||||
+ Sync;
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu),
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Debug,
|
||||
@@ -223,8 +216,6 @@ pub struct FullPayload<E: EthSpec> {
|
||||
pub execution_payload: ExecutionPayloadDeneb<E>,
|
||||
#[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))]
|
||||
pub execution_payload: ExecutionPayloadElectra<E>,
|
||||
#[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))]
|
||||
pub execution_payload: ExecutionPayloadHeze<E>,
|
||||
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
|
||||
pub execution_payload: ExecutionPayloadFulu<E>,
|
||||
}
|
||||
@@ -338,7 +329,6 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
|
||||
FullPayload::Deneb(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayload::Electra(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayload::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayload::Heze(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +340,6 @@ impl<E: EthSpec> ExecPayload<E> for FullPayload<E> {
|
||||
FullPayload::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayload::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayload::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayload::Heze(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,7 +471,6 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
|
||||
FullPayloadRef::Electra(inner) => {
|
||||
Ok(inner.execution_payload.withdrawals.tree_hash_root())
|
||||
}
|
||||
FullPayloadRef::Heze(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.withdrawals.tree_hash_root()),
|
||||
}
|
||||
}
|
||||
@@ -494,7 +482,6 @@ impl<E: EthSpec> ExecPayload<E> for FullPayloadRef<'_, E> {
|
||||
}
|
||||
FullPayloadRef::Deneb(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayloadRef::Electra(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayloadRef::Heze(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
FullPayloadRef::Fulu(inner) => Ok(inner.execution_payload.blob_gas_used),
|
||||
}
|
||||
}
|
||||
@@ -518,7 +505,6 @@ impl<E: EthSpec> AbstractExecPayload<E> for FullPayload<E> {
|
||||
type Capella = FullPayloadCapella<E>;
|
||||
type Deneb = FullPayloadDeneb<E>;
|
||||
type Electra = FullPayloadElectra<E>;
|
||||
type Heze = FullPayloadHeze<E>;
|
||||
type Fulu = FullPayloadFulu<E>;
|
||||
}
|
||||
|
||||
@@ -538,7 +524,7 @@ impl<E: EthSpec> TryFrom<ExecutionPayloadHeader<E>> for FullPayload<E> {
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Heze, Fulu),
|
||||
variants(Bellatrix, Capella, Deneb, Electra, Fulu),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Debug,
|
||||
@@ -596,8 +582,6 @@ pub struct BlindedPayload<E: EthSpec> {
|
||||
pub execution_payload_header: ExecutionPayloadHeaderDeneb<E>,
|
||||
#[superstruct(only(Electra), partial_getter(rename = "execution_payload_electra"))]
|
||||
pub execution_payload_header: ExecutionPayloadHeaderElectra<E>,
|
||||
#[superstruct(only(Heze), partial_getter(rename = "execution_payload_heze"))]
|
||||
pub execution_payload_header: ExecutionPayloadHeaderHeze<E>,
|
||||
#[superstruct(only(Fulu), partial_getter(rename = "execution_payload_fulu"))]
|
||||
pub execution_payload_header: ExecutionPayloadHeaderFulu<E>,
|
||||
}
|
||||
@@ -689,7 +673,6 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
|
||||
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayload::Heze(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -701,7 +684,6 @@ impl<E: EthSpec> ExecPayload<E> for BlindedPayload<E> {
|
||||
BlindedPayload::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayload::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayload::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayload::Heze(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,7 +782,6 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
|
||||
BlindedPayloadRef::Electra(inner) => {
|
||||
Ok(inner.execution_payload_header.withdrawals_root)
|
||||
}
|
||||
BlindedPayloadRef::Heze(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.withdrawals_root),
|
||||
}
|
||||
}
|
||||
@@ -812,7 +793,6 @@ impl<'b, E: EthSpec> ExecPayload<E> for BlindedPayloadRef<'b, E> {
|
||||
}
|
||||
BlindedPayloadRef::Deneb(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayloadRef::Electra(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayloadRef::Heze(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
BlindedPayloadRef::Fulu(inner) => Ok(inner.execution_payload_header.blob_gas_used),
|
||||
}
|
||||
}
|
||||
@@ -1118,14 +1098,6 @@ impl_exec_payload_for_fork!(
|
||||
ExecutionPayloadElectra,
|
||||
Electra
|
||||
);
|
||||
|
||||
impl_exec_payload_for_fork!(
|
||||
BlindedPayloadHeze,
|
||||
FullPayloadHeze,
|
||||
ExecutionPayloadHeaderHeze,
|
||||
ExecutionPayloadHeze,
|
||||
Heze
|
||||
);
|
||||
impl_exec_payload_for_fork!(
|
||||
BlindedPayloadFulu,
|
||||
FullPayloadFulu,
|
||||
@@ -1140,7 +1112,6 @@ impl<E: EthSpec> AbstractExecPayload<E> for BlindedPayload<E> {
|
||||
type Capella = BlindedPayloadCapella<E>;
|
||||
type Deneb = BlindedPayloadDeneb<E>;
|
||||
type Electra = BlindedPayloadElectra<E>;
|
||||
type Heze = BlindedPayloadHeze<E>;
|
||||
type Fulu = BlindedPayloadFulu<E>;
|
||||
}
|
||||
|
||||
@@ -1178,11 +1149,6 @@ impl<E: EthSpec> From<ExecutionPayloadHeader<E>> for BlindedPayload<E> {
|
||||
execution_payload_header,
|
||||
})
|
||||
}
|
||||
ExecutionPayloadHeader::Heze(execution_payload_header) => {
|
||||
Self::Heze(BlindedPayloadHeze {
|
||||
execution_payload_header,
|
||||
})
|
||||
}
|
||||
ExecutionPayloadHeader::Fulu(execution_payload_header) => {
|
||||
Self::Fulu(BlindedPayloadFulu {
|
||||
execution_payload_header,
|
||||
@@ -1207,9 +1173,6 @@ impl<E: EthSpec> From<BlindedPayload<E>> for ExecutionPayloadHeader<E> {
|
||||
BlindedPayload::Electra(blinded_payload) => {
|
||||
ExecutionPayloadHeader::Electra(blinded_payload.execution_payload_header)
|
||||
}
|
||||
BlindedPayload::Heze(blinded_payload) => {
|
||||
ExecutionPayloadHeader::Heze(blinded_payload.execution_payload_header)
|
||||
}
|
||||
BlindedPayload::Fulu(blinded_payload) => {
|
||||
ExecutionPayloadHeader::Fulu(blinded_payload.execution_payload_header)
|
||||
}
|
||||
|
||||
@@ -1,48 +1,97 @@
|
||||
use crate::execution::{
|
||||
ExecutionPayloadEnvelopeGloas, ExecutionPayloadEnvelopeHeze, ExecutionPayloadEnvelopeRef,
|
||||
};
|
||||
use crate::fork::ForkVersionDecode;
|
||||
use crate::state::BeaconStateError;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{
|
||||
BeaconState, BeaconStateError, ChainSpec, Domain, Epoch, EthSpec, ExecutionBlockHash,
|
||||
ExecutionPayloadEnvelope, Fork, ForkName, Hash256, SignedRoot, Slot,
|
||||
consts::gloas::BUILDER_INDEX_SELF_BUILD,
|
||||
BeaconState, ChainSpec, Domain, Epoch, EthSpec, ExecutionBlockHash, Fork, ForkName, Hash256,
|
||||
SignedRoot, Slot, consts::gloas::BUILDER_INDEX_SELF_BUILD,
|
||||
};
|
||||
use bls::{PublicKey, Signature};
|
||||
use context_deserialize::context_deserialize;
|
||||
use context_deserialize::{ContextDeserialize, context_deserialize};
|
||||
use educe::Educe;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use ssz::Encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use superstruct::superstruct;
|
||||
use test_random_derive::TestRandom;
|
||||
use tree_hash_derive::TreeHash;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Encode, Decode, Deserialize, TestRandom, TreeHash, Educe)]
|
||||
#[educe(PartialEq, Hash(bound(E: EthSpec)))]
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
#[context_deserialize(ForkName)]
|
||||
#[superstruct(
|
||||
variants(Gloas, Heze),
|
||||
variant_attributes(
|
||||
derive(
|
||||
Debug,
|
||||
Clone,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
TestRandom,
|
||||
TreeHash,
|
||||
Educe,
|
||||
),
|
||||
educe(PartialEq, Hash(bound(E: EthSpec))),
|
||||
context_deserialize(ForkName),
|
||||
serde(bound = "E: EthSpec"),
|
||||
cfg_attr(
|
||||
feature = "arbitrary",
|
||||
derive(arbitrary::Arbitrary),
|
||||
arbitrary(bound = "E: EthSpec"),
|
||||
),
|
||||
),
|
||||
cast_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
partial_getter_error(
|
||||
ty = "BeaconStateError",
|
||||
expr = "BeaconStateError::IncorrectStateVariant"
|
||||
),
|
||||
map_ref_into(ExecutionPayloadEnvelopeRef)
|
||||
)]
|
||||
#[cfg_attr(
|
||||
feature = "arbitrary",
|
||||
derive(arbitrary::Arbitrary),
|
||||
arbitrary(bound = "E: EthSpec")
|
||||
)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, TreeHash)]
|
||||
#[serde(untagged)]
|
||||
#[tree_hash(enum_behaviour = "transparent")]
|
||||
#[ssz(enum_behaviour = "transparent")]
|
||||
#[serde(bound = "E: EthSpec", deny_unknown_fields)]
|
||||
pub struct SignedExecutionPayloadEnvelope<E: EthSpec> {
|
||||
#[superstruct(flatten)]
|
||||
pub message: ExecutionPayloadEnvelope<E>,
|
||||
pub signature: Signature,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
/// Returns the minimum SSZ-encoded size (all variable-length fields empty).
|
||||
pub fn min_size() -> usize {
|
||||
Self {
|
||||
message: ExecutionPayloadEnvelope::empty(),
|
||||
signature: Signature::empty(),
|
||||
pub fn message(&self) -> ExecutionPayloadEnvelopeRef<'_, E> {
|
||||
match self {
|
||||
Self::Gloas(inner) => ExecutionPayloadEnvelopeRef::Gloas(&inner.message),
|
||||
Self::Heze(inner) => ExecutionPayloadEnvelopeRef::Heze(&inner.message),
|
||||
}
|
||||
.as_ssz_bytes()
|
||||
.len()
|
||||
}
|
||||
|
||||
/// Returns the maximum SSZ-encoded size.
|
||||
pub fn min_size() -> usize {
|
||||
SignedExecutionPayloadEnvelopeGloas::<E>::empty()
|
||||
.as_ssz_bytes()
|
||||
.len()
|
||||
}
|
||||
|
||||
#[allow(clippy::arithmetic_side_effects)]
|
||||
pub fn max_size() -> usize {
|
||||
// Signature is fixed-size, so the variable-length delta is entirely from the envelope.
|
||||
Self::min_size() + ExecutionPayloadEnvelope::<E>::max_size()
|
||||
- ExecutionPayloadEnvelope::<E>::min_size()
|
||||
Self::min_size() + ExecutionPayloadEnvelopeGloas::<E>::max_size()
|
||||
- ExecutionPayloadEnvelopeGloas::<E>::min_size()
|
||||
}
|
||||
|
||||
pub fn slot(&self) -> Slot {
|
||||
self.message.slot()
|
||||
match self {
|
||||
Self::Gloas(inner) => inner.message.payload.slot_number,
|
||||
Self::Heze(inner) => inner.message.payload.slot_number,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn epoch(&self) -> Epoch {
|
||||
@@ -50,11 +99,24 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
}
|
||||
|
||||
pub fn beacon_block_root(&self) -> Hash256 {
|
||||
self.message.beacon_block_root
|
||||
match self {
|
||||
Self::Gloas(inner) => inner.message.beacon_block_root,
|
||||
Self::Heze(inner) => inner.message.beacon_block_root,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn block_hash(&self) -> ExecutionBlockHash {
|
||||
self.message.payload.block_hash
|
||||
match self {
|
||||
Self::Gloas(inner) => inner.message.payload.block_hash,
|
||||
Self::Heze(inner) => inner.message.payload.block_hash,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn builder_index(&self) -> u64 {
|
||||
match self {
|
||||
Self::Gloas(inner) => inner.message.builder_index,
|
||||
Self::Heze(inner) => inner.message.builder_index,
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify `self.signature`.
|
||||
@@ -65,8 +127,6 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
genesis_validators_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> bool {
|
||||
// Signed envelopes using the new BeaconBuilder domain per the spec:
|
||||
// https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.1/specs/gloas/beacon-chain.md#new-verify_execution_payload_envelope_signature
|
||||
let domain = spec.get_domain(
|
||||
self.epoch(),
|
||||
Domain::BeaconBuilder,
|
||||
@@ -74,9 +134,8 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
genesis_validators_root,
|
||||
);
|
||||
|
||||
let message = self.message.signing_root(domain);
|
||||
|
||||
self.signature.verify(pubkey, message)
|
||||
let message = self.message().signing_root(domain);
|
||||
self.signature().verify(pubkey, message)
|
||||
}
|
||||
|
||||
/// Verify `self.signature` using keys drawn from the beacon state.
|
||||
@@ -85,7 +144,7 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
state: &BeaconState<E>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<bool, BeaconStateError> {
|
||||
let builder_index = self.message.builder_index;
|
||||
let builder_index = self.builder_index();
|
||||
|
||||
let pubkey_bytes = if builder_index == BUILDER_INDEX_SELF_BUILD {
|
||||
let validator_index = state.latest_block_header().proposer_index;
|
||||
@@ -94,12 +153,8 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
state.get_builder(builder_index)?.pubkey
|
||||
};
|
||||
|
||||
// TODO(gloas): Could use pubkey cache on state here, but it probably isn't worth
|
||||
// it because this function is rarely used. Almost always the envelope should be signature
|
||||
// verified prior to consensus code running.
|
||||
let pubkey = pubkey_bytes.decompress()?;
|
||||
|
||||
// Ensure the state's epoch matches the message's epoch before determining the Fork.
|
||||
if self.epoch() != state.current_epoch() {
|
||||
return Err(BeaconStateError::SignedEnvelopeIncorrectEpoch {
|
||||
state_epoch: state.current_epoch(),
|
||||
@@ -116,10 +171,79 @@ impl<E: EthSpec> SignedExecutionPayloadEnvelope<E> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedExecutionPayloadEnvelopeGloas<E> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
message: ExecutionPayloadEnvelopeGloas::empty(),
|
||||
signature: Signature::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> SignedExecutionPayloadEnvelopeHeze<E> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
message: ExecutionPayloadEnvelopeHeze::empty(),
|
||||
signature: Signature::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> ForkVersionDecode for SignedExecutionPayloadEnvelope<E> {
|
||||
fn from_ssz_bytes_by_fork(bytes: &[u8], fork_name: ForkName) -> Result<Self, ssz::DecodeError> {
|
||||
match fork_name {
|
||||
ForkName::Gloas => {
|
||||
<SignedExecutionPayloadEnvelopeGloas<E> as ssz::Decode>::from_ssz_bytes(bytes)
|
||||
.map(Self::Gloas)
|
||||
}
|
||||
ForkName::Heze => {
|
||||
<SignedExecutionPayloadEnvelopeHeze<E> as ssz::Decode>::from_ssz_bytes(bytes)
|
||||
.map(Self::Heze)
|
||||
}
|
||||
_ => Err(ssz::DecodeError::BytesInvalid(format!(
|
||||
"unsupported fork for SignedExecutionPayloadEnvelope: {fork_name}",
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, E: EthSpec> ContextDeserialize<'de, ForkName> for SignedExecutionPayloadEnvelope<E> {
|
||||
fn context_deserialize<D>(deserializer: D, context: ForkName) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let convert_err = |e| {
|
||||
serde::de::Error::custom(format!(
|
||||
"SignedExecutionPayloadEnvelope failed to deserialize: {:?}",
|
||||
e
|
||||
))
|
||||
};
|
||||
match context {
|
||||
ForkName::Heze => Ok(Self::Heze(
|
||||
Deserialize::deserialize(deserializer).map_err(convert_err)?,
|
||||
)),
|
||||
ForkName::Gloas => Ok(Self::Gloas(
|
||||
Deserialize::deserialize(deserializer).map_err(convert_err)?,
|
||||
)),
|
||||
_ => Err(serde::de::Error::custom(format!(
|
||||
"SignedExecutionPayloadEnvelope failed to deserialize: unsupported fork '{}'",
|
||||
context
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::MainnetEthSpec;
|
||||
|
||||
ssz_and_tree_hash_tests!(SignedExecutionPayloadEnvelope<MainnetEthSpec>);
|
||||
mod gloas {
|
||||
use super::*;
|
||||
ssz_and_tree_hash_tests!(SignedExecutionPayloadEnvelopeGloas<MainnetEthSpec>);
|
||||
}
|
||||
mod heze {
|
||||
use super::*;
|
||||
ssz_and_tree_hash_tests!(SignedExecutionPayloadEnvelopeHeze<MainnetEthSpec>);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user