Skip to content

Commit

Permalink
Added Capella Data Structures to consensus/types (sigp#3637)
Browse files Browse the repository at this point in the history
* Ran Cargo fmt

* Added Capella Data Structures to consensus/types
  • Loading branch information
ethDreamer authored and Woodpile37 committed Jan 6, 2024
1 parent cee703e commit e2a5ddb
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 34 deletions.
20 changes: 17 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions beacon_node/http_api/src/publish_blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ use beacon_chain::validator_monitor::{get_slot_delay_ms, timestamp_now};
use beacon_chain::{BeaconChain, BeaconChainTypes};
use lighthouse_network::PubsubMessage;
use network::NetworkMessage;
use slog::{Logger};
use slog::Logger;
use std::sync::Arc;
use tokio::sync::mpsc::UnboundedSender;
use types::{
SignedBlobsSidecar,
};
use types::SignedBlobsSidecar;
use warp::Rejection;

/// Handles a request from the HTTP API for full blocks.
Expand Down
2 changes: 1 addition & 1 deletion consensus/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ regex = "1.5.5"
lazy_static = "1.4.0"
parking_lot = "0.12.0"
itertools = "0.10.0"
superstruct = "0.5.0"
superstruct = "0.6.0"
serde_json = "1.0.74"
smallvec = "1.8.0"
serde_with = "1.13.0"
Expand Down
15 changes: 9 additions & 6 deletions consensus/types/src/builder_bid.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{ChainSpec, EthSpec, ExecPayload, ExecutionPayloadHeader, SignedRoot, Uint256};
use crate::{
AbstractExecPayload, ChainSpec, EthSpec, ExecPayload, ExecutionPayloadHeader, SignedRoot,
Uint256,
};
use bls::PublicKeyBytes;
use bls::Signature;
use serde::{Deserialize as De, Deserializer, Serialize as Ser, Serializer};
Expand All @@ -10,7 +13,7 @@ use tree_hash_derive::TreeHash;
#[serde_as]
#[derive(PartialEq, Debug, Serialize, Deserialize, TreeHash, Clone)]
#[serde(bound = "E: EthSpec, Payload: ExecPayload<E>")]
pub struct BuilderBid<E: EthSpec, Payload: ExecPayload<E>> {
pub struct BuilderBid<E: EthSpec, Payload: AbstractExecPayload<E>> {
#[serde_as(as = "BlindedPayloadAsHeader<E>")]
pub header: Payload,
#[serde(with = "eth2_serde_utils::quoted_u256")]
Expand All @@ -21,12 +24,12 @@ pub struct BuilderBid<E: EthSpec, Payload: ExecPayload<E>> {
_phantom_data: PhantomData<E>,
}

impl<E: EthSpec, Payload: ExecPayload<E>> SignedRoot for BuilderBid<E, Payload> {}
impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedRoot for BuilderBid<E, Payload> {}

/// Validator registration, for use in interacting with servers implementing the builder API.
#[derive(PartialEq, Debug, Serialize, Deserialize, Clone)]
#[serde(bound = "E: EthSpec, Payload: ExecPayload<E>")]
pub struct SignedBuilderBid<E: EthSpec, Payload: ExecPayload<E>> {
pub struct SignedBuilderBid<E: EthSpec, Payload: AbstractExecPayload<E>> {
pub message: BuilderBid<E, Payload>,
pub signature: Signature,
}
Expand All @@ -42,7 +45,7 @@ impl<E: EthSpec, Payload: ExecPayload<E>> SerializeAs<Payload> for BlindedPayloa
}
}

impl<'de, E: EthSpec, Payload: ExecPayload<E>> DeserializeAs<'de, Payload>
impl<'de, E: EthSpec, Payload: AbstractExecPayload<E>> DeserializeAs<'de, Payload>
for BlindedPayloadAsHeader<E>
{
fn deserialize_as<D>(deserializer: D) -> Result<Payload, D::Error>
Expand All @@ -55,7 +58,7 @@ impl<'de, E: EthSpec, Payload: ExecPayload<E>> DeserializeAs<'de, Payload>
}
}

impl<E: EthSpec, Payload: ExecPayload<E>> SignedBuilderBid<E, Payload> {
impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBuilderBid<E, Payload> {
pub fn verify_signature(&self, spec: &ChainSpec) -> bool {
self.message
.pubkey
Expand Down
68 changes: 60 additions & 8 deletions consensus/types/src/execution_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,35 @@ pub type Transactions<T> = VariableList<
<T as EthSpec>::MaxTransactionsPerPayload,
>;

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Default, Debug, Clone, Serialize, Deserialize, Encode, Decode, TreeHash, TestRandom, Derivative,
#[superstruct(
variants(Merge, Capella, Eip4844),
variant_attributes(
derive(
Default,
Debug,
Clone,
Serialize,
Deserialize,
Encode,
Decode,
TreeHash,
TestRandom,
Derivative,
),
derivative(PartialEq, Hash(bound = "T: EthSpec")),
serde(bound = "T: EthSpec", deny_unknown_fields),
cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))
),
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
)]
#[derive(Debug, Clone, Serialize, Encode, Deserialize, TreeHash, Derivative)]
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
#[serde(untagged)]
#[serde(bound = "T: EthSpec")]
#[ssz(enum_behaviour = "transparent")]
#[tree_hash(enum_behaviour = "transparent")]
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
pub struct ExecutionPayload<T: EthSpec> {
pub parent_hash: ExecutionBlockHash,
pub fee_recipient: Address,
Expand All @@ -39,9 +62,14 @@ pub struct ExecutionPayload<T: EthSpec> {
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
#[serde(with = "eth2_serde_utils::quoted_u256")]
pub base_fee_per_gas: Uint256,
#[superstruct(only(Eip4844))]
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub excess_blobs: u64,
pub block_hash: ExecutionBlockHash,
#[serde(with = "ssz_types::serde_utils::list_of_hex_var_list")]
pub transactions: Transactions<T>,
#[superstruct(only(Capella, Eip4844))]
pub withdrawals: VariableList<Withdrawal, T::MaxWithdrawalsPerPayload>,
}

#[derive(
Expand All @@ -63,22 +91,46 @@ impl <T: EthSpec> TestRandom for BlobsBundle<T> {
}

impl<T: EthSpec> ExecutionPayload<T> {
pub fn empty() -> Self {
Self::default()
#[allow(clippy::integer_arithmetic)]
/// Returns the maximum size of an execution payload.
pub fn max_execution_payload_merge_size() -> usize {
// Fixed part
ExecutionPayloadMerge::<T>::default().as_ssz_bytes().len()
// Max size of variable length `extra_data` field
+ (T::max_extra_data_bytes() * <u8 as Encode>::ssz_fixed_len())
// Max size of variable length `transactions` field
+ (T::max_transactions_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + T::max_bytes_per_transaction()))
}

#[allow(clippy::integer_arithmetic)]
/// Returns the maximum size of an execution payload.
pub fn max_execution_payload_capella_size() -> usize {
// Fixed part
ExecutionPayloadCapella::<T>::default().as_ssz_bytes().len()
// Max size of variable length `extra_data` field
+ (T::max_extra_data_bytes() * <u8 as Encode>::ssz_fixed_len())
// Max size of variable length `transactions` field
+ (T::max_transactions_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + T::max_bytes_per_transaction()))
// Max size of variable length `withdrawals` field
// TODO: check this
+ (T::max_withdrawals_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + <Withdrawal as Encode>::ssz_fixed_len()))
}

