diff --git a/Cargo.toml b/Cargo.toml index 612224dd..fecfa308 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ op-alloy-rpc-jsonrpsee = { version = "0.2.10", path = "crates/rpc-jsonrpsee" } op-alloy-rpc-types = { version = "0.2.10", path = "crates/rpc-types" } op-alloy-rpc-types-engine = { version = "0.2.10", path = "crates/rpc-types-engine" } op-alloy-consensus = { version = "0.2.10", path = "crates/consensus", default-features = false } +op-alloy-protocol = { version = "0.2.9", path = "crates/protocol", default-features = false } alloy-rlp = { version = "0.3", default-features = false } alloy-primitives = { version = "0.8", default-features = false } @@ -41,7 +42,7 @@ alloy = { version = "0.3.4" } alloy-consensus = { version = "0.3.4", default-features = false } alloy-network = { version = "0.3.4", default-features = false } alloy-rpc-types = { version = "0.3.4" } -alloy-rpc-types-engine = { version = "0.3.4" } +alloy-rpc-types-engine = { version = "0.3.4", default-features = false } alloy-rpc-types-eth = { version = "0.3.4" } alloy-eips = { version = "0.3.4", default-features = false } alloy-serde = { version = "0.3.4", default-features = false } diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index 940e16ed..53a2b1fd 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -14,9 +14,15 @@ exclude.workspace = true [dependencies] alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true -alloy-serde.workspace = true +op-alloy-protocol.workspace = true -serde.workspace = true +# serde +serde = { workspace = true, optional = true } +alloy-serde = { workspace = true, optional = true } [dev-dependencies] serde_json.workspace = true + +[features] +default = ["serde"] +serde = ["dep:serde", "dep:alloy-serde", "alloy-rpc-types-engine/serde", "op-alloy-protocol/serde"] diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 64f0f33e..eaab8499 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -2,34 +2,77 @@ use alloy_primitives::{Bytes, B256, U256}; use alloy_rpc_types_engine::{ BlobsBundleV1, ExecutionPayloadV3, ExecutionPayloadV4, PayloadAttributes, }; -use serde::{Deserialize, Serialize}; +use op_alloy_protocol::L2BlockInfo; /// Optimism Payload Attributes -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct OptimismPayloadAttributes { /// The payload attributes - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub payload_attributes: PayloadAttributes, /// Transactions is a field for rollups: the transactions list is forced into the block - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub transactions: Option>, /// If true, the no transactions are taken out of the tx-pool, only transactions from the above /// Transactions list will be included. - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub no_tx_pool: Option, /// If set, this sets the exact gas limit the block produced with. - #[serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt") + )] pub gas_limit: Option, } +/// Optimism Payload Attributes with parent block reference. +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct OptimismAttributesWithParent { + /// The payload attributes. + pub attributes: OptimismPayloadAttributes, + /// The parent block reference. + pub parent: L2BlockInfo, + /// Whether the current batch is the last in its span. + pub is_last_in_span: bool, +} + +impl OptimismAttributesWithParent { + /// Create a new [OptimismAttributesWithParent] instance. + pub const fn new( + attributes: OptimismPayloadAttributes, + parent: L2BlockInfo, + is_last_in_span: bool, + ) -> Self { + Self { attributes, parent, is_last_in_span } + } + + /// Returns the payload attributes. + pub const fn attributes(&self) -> &OptimismPayloadAttributes { + &self.attributes + } + + /// Returns the parent block reference. + pub const fn parent(&self) -> &L2BlockInfo { + &self.parent + } + + /// Returns whether the current batch is the last in its span. + pub const fn is_last_in_span(&self) -> bool { + self.is_last_in_span + } +} + /// This structure maps for the return value of `engine_getPayload` of the beacon chain spec, for /// V3. /// /// See also: /// [Optimism execution payload envelope v3] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct OptimismExecutionPayloadEnvelopeV3 { /// Execution payload V3 pub execution_payload: ExecutionPayloadV3, @@ -49,8 +92,9 @@ pub struct OptimismExecutionPayloadEnvelopeV3 { /// /// See also: /// [Optimism execution payload envelope v4] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct OptimismExecutionPayloadEnvelopeV4 { /// Execution payload V4 pub execution_payload: ExecutionPayloadV4, @@ -70,6 +114,7 @@ mod tests { use super::*; #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_execution_payload_envelope_v3() { // pulled from a geth response getPayloadV3 in hive tests, modified to add a mock parent // beacon block root.