diff --git a/crates/eips/src/eip6110.rs b/crates/eips/src/eip6110.rs new file mode 100644 index 00000000000..74ac64bbdb4 --- /dev/null +++ b/crates/eips/src/eip6110.rs @@ -0,0 +1,35 @@ +//! Contains Deposit types, first introduced in the Prague hardfork: +//! +//! See also [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110): Supply validator deposits on chain +//! +//! Provides validator deposits as a list of deposit operations added to the Execution Layer block. + +use alloy_primitives::{address, Address, FixedBytes, B256}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; + +/// Mainnet deposit contract address. +pub const MAINNET_DEPOSIT_CONTRACT_ADDRESS: Address = + address!("00000000219ab540356cbb839cbe05303d7705fa"); + +/// This structure maps onto the deposit object from [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110). +#[derive(Clone, Copy, Debug, PartialEq, Eq, RlpEncodable, RlpDecodable)] +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] +pub struct Deposit { + /// Validator public key + pub pubkey: FixedBytes<48>, + /// Withdrawal credentials + pub withdrawal_credentials: B256, + /// Amount of ether deposited in gwei + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::u64_hex"))] + pub amount: u64, + /// Deposit signature + pub signature: FixedBytes<96>, + /// Deposit index + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::u64_hex"))] + pub index: u64, +} diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 2a4a82d8d61..00161bcca60 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -31,6 +31,7 @@ pub mod eip4788; pub mod eip4844; pub use eip4844::{calc_blob_gasprice, calc_excess_blob_gas}; +pub mod eip6110; pub mod merge; pub mod eip4895; diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index 3db75dace70..c3ef64e4d78 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -18,6 +18,7 @@ alloy-primitives = { workspace = true, features = ["rlp", "serde"] } alloy-consensus = { workspace = true, features = ["std"] } alloy-rpc-types.workspace = true alloy-serde.workspace = true +alloy-eips = { workspace = true, features = ["serde"] } # ssz ethereum_ssz_derive = { workspace = true, optional = true } @@ -28,11 +29,10 @@ thiserror.workspace = true # jsonrpsee jsonrpsee-types = { version = "0.22", optional = true } -alloy-eips = { workspace= true, optional = true } [features] jsonrpsee-types = ["dep:jsonrpsee-types"] -ssz = ["dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz", "alloy-rpc-types/ssz", "dep:alloy-eips", "alloy-eips/ssz"] +ssz = ["dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz", "alloy-rpc-types/ssz", "alloy-eips/ssz"] kzg = ["alloy-consensus/kzg"] [dev-dependencies] diff --git a/crates/rpc-types-engine/src/exit.rs b/crates/rpc-types-engine/src/exit.rs new file mode 100644 index 00000000000..669ddb08deb --- /dev/null +++ b/crates/rpc-types-engine/src/exit.rs @@ -0,0 +1,24 @@ +//! Contains Exit types, first introduced in the Prague hardfork: +//! +//! See also [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110). + +use alloy_primitives::{FixedBytes, B256}; +use serde::{Deserialize, Serialize}; + +/// This structure maps onto the exit object +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ExitV1 { + /// Validator public key + pub pubkey: FixedBytes<48>, + /// Withdrawal credentials + pub withdrawal_credentials: B256, + /// Amount of withdrawn ether in gwei + #[serde(with = "alloy_serde::u64_hex")] + pub amount: u64, + /// Deposit signature + pub signature: FixedBytes<96>, + /// Deposit index + #[serde(with = "alloy_serde::u64_hex")] + pub index: u64, +} diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index 2d6f8d958db..fef6851dfd2 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -21,12 +21,16 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod cancun; +mod exit; mod forkchoice; mod optimism; pub mod payload; mod transition; -pub use self::{cancun::*, forkchoice::*, optimism::*, payload::*, transition::*}; +pub use self::{cancun::*, exit::*, forkchoice::*, optimism::*, payload::*, transition::*}; + +#[doc(inline)] +pub use alloy_eips::eip6110::Deposit; /// The list of all supported Engine capabilities available over the engine endpoint. pub const CAPABILITIES: [&str; 12] = [ diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 6ce057cfbea..dde0bfb2d21 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -1,5 +1,7 @@ //! Payload types. +use crate::ExitV1; use alloy_consensus::{Blob, Bytes48}; +use alloy_eips::eip6110::Deposit; use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256}; use alloy_rpc_types::{transaction::BlobTransactionSidecar, Withdrawal}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; @@ -399,6 +401,38 @@ impl ssz::Encode for ExecutionPayloadV3 { } } +/// This structure maps on the ExecutionPayloadV4 structure of the beacon chain spec. +/// +/// See also: +/// +/// This structure has the syntax of ExecutionPayloadV3 and appends the new fields: depositReceipts +/// and exits. +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ExecutionPayloadV4 { + /// Inner V3 payload + #[serde(flatten)] + pub payload_inner: ExecutionPayloadV3, + /// Array of deposits. + /// + /// This maps directly to the Deposits defined in [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110). + pub deposit_receipts: Vec, + /// Array of exits + pub exits: Vec, +} + +impl ExecutionPayloadV4 { + /// Returns the withdrawals for the payload. + pub const fn withdrawals(&self) -> &Vec { + self.payload_inner.withdrawals() + } + + /// Returns the timestamp for the payload. + pub const fn timestamp(&self) -> u64 { + self.payload_inner.payload_inner.timestamp() + } +} + /// This includes all bundled blob related data of an executed payload. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct BlobsBundleV1 {