Skip to content

Commit

Permalink
chore: move optimism payload attribute types to optimism.rs files (pa…
Browse files Browse the repository at this point in the history
  • Loading branch information
Rjected authored Jan 10, 2024
1 parent e881773 commit 43cdd73
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 158 deletions.
4 changes: 3 additions & 1 deletion crates/payload/builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
pub mod database;
pub mod error;
mod metrics;
mod optimism;
mod payload;
mod service;
mod traits;
Expand All @@ -112,7 +113,8 @@ pub mod noop;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;

pub use payload::{BuiltPayload, EthPayloadBuilderAttributes, OptimismPayloadBuilderAttributes};
pub use optimism::OptimismPayloadBuilderAttributes;
pub use payload::{BuiltPayload, EthPayloadBuilderAttributes};
pub use reth_rpc_types::engine::PayloadId;
pub use service::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore};
pub use traits::{KeepPayloadJobAlive, PayloadJob, PayloadJobGenerator};
133 changes: 133 additions & 0 deletions crates/payload/builder/src/optimism.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use crate::EthPayloadBuilderAttributes;
use alloy_rlp::{Encodable, Error as DecodeError};
use reth_node_api::PayloadBuilderAttributes;
use reth_primitives::{Address, TransactionSigned, Withdrawal, B256};
use reth_rpc_types::engine::{OptimismPayloadAttributes, PayloadId};
use reth_rpc_types_compat::engine::payload::convert_standalone_withdraw_to_withdrawal;

/// Optimism Payload Builder Attributes
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OptimismPayloadBuilderAttributes {
/// Inner ethereum payload builder attributes
pub payload_attributes: EthPayloadBuilderAttributes,
/// NoTxPool option for the generated payload
pub no_tx_pool: bool,
/// Transactions for the generated payload
pub transactions: Vec<TransactionSigned>,
/// The gas limit for the generated payload
pub gas_limit: Option<u64>,
}

impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
type RpcPayloadAttributes = OptimismPayloadAttributes;
type Error = DecodeError;

/// Creates a new payload builder for the given parent block and the attributes.
///
/// Derives the unique [PayloadId] for the given parent and attributes
fn try_new(parent: B256, attributes: OptimismPayloadAttributes) -> Result<Self, DecodeError> {
let (id, transactions) = {
let transactions: Vec<_> = attributes
.transactions
.as_deref()
.unwrap_or(&[])
.iter()
.map(|tx| TransactionSigned::decode_enveloped(&mut tx.as_ref()))
.collect::<Result<_, _>>()?;
(payload_id_optimism(&parent, &attributes, &transactions), transactions)
};

let withdraw = attributes.payload_attributes.withdrawals.map(
|withdrawals: Vec<reth_rpc_types::engine::payload::Withdrawal>| {
withdrawals
.into_iter()
.map(convert_standalone_withdraw_to_withdrawal) // Removed the parentheses here
.collect::<Vec<_>>()
},
);

let payload_attributes = EthPayloadBuilderAttributes {
id,
parent,
timestamp: attributes.payload_attributes.timestamp,
suggested_fee_recipient: attributes.payload_attributes.suggested_fee_recipient,
prev_randao: attributes.payload_attributes.prev_randao,
withdrawals: withdraw.unwrap_or_default(),
parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root,
};

Ok(Self {
payload_attributes,
no_tx_pool: attributes.no_tx_pool.unwrap_or_default(),
transactions,
gas_limit: attributes.gas_limit,
})
}

fn parent(&self) -> B256 {
self.payload_attributes.parent
}

fn payload_id(&self) -> PayloadId {
self.payload_attributes.id
}

fn timestamp(&self) -> u64 {
self.payload_attributes.timestamp
}

fn parent_beacon_block_root(&self) -> Option<B256> {
self.payload_attributes.parent_beacon_block_root
}

fn suggested_fee_recipient(&self) -> Address {
self.payload_attributes.suggested_fee_recipient
}

fn prev_randao(&self) -> B256 {
self.payload_attributes.prev_randao
}

fn withdrawals(&self) -> &Vec<Withdrawal> {
&self.payload_attributes.withdrawals
}
}

