Skip to content
12 changes: 5 additions & 7 deletions Cargo.lock

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

7 changes: 0 additions & 7 deletions crates/optimism/bin/op-reth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,12 @@ reth-optimism-evm.workspace = true
reth-optimism-payload-builder.workspace = true
reth-optimism-primitives.workspace = true
reth-optimism-forks.workspace = true
reth-optimism-exex = { workspace = true, features = ["metrics"] }
reth-optimism-trie = { workspace = true, features = ["metrics"] }
reth-node-builder.workspace = true
reth-db-api.workspace = true
reth-chainspec.workspace = true
reth-db.workspace = true
reth-tasks.workspace = true

clap = { workspace = true, features = ["derive", "env"] }
tracing.workspace = true
eyre.workspace = true
futures-util.workspace = true
tokio.workspace = true

[lints]
workspace = true
Expand Down
96 changes: 4 additions & 92 deletions crates/optimism/bin/op-reth/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,12 @@

use clap::Parser;
use eyre::ErrReport;
use futures_util::FutureExt;
use reth_db::DatabaseEnv;
use reth_db_api::database_metrics::DatabaseMetrics;
use reth_node_builder::{FullNodeComponents, NodeBuilder, WithLaunchContext};
use reth_node_builder::{NodeBuilder, WithLaunchContext};
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli};
use reth_optimism_exex::OpProofsExEx;
use reth_optimism_node::{args::RollupArgs, OpNode};
use reth_optimism_rpc::{
debug::{DebugApiExt, DebugApiOverrideServer},
eth::proofs::{EthApiExt, EthApiOverrideServer},
};
use reth_optimism_trie::{db::MdbxProofsStorage, OpProofsStorage};
use reth_tasks::TaskExecutor;
use std::{sync::Arc, time::Duration};
use tokio::time::sleep;
use reth_optimism_node::{args::RollupArgs, proof_history};
use std::sync::Arc;
use tracing::info;

#[global_allocator]
Expand All @@ -35,85 +25,7 @@ async fn launch_node(
builder: WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, OpChainSpec>>,
args: RollupArgs,
) -> eyre::Result<(), ErrReport> {
let proofs_history_enabled = args.proofs_history;
let proofs_history_window = args.proofs_history_window;
let proofs_history_prune_interval = args.proofs_history_prune_interval;
let proofs_history_verification_interval = args.proofs_history_verification_interval;

// Start from a plain OpNode builder
let mut node_builder = builder.node(OpNode::new(args.clone()));

if proofs_history_enabled {
let path = args
.proofs_history_storage_path
.clone()
.expect("Path must be provided if not using in-memory storage");
info!(target: "reth::cli", "Using on-disk storage for proofs history");

let mdbx = Arc::new(
MdbxProofsStorage::new(&path)
.map_err(|e| eyre::eyre!("Failed to create MdbxProofsStorage: {e}"))?,
);
let storage: OpProofsStorage<_> = mdbx.clone().into();

let storage_exec = storage.clone();

node_builder = node_builder
.on_node_started(move |node| {
spawn_proofs_db_metrics(
node.task_executor,
mdbx,
node.config.metrics.push_gateway_interval,
);
Ok(())
})
.install_exex("proofs-history", async move |exex_context| {
Ok(OpProofsExEx::builder(exex_context, storage_exec)
.with_proofs_history_window(proofs_history_window)
.with_proofs_history_prune_interval(proofs_history_prune_interval)
.with_verification_interval(proofs_history_verification_interval)
.build()
.run()
.boxed())
})
.extend_rpc_modules(move |ctx| {
let api_ext = EthApiExt::new(ctx.registry.eth_api().clone(), storage.clone());
let debug_ext = DebugApiExt::new(
ctx.node().provider().clone(),
ctx.registry.eth_api().clone(),
storage,
Box::new(ctx.node().task_executor().clone()),
ctx.node().evm_config().clone(),
);
ctx.modules.replace_configured(api_ext.into_rpc())?;
ctx.modules.replace_configured(debug_ext.into_rpc())?;
Ok(())
});
}

// In all cases (with or without proofs), launch the node.
let handle = node_builder.launch_with_debug_capabilities().await?;
handle.node_exit_future.await
}

/// Spawns a task that periodically reports metrics for the proofs DB.
fn spawn_proofs_db_metrics(
executor: TaskExecutor,
storage: Arc<MdbxProofsStorage>,
metrics_report_interval: Duration,
) {
executor.spawn_critical("op-proofs-storage-metrics", async move {
info!(
target: "reth::cli",
?metrics_report_interval,
"Starting op-proofs-storage metrics task"
);

loop {
sleep(metrics_report_interval).await;
storage.report_metrics();
}
});
proof_history::launch_node_with_proof_history(builder, args).await
}

fn main() {
Expand Down
12 changes: 9 additions & 3 deletions crates/optimism/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ reth-transaction-pool.workspace = true
reth-network.workspace = true
reth-evm.workspace = true
reth-rpc-server-types.workspace = true
reth-tasks = { workspace = true, optional = true }
reth-tasks.workspace = true
reth-trie-common.workspace = true
reth-node-core.workspace = true
reth-rpc-engine-api.workspace = true
reth-engine-local = { workspace = true, features = ["op"] }
reth-rpc-api.workspace = true
reth-db = { workspace = true, features = ["op"] }
reth-db-api = { workspace = true, features = ["op"] }

# op-reth
reth-optimism-payload-builder.workspace = true
Expand All @@ -42,6 +44,8 @@ reth-optimism-chainspec.workspace = true
reth-optimism-consensus = { workspace = true, features = ["std"] }
reth-optimism-forks.workspace = true
reth-optimism-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] }
reth-optimism-exex = { workspace = true, features = ["metrics"] }
reth-optimism-trie = { workspace = true, features = ["metrics"] }