#[allow(clippy::integer_arithmetic)]
/// Returns the maximum size of an execution payload.
pub fn max_execution_payload_size() -> usize {
pub fn max_execution_payload_eip4844_size() -> usize {
// Fixed part
Self::empty().as_ssz_bytes().len()
ExecutionPayloadEip4844::<T>::default().as_ssz_bytes().len()
// Max size of variable length `extra_data` field
+ (T::max_extra_data_bytes() * <u8 as Encode>::ssz_fixed_len())
// Max size of variable length `transactions` field
+ (T::max_transactions_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + T::max_bytes_per_transaction()))
// Max size of variable length `withdrawals` field
// TODO: check this
+ (T::max_withdrawals_per_payload() * (ssz::BYTES_PER_LENGTH_OFFSET + <Withdrawal as Encode>::ssz_fixed_len()))
}

pub fn blob_txns_iter(&self) -> Iter<'_, Transaction<T::MaxBytesPerTransaction>> {
self.transactions.iter()
self.transactions().iter()
}
}
123 changes: 111 additions & 12 deletions consensus/types/src/execution_payload_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,37 @@ use ssz_derive::{Decode, Encode};
use test_random_derive::TestRandom;
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
use BeaconStateError;

#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
#[derive(
Default, Debug, Clone, Serialize, Deserialize, Derivative, Encode, Decode, TreeHash, TestRandom,
#[superstruct(
variants(Merge, Capella, Eip4844),
variant_attributes(
derive(
Default,
Debug,
Clone,
Serialize,
Deserialize,
Encode,
Decode,
TreeHash,
TestRandom,
Derivative,
),
derivative(PartialEq, Hash(bound = "T: EthSpec")),
serde(bound = "T: EthSpec", deny_unknown_fields),
cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))
),
ref_attributes(derive(PartialEq, TreeHash), tree_hash(enum_behaviour = "transparent")),
cast_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant"),
partial_getter_error(ty = "Error", expr = "BeaconStateError::IncorrectStateVariant")
)]
#[derive(Debug, Clone, Serialize, Deserialize, Encode, TreeHash, Derivative)]
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
#[serde(bound = "T: EthSpec")]
#[tree_hash(enum_behaviour = "transparent")]
#[ssz(enum_behaviour = "transparent")]
#[cfg_attr(feature = "arbitrary-fuzz", derive(arbitrary::Arbitrary))]
pub struct ExecutionPayloadHeader<T: EthSpec> {
pub parent_hash: ExecutionBlockHash,
pub fee_recipient: Address,
Expand All @@ -31,33 +56,107 @@ pub struct ExecutionPayloadHeader<T: EthSpec> {
pub extra_data: VariableList<u8, T::MaxExtraDataBytes>,
#[serde(with = "eth2_serde_utils::quoted_u256")]
pub base_fee_per_gas: Uint256,
#[superstruct(only(Eip4844))]
#[serde(with = "eth2_serde_utils::quoted_u64")]
pub excess_blobs: u64,
pub block_hash: ExecutionBlockHash,
pub transactions_root: Hash256,
#[superstruct(only(Capella, Eip4844))]
pub withdrawals_root: Hash256,
}

impl<T: EthSpec> ExecutionPayloadHeader<T> {
pub fn empty() -> Self {
Self::default()
impl<T: EthSpec> From<ExecutionPayloadMerge<T>> for ExecutionPayloadHeaderMerge<T> {
fn from(payload: ExecutionPayloadMerge<T>) -> 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,
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,
base_fee_per_gas: payload.base_fee_per_gas,
block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(),
}
}
}

impl<'a, T: EthSpec> From<&'a ExecutionPayload<T>> for ExecutionPayloadHeader<T> {
fn from(payload: &'a ExecutionPayload<T>) -> Self {
ExecutionPayloadHeader {
impl<T: EthSpec> From<ExecutionPayloadCapella<T>> for ExecutionPayloadHeaderCapella<T> {
fn from(payload: ExecutionPayloadCapella<T>) -> 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,
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,
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(),
}
}
}
impl<T: EthSpec> From<ExecutionPayloadEip4844<T>> for ExecutionPayloadHeaderEip4844<T> {
fn from(payload: ExecutionPayloadEip4844<T>) -> 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(),
logs_bloom: payload.logs_bloom,
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(),
extra_data: payload.extra_data,
base_fee_per_gas: payload.base_fee_per_gas,
excess_blobs: payload.excess_blobs,
block_hash: payload.block_hash,
transactions_root: payload.transactions.tree_hash_root(),
withdrawals_root: payload.withdrawals.tree_hash_root(),
}
}
}