/// Generates the payload id for the configured payload from the [OptimismPayloadAttributes].
///
/// Returns an 8-byte identifier by hashing the payload components with sha256 hash.
pub(crate) fn payload_id_optimism(
parent: &B256,
attributes: &OptimismPayloadAttributes,
txs: &[TransactionSigned],
) -> PayloadId {
use sha2::Digest;
let mut hasher = sha2::Sha256::new();
hasher.update(parent.as_slice());
hasher.update(&attributes.payload_attributes.timestamp.to_be_bytes()[..]);
hasher.update(attributes.payload_attributes.prev_randao.as_slice());
hasher.update(attributes.payload_attributes.suggested_fee_recipient.as_slice());
if let Some(withdrawals) = &attributes.payload_attributes.withdrawals {
let mut buf = Vec::new();
withdrawals.encode(&mut buf);
hasher.update(buf);
}

if let Some(parent_beacon_block) = attributes.payload_attributes.parent_beacon_block_root {
hasher.update(parent_beacon_block);
}

let no_tx_pool = attributes.no_tx_pool.unwrap_or_default();
if no_tx_pool || !txs.is_empty() {
hasher.update([no_tx_pool as u8]);
hasher.update(txs.len().to_be_bytes());
txs.iter().for_each(|tx| hasher.update(tx.hash()));
}

if let Some(gas_limit) = attributes.gas_limit {
hasher.update(gas_limit.to_be_bytes());
}

let out = hasher.finalize();
PayloadId::new(out.as_slice()[..8].try_into().expect("sufficient length"))
}
139 changes: 5 additions & 134 deletions crates/payload/builder/src/payload.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
//! Contains types required for building a payload.

use std::convert::Infallible;

use alloy_rlp::{Encodable, Error as DecodeError};
use alloy_rlp::Encodable;
use reth_node_api::PayloadBuilderAttributes;
use reth_primitives::{
revm::config::revm_spec_by_timestamp_after_merge,
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, SpecId},
Address, BlobTransactionSidecar, ChainSpec, Header, SealedBlock, TransactionSigned, Withdrawal,
B256, U256,
Address, BlobTransactionSidecar, ChainSpec, Header, SealedBlock, Withdrawal, B256, U256,
};
use reth_rpc_types::engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadV1,
OptimismPayloadAttributes, PayloadAttributes, PayloadId,
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadV1, PayloadAttributes,
PayloadId,
};
use reth_rpc_types_compat::engine::payload::{
block_to_payload_v3, convert_block_to_payload_field_v2,
convert_standalone_withdraw_to_withdrawal, try_block_to_payload_v1,
};
use std::convert::Infallible;

/// Contains the built payload.
///
Expand Down Expand Up @@ -276,133 +274,6 @@ impl PayloadBuilderAttributes for EthPayloadBuilderAttributes {
}
}

/// Optimism Payload Builder Attributes
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OptimismPayloadBuilderAttributes {
/// Inner ethereum payload builder attributes
pub payload_attributes: EthPayloadBuilderAttributes,
/// NoTxPool option for the generated payload
pub no_tx_pool: bool,
/// Transactions for the generated payload
pub transactions: Vec<TransactionSigned>,
/// The gas limit for the generated payload
pub gas_limit: Option<u64>,
}

impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
type RpcPayloadAttributes = OptimismPayloadAttributes;
type Error = DecodeError;

/// Creates a new payload builder for the given parent block and the attributes.
///
/// Derives the unique [PayloadId] for the given parent and attributes
fn try_new(parent: B256, attributes: OptimismPayloadAttributes) -> Result<Self, DecodeError> {
let (id, transactions) = {
let transactions: Vec<_> = attributes
.transactions
.as_deref()
.unwrap_or(&[])
.iter()
.map(|tx| TransactionSigned::decode_enveloped(&mut tx.as_ref()))
.collect::<Result<_, _>>()?;
(payload_id_optimism(&parent, &attributes, &transactions), transactions)
};

let withdraw = attributes.payload_attributes.withdrawals.map(
|withdrawals: Vec<reth_rpc_types::engine::payload::Withdrawal>| {
withdrawals
.into_iter()
.map(convert_standalone_withdraw_to_withdrawal) // Removed the parentheses here
.collect::<Vec<_>>()
},
);

let payload_attributes = EthPayloadBuilderAttributes {
id,
parent,
timestamp: attributes.payload_attributes.timestamp,
suggested_fee_recipient: attributes.payload_attributes.suggested_fee_recipient,
prev_randao: attributes.payload_attributes.prev_randao,
withdrawals: withdraw.unwrap_or_default(),
parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root,
};

Ok(Self {
payload_attributes,
no_tx_pool: attributes.no_tx_pool.unwrap_or_default(),
transactions,
gas_limit: attributes.gas_limit,
})
}