# revm with required optimism features
# Note: this must be kept to ensure all features are properly enabled/forwarded
Expand All @@ -65,6 +69,8 @@ serde.workspace = true
eyre.workspace = true
url.workspace = true
humantime.workspace = true
futures-util.workspace = true
tracing.workspace = true

# test-utils dependencies
reth-e2e-test-utils = { workspace = true, optional = true }
Expand All @@ -76,7 +82,6 @@ reth-optimism-node = { workspace = true, features = ["test-utils"] }
reth-db = { workspace = true, features = ["op", "test-utils"] }
reth-node-builder = { workspace = true, features = ["test-utils"] }
reth-provider = { workspace = true, features = ["test-utils"] }
reth-tasks.workspace = true
reth-payload-util.workspace = true
reth-revm = { workspace = true, features = ["std"] }
reth-rpc.workspace = true
Expand Down Expand Up @@ -109,7 +114,6 @@ js-tracer = [
"reth-rpc-eth-types/js-tracer",
]
test-utils = [
"reth-tasks",
"reth-e2e-test-utils",
"alloy-genesis",
"serde_json",
Expand All @@ -129,6 +133,8 @@ test-utils = [
"reth-trie-common/test-utils",
"reth-trie-db/test-utils",
"reth-stages-types/test-utils",
"reth-db-api/test-utils",
"reth-optimism-exex/test-utils",
]
reth-codec = ["reth-optimism-primitives/reth-codec"]

Expand Down
2 changes: 2 additions & 0 deletions crates/optimism/node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ pub use version::OP_NAME_CLIENT;

pub use reth_optimism_txpool as txpool;

pub mod proof_history;

/// Helpers for running test node instances.
#[cfg(feature = "test-utils")]
pub mod utils;
Expand Down
109 changes: 109 additions & 0 deletions crates/optimism/node/src/proof_history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//! Node luncher with proof history support.

use crate::{args::RollupArgs, OpNode};
use eyre::ErrReport;
use futures_util::FutureExt;
use reth_db::DatabaseEnv;
use reth_db_api::database_metrics::DatabaseMetrics;
use reth_node_builder::{FullNodeComponents, NodeBuilder, WithLaunchContext};
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_exex::OpProofsExEx;
use reth_optimism_rpc::{
debug::{DebugApiExt, DebugApiOverrideServer},
eth::proofs::{EthApiExt, EthApiOverrideServer},
};
use reth_optimism_trie::{db::MdbxProofsStorage, OpProofsStorage};
use reth_tasks::TaskExecutor;
use std::{sync::Arc, time::Duration};
use tokio::time::sleep;
use tracing::info;

/// - no proofs history (plain node),
/// - in-mem proofs storage,
/// - MDBX proofs storage.
pub async fn launch_node_with_proof_history(
builder: WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, OpChainSpec>>,
args: RollupArgs,
) -> eyre::Result<(), ErrReport> {
let RollupArgs {
proofs_history,
proofs_history_window,
proofs_history_prune_interval,
proofs_history_verification_interval,
..
} = args;

// Start from a plain OpNode builder
let mut node_builder = builder.node(OpNode::new(args.clone()));

if proofs_history {
let path = args
.proofs_history_storage_path
.clone()
.expect("Path must be provided if not using in-memory storage");
info!(target: "reth::cli", "Using on-disk storage for proofs history");

let mdbx = Arc::new(
MdbxProofsStorage::new(&path)
.map_err(|e| eyre::eyre!("Failed to create MdbxProofsStorage: {e}"))?,
);
let storage: OpProofsStorage<Arc<MdbxProofsStorage>> = mdbx.clone().into();

let storage_exec = storage.clone();

node_builder = node_builder
.on_node_started(move |node| {
spawn_proofs_db_metrics(
node.task_executor,
mdbx,
node.config.metrics.push_gateway_interval,
);
Ok(())
})
.install_exex("proofs-history", async move |exex_context| {
Ok(OpProofsExEx::builder(exex_context, storage_exec)
.with_proofs_history_window(proofs_history_window)
.with_proofs_history_prune_interval(proofs_history_prune_interval)
.with_verification_interval(proofs_history_verification_interval)
.build()
.run()
.boxed())
})
.extend_rpc_modules(move |ctx| {
let api_ext = EthApiExt::new(ctx.registry.eth_api().clone(), storage.clone());
let debug_ext = DebugApiExt::new(
ctx.node().provider().clone(),
ctx.registry.eth_api().clone(),
storage,
Box::new(ctx.node().task_executor().clone()),
ctx.node().evm_config().clone(),
);
ctx.modules.replace_configured(api_ext.into_rpc())?;
ctx.modules.replace_configured(debug_ext.into_rpc())?;
Ok(())
});
}

// In all cases (with or without proofs), launch the node.
let handle = node_builder.launch_with_debug_capabilities().await?;
handle.node_exit_future.await
}
/// Spawns a task that periodically reports metrics for the proofs DB.
fn spawn_proofs_db_metrics(
executor: TaskExecutor,
storage: Arc<MdbxProofsStorage>,
metrics_report_interval: Duration,
) {
executor.spawn_critical("op-proofs-storage-metrics", async move {
info!(
target: "reth::cli",
?metrics_report_interval,
"Starting op-proofs-storage metrics task"
);

loop {
sleep(metrics_report_interval).await;
storage.report_metrics();
}
});
}
Loading