impl<T: EthSpec> TryFrom<ExecutionPayloadHeader<T>> for ExecutionPayloadHeaderMerge<T> {
type Error = BeaconStateError;
fn try_from(header: ExecutionPayloadHeader<T>) -> Result<Self, Self::Error> {
match header {
ExecutionPayloadHeader::Merge(execution_payload_header) => Ok(execution_payload_header),
_ => Err(BeaconStateError::IncorrectStateVariant),
}
}
}
impl<T: EthSpec> TryFrom<ExecutionPayloadHeader<T>> for ExecutionPayloadHeaderCapella<T> {
type Error = BeaconStateError;
fn try_from(header: ExecutionPayloadHeader<T>) -> Result<Self, Self::Error> {
match header {
ExecutionPayloadHeader::Capella(execution_payload_header) => {
Ok(execution_payload_header)
}
_ => Err(BeaconStateError::IncorrectStateVariant),
}
}
}
impl<T: EthSpec> TryFrom<ExecutionPayloadHeader<T>> for ExecutionPayloadHeaderEip4844<T> {
type Error = BeaconStateError;
fn try_from(header: ExecutionPayloadHeader<T>) -> Result<Self, Self::Error> {
match header {
ExecutionPayloadHeader::Eip4844(execution_payload_header) => {
Ok(execution_payload_header)
}
_ => Err(BeaconStateError::IncorrectStateVariant),
}
}
}
Loading

0 comments on commit e2a5ddb

Please sign in to comment.