fn parent(&self) -> B256 {
self.payload_attributes.parent
}

fn payload_id(&self) -> PayloadId {
self.payload_attributes.id
}

fn timestamp(&self) -> u64 {
self.payload_attributes.timestamp
}

fn parent_beacon_block_root(&self) -> Option<B256> {
self.payload_attributes.parent_beacon_block_root
}

fn suggested_fee_recipient(&self) -> Address {
self.payload_attributes.suggested_fee_recipient
}

fn prev_randao(&self) -> B256 {
self.payload_attributes.prev_randao
}

fn withdrawals(&self) -> &Vec<Withdrawal> {
&self.payload_attributes.withdrawals
}
}

/// Generates the payload id for the configured payload from the [OptimismPayloadAttributes].
///
/// Returns an 8-byte identifier by hashing the payload components with sha256 hash.
pub(crate) fn payload_id_optimism(
parent: &B256,
attributes: &OptimismPayloadAttributes,
txs: &[TransactionSigned],
) -> PayloadId {
use sha2::Digest;
let mut hasher = sha2::Sha256::new();
hasher.update(parent.as_slice());
hasher.update(&attributes.payload_attributes.timestamp.to_be_bytes()[..]);
hasher.update(attributes.payload_attributes.prev_randao.as_slice());
hasher.update(attributes.payload_attributes.suggested_fee_recipient.as_slice());
if let Some(withdrawals) = &attributes.payload_attributes.withdrawals {
let mut buf = Vec::new();
withdrawals.encode(&mut buf);
hasher.update(buf);
}

if let Some(parent_beacon_block) = attributes.payload_attributes.parent_beacon_block_root {
hasher.update(parent_beacon_block);
}

let no_tx_pool = attributes.no_tx_pool.unwrap_or_default();
if no_tx_pool || !txs.is_empty() {
hasher.update([no_tx_pool as u8]);
hasher.update(txs.len().to_be_bytes());
txs.iter().for_each(|tx| hasher.update(tx.hash()));
}

if let Some(gas_limit) = attributes.gas_limit {
hasher.update(gas_limit.to_be_bytes());
}

let out = hasher.finalize();
PayloadId::new(out.as_slice()[..8].try_into().expect("sufficient length"))
}

/// Generates the payload id for the configured payload from the [PayloadAttributes].
///
/// Returns an 8-byte identifier by hashing the payload components with sha256 hash.
Expand Down
3 changes: 2 additions & 1 deletion crates/rpc/rpc-types/src/eth/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

mod cancun;
mod forkchoice;
mod optimism;
pub mod payload;
mod transition;
pub use self::{cancun::*, forkchoice::*, payload::*, transition::*};
pub use self::{cancun::*, forkchoice::*, optimism::*, payload::*, transition::*};

/// The list of all supported Engine capabilities available over the engine endpoint.
pub const CAPABILITIES: [&str; 12] = [
Expand Down
25 changes: 25 additions & 0 deletions crates/rpc/rpc-types/src/eth/engine/optimism.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::engine::PayloadAttributes;
use alloy_primitives::Bytes;
use serde::{Deserialize, Serialize};

/// Optimism Payload Attributes
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OptimismPayloadAttributes {
/// The payload attributes
#[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")]
pub transactions: Option<Vec<Bytes>>,
/// 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")]
pub no_tx_pool: Option<bool>,
/// If set, this sets the exact gas limit the block produced with.
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "crate::serde_helpers::u64_hex_opt::deserialize"
)]
pub gas_limit: Option<u64>,
}
22 changes: 0 additions & 22 deletions crates/rpc/rpc-types/src/eth/engine/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,28 +625,6 @@ pub struct PayloadAttributes {
pub parent_beacon_block_root: Option<B256>,
}

/// Optimism Payload Attributes
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OptimismPayloadAttributes {
/// The payload attributes
#[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")]
pub transactions: Option<Vec<Bytes>>,
/// 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")]
pub no_tx_pool: Option<bool>,
/// If set, this sets the exact gas limit the block produced with.
#[serde(
skip_serializing_if = "Option::is_none",
deserialize_with = "crate::serde_helpers::u64_hex_opt::deserialize"
)]
pub gas_limit: Option<u64>,
}

/// This structure contains the result of processing a payload or fork choice update.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down

0 comments on commit 43cdd73

Please sign in to comment.