Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ test-utils = [
"nanoid",
"tokio/full",
"alloy-genesis",
"rand",
"reth-ipc",
"reth-ethereum/test-utils",
"reth-optimism-rpc/client",
Expand Down Expand Up @@ -112,50 +111,48 @@ jsonrpsee = "0.26.0"
parking_lot = "0.12"
metrics = "0.24.0"
priority-queue = "2.0.0"

rand = "0.9"

# Alloy dependencies
alloy-origin = { version = "1.0.37", package = "alloy", features = [
alloy-origin = { version = "1.0.41", package = "alloy", features = [
"k256",
"rpc-types-mev",
] }
alloy-evm = "0.21.2"
alloy-serde = "1.0.37"
alloy-evm = "0.23.0"

# Reth dependencies
reth-origin = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", package = "reth" }
reth-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-rpc-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-ethereum = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", features = [
reth-origin = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", package = "reth" }
reth-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-rpc-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-basic-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ethereum = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", features = [
"node",
"evm",
] }
reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2" }
reth-ipc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3" }
reth-ipc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }

# Reth-optimism dependencies (optional)
op-alloy = { version = "0.20.0", features = ["full"], optional = true }
op-alloy = { version = "0.22.0", features = ["full"], optional = true }
op-alloy-flz = "0.13.1"
reth-optimism-node = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-rpc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-payload-util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.8.2", optional = true }
reth-optimism-node = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-optimism-rpc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-payload-util = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-optimism-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }
reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.9.3", optional = true }

# test-utils
rblib-tests-macros = { path = "src/test_utils/macros", optional = true }
jsonrpsee-core = { version = "0.26.0", optional = true, features = ["client"] }
nanoid = { version = "0.4", optional = true }
alloy-genesis = { version = "1.0", default-features = false, optional = true }
rand = { version = "0.9", optional = true }
ctor = { version = "0.5", optional = true }
tracing-subscriber = { version = "0.3", features = [
"env-filter",
Expand Down
13 changes: 11 additions & 2 deletions src/pipelines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ pub mod traits {
reth::{
api::FullNodeTypes,
evm::ConfigureEvm,
node::builder::NodeTypes,
providers::{ChainSpecProvider, HeaderProvider, StateProviderFactory},
transaction_pool::{PoolTransaction, TransactionPool},
},
Expand Down Expand Up @@ -410,7 +411,11 @@ pub mod traits {

pub trait PlatformExecBounds<P: Platform>:
Platform<
NodeTypes = types::NodeTypes<P>,
NodeTypes: NodeTypes<
ChainSpec = types::ChainSpec<P>,
Primitives = types::Primitives<P>,
Payload = types::PayloadTypes<P>,
>,
EvmConfig = types::EvmConfig<P>,
ExtraLimits = types::ExtraLimits<P>,
>
Expand All @@ -419,7 +424,11 @@ pub mod traits {

impl<T, P: Platform> PlatformExecBounds<T> for P where
T: Platform<
NodeTypes = types::NodeTypes<P>,
NodeTypes: NodeTypes<
ChainSpec = types::ChainSpec<P>,
Primitives = types::Primitives<P>,
Payload = types::PayloadTypes<P>,
>,
EvmConfig = types::EvmConfig<P>,
ExtraLimits = types::ExtraLimits<P>,
>
Expand Down
12 changes: 6 additions & 6 deletions src/platform/ethereum/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ where
.map_err(PayloadBuilderError::other)?;

let mut cumulative_gas_used = 0;
let block_gas_limit: u64 = builder.evm_mut().block().gas_limit;
let base_fee = builder.evm_mut().block().basefee;
let block_gas_limit: u64 = builder.evm_mut().block().gas_limit();
let base_fee = builder.evm_mut().block().basefee();

let mut best_txs = best_txs(BestTransactionsAttributes::new(
base_fee,
Expand Down Expand Up @@ -277,10 +277,10 @@ where
if is_osaka && estimated_block_size_with_tx > MAX_RLP_BLOCK_SIZE {
best_txs.mark_invalid(
&pool_tx,
InvalidPoolTransactionError::OversizedData(
estimated_block_size_with_tx,
MAX_RLP_BLOCK_SIZE,
),
InvalidPoolTransactionError::OversizedData {
size: estimated_block_size_with_tx,
limit: MAX_RLP_BLOCK_SIZE,
},
);
continue;
}
Expand Down
10 changes: 7 additions & 3 deletions src/platform/limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ pub struct Limits<P: Platform> {
impl<P: Platform> Copy for Limits<P> {}

/// This trait must be implemented by extension limits
pub trait LimitExtension:
Copy + Debug + Default + Send + Sync + 'static
{
pub trait LimitExtension: Default + Copy + Debug + Send + Sync {
#[must_use]
fn clamp(&self, other: &Self) -> Self;
}
Expand Down Expand Up @@ -100,6 +98,12 @@ impl<P: Platform> Limits<P> {
self
}

#[must_use]
pub fn with_ext(mut self, ext: P::ExtraLimits) -> Self {
self.ext = ext;
self
}

#[must_use]
pub fn clamp(self, other: &Self) -> Self {
Self {
Expand Down
127 changes: 122 additions & 5 deletions src/platform/optimism/ext.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,63 @@
use {
crate::{alloy, prelude::*, reth},
alloy::eips::Encodable2718,
alloy::{
eips::Encodable2718,
evm::{
op_revm::L1BlockInfo,
revm::database::{State, WrapDatabaseRef},
},
},
op_alloy_flz,
reth::api::NodeTypes,
reth::{api::NodeTypes, optimism::forks::OpHardforks},
};

pub trait BlockOpExt<P: Platform> {
/// Returns `true` if [`Ecotone`] hard fork is active at the given block
/// timestamp.
fn is_ecotone_active(&self) -> bool;

/// Returns `true` if [`Holocene`] hard fork is active at the given block
/// timestamp.
fn is_holocene_active(&self) -> bool;

/// Returns `true` if [`Jovian`] hard fork is active at the given block
/// timestamp.
fn is_jovian_active(&self) -> bool;
}

impl<P: Platform> BlockOpExt<P> for BlockContext<P>
where
P: Platform<
NodeTypes: NodeTypes<
ChainSpec = types::ChainSpec<Optimism>,
Payload = types::PayloadTypes<Optimism>,
>,
>,
{
fn is_ecotone_active(&self) -> bool {
self
.chainspec()
.is_ecotone_active_at_timestamp(self.timestamp())
}

fn is_holocene_active(&self) -> bool {
self
.chainspec()
.is_holocene_active_at_timestamp(self.timestamp())
}

fn is_jovian_active(&self) -> bool {
self
.chainspec()
.is_jovian_active_at_timestamp(self.timestamp())
}
}

pub trait ExecutionResultOpExt<P: Platform> {
/// Data availability bytes used by this execution.
/// Returns the data availability bytes used by this execution.
/// (`daUsageEstimate`) Only non-deposit transactions are counted towards da
/// bytes usage.
/// Deposit transactions are not counted.
fn da_bytes_used(&self) -> u64;
}

Expand All @@ -25,6 +76,7 @@ where
.source
.transactions()
.iter()
.filter(|tx| !tx.is_deposit())
.map(|tx| {
op_alloy_flz::tx_estimated_size_fjord_bytes(
tx.encoded_2718().as_slice(),
Expand All @@ -35,9 +87,13 @@ where
}

pub trait SpanOpExt<P: Platform> {
/// Returns the total data availability bytes used by all checkpoints in this
/// span
/// Returns the cumulative data availability bytes used by all checkpoints in
/// this span
fn da_bytes_used(&self) -> u64;

/// Returns the cumulative data availability footprint used by all checkpoints
/// in this span
fn da_footprint(&self) -> u64;
}

impl<P: Platform> SpanOpExt<P> for Span<P>
Expand All @@ -53,6 +109,10 @@ where
fn da_bytes_used(&self) -> u64 {
self.iter().map(CheckpointOpExt::da_bytes_used).sum()
}

fn da_footprint(&self) -> u64 {
self.iter().filter_map(CheckpointOpExt::da_footprint).sum()
}
}

pub trait CheckpointOpExt<P: Platform> {
Expand All @@ -62,6 +122,27 @@ pub trait CheckpointOpExt<P: Platform> {
/// Returns the cumulative data availability bytes used by all checkpoints in
/// the history of this checkpoint, including this checkpoint itself.
fn cumulative_da_bytes_used(&self) -> u64;

/// Returns the data availability footprint gas scalar (L1 Block Attribute)
fn da_footprint_gas_scalar(&self) -> Option<u16>;

/// Returns the data availability footprint
fn da_footprint(&self) -> Option<u64> {
self
.da_footprint_gas_scalar()
.map(|scalar| self.da_bytes_used() * u64::from(scalar))
}

/// Returns the cumulative data availability footprint used by all checkpoints
/// in the history of this checkpoint, including this checkpoint itself.
fn cumulative_da_footprint(&self) -> Option<u64>;

/// Returns the blob fields for the header.
///
/// After jovian: this will return `da_footprint`.
/// After Ecotone: this will always return Some(0) (blobs aren't supported)
/// Pre-Ecotone: these fields aren't used.
fn blob_fields(&self) -> (Option<u64>, Option<u64>);
}

impl<P: Platform> CheckpointOpExt<P> for Checkpoint<P>
Expand All @@ -81,4 +162,40 @@ where
fn cumulative_da_bytes_used(&self) -> u64 {
self.history().da_bytes_used()
}

fn da_footprint_gas_scalar(&self) -> Option<u16> {
self.block().is_jovian_active().then(|| {
let mut state = State::builder()
.with_database(WrapDatabaseRef(self))
.build();
// fetch from storage. It could be memoized as it's set once at the start
// of the block
L1BlockInfo::fetch_da_footprint_gas_scalar(&mut state).ok()
})?
}

fn cumulative_da_footprint(&self) -> Option<u64> {
self
.block()
.is_jovian_active()
.then(|| self.history().da_footprint())
}

fn blob_fields(&self) -> (Option<u64>, Option<u64>) {
// Jovian
if self.block().is_jovian_active() {
let footprint = self
.cumulative_da_footprint()
.expect("Jovian but no da footprint");
(Some(0), Some(footprint))
}
// Ecotone
else if self.block().is_ecotone_active() {
(Some(0), Some(0))
}
// Pre-Ecotone
else {
(None, None)
}
}
}
Loading
Loading