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
2 changes: 1 addition & 1 deletion crates/optimism/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ reth-optimism-payload-builder.workspace = true
reth-optimism-primitives.workspace = true
reth-optimism-forks.workspace = true
reth-optimism-exex.workspace = true
reth-optimism-trie.workspace = true
reth-optimism-trie = { workspace = true, features = ["metrics"] }
reth-node-builder.workspace = true
reth-db-api.workspace = true
reth-chainspec.workspace = true
Expand Down
26 changes: 19 additions & 7 deletions crates/optimism/bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli};
use reth_optimism_exex::OpProofsExEx;
use reth_optimism_node::{args::RollupArgs, OpNode};
use reth_optimism_rpc::eth::proofs::{EthApiExt, EthApiOverrideServer};
use reth_optimism_trie::{db::MdbxProofsStorage, InMemoryProofsStorage, OpProofsStorage};
use reth_optimism_trie::{
db::MdbxProofsStorage, InMemoryProofsStorage, OpProofsStorage, OpProofsStore, StorageMetrics,
};
use tracing::info;

use std::{path::PathBuf, sync::Arc};
Expand Down Expand Up @@ -68,10 +70,10 @@ struct Args {
async fn launch_node_with_storage<S>(
builder: WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, OpChainSpec>>,
args: Args,
storage: S,
storage: OpProofsStorage<S>,
) -> eyre::Result<(), ErrReport>
where
S: OpProofsStorage + Clone + 'static,
S: OpProofsStore + Clone + 'static,
{
let storage_clone = storage.clone();
let proofs_history_enabled = args.proofs_history;
Expand Down Expand Up @@ -106,7 +108,12 @@ fn main() {
info!(target: "reth::cli", "Launching node");

if args.proofs_history_storage_in_mem {
let storage = Arc::new(InMemoryProofsStorage::new());
// todo: enable launch without metrics
let storage = OpProofsStorage::new(
Arc::new(InMemoryProofsStorage::new()),
Arc::new(StorageMetrics::default()),
);

launch_node_with_storage(builder, args.clone(), storage).await?;
} else {
let path = args
Expand All @@ -115,10 +122,15 @@ fn main() {
.expect("Path must be provided if not using in-memory storage");
info!(target: "reth::cli", "Using on-disk storage for proofs history");

let storage = Arc::new(
MdbxProofsStorage::new(&path)
.map_err(|e| eyre::eyre!("Failed to create MdbxProofsStorage: {e}"))?,
// todo: enable launch without metrics
let storage = OpProofsStorage::new(
Arc::new(
MdbxProofsStorage::new(&path)
.map_err(|e| eyre::eyre!("Failed to create MdbxProofsStorage: {e}"))?,
),
Arc::new(StorageMetrics::default()),
);

launch_node_with_storage(builder, args.clone(), storage).await?;
}

Expand Down
6 changes: 3 additions & 3 deletions crates/optimism/exex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use reth_chainspec::ChainInfo;
use reth_exex::{ExExContext, ExExEvent};
use reth_node_api::{FullNodeComponents, NodePrimitives};
use reth_node_types::NodeTypes;
use reth_optimism_trie::{BackfillJob, OpProofsStorage};
use reth_optimism_trie::{BackfillJob, OpProofsStore};
use reth_provider::{BlockNumReader, DBProvider, DatabaseProviderFactory};

/// OP Proofs ExEx - processes blocks and tracks state changes within fault proof window.
Expand All @@ -26,7 +26,7 @@ use reth_provider::{BlockNumReader, DBProvider, DatabaseProviderFactory};
pub struct OpProofsExEx<Node, S>
where
Node: FullNodeComponents,
S: OpProofsStorage + Clone,
S: OpProofsStore + Clone,
{
/// The ExEx context containing the node related utilities e.g. provider, notifications,
/// events.
Expand All @@ -43,7 +43,7 @@ impl<Node, S, Primitives> OpProofsExEx<Node, S>
where
Node: FullNodeComponents<Types: NodeTypes<Primitives = Primitives>>,
Primitives: NodePrimitives,
S: OpProofsStorage + Clone,
S: OpProofsStore + Clone,
{
/// Main execution loop for the ExEx
pub async fn run(mut self) -> eyre::Result<()> {
Expand Down
8 changes: 4 additions & 4 deletions crates/optimism/rpc/src/eth/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use derive_more::Constructor;
use jsonrpsee::proc_macros::rpc;
use jsonrpsee_core::RpcResult;
use jsonrpsee_types::error::ErrorObject;
use reth_optimism_trie::{provider::OpProofsStateProviderRef, OpProofsStorage};
use reth_optimism_trie::{provider::OpProofsStateProviderRef, OpProofsStorage, OpProofsStore};
use reth_provider::{BlockIdReader, ProviderError, ProviderResult, StateProofProvider};
use reth_rpc_api::eth::helpers::FullEthApi;
use reth_rpc_eth_types::EthApiError;
Expand All @@ -32,14 +32,14 @@ pub trait EthApiOverride {
/// Overrides applied to the `eth_` namespace of the RPC API for historical proofs ExEx.
pub struct EthApiExt<Eth, P> {
eth_api: Eth,
preimage_store: P,
preimage_store: OpProofsStorage<P>,
}

impl<Eth, P> EthApiExt<Eth, P>
where
Eth: FullEthApi + Send + Sync + 'static,
ErrorObject<'static>: From<Eth::Error>,
P: OpProofsStorage + Clone + 'static,
P: OpProofsStore + Clone + 'static,
{
async fn state_provider(
&self,
Expand Down Expand Up @@ -87,7 +87,7 @@ impl<Eth, P> EthApiOverrideServer for EthApiExt<Eth, P>
where
Eth: FullEthApi + Send + Sync + 'static,
ErrorObject<'static>: From<Eth::Error>,
P: OpProofsStorage + Clone + 'static,
P: OpProofsStore + Clone + 'static,
{
async fn get_proof(
&self,
Expand Down
1 change: 1 addition & 0 deletions crates/optimism/trie/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ serde-bincode-compat = [
"alloy-genesis/serde-bincode-compat",
"reth-ethereum-primitives/serde-bincode-compat",
]
metrics = ["reth-trie/metrics"]
23 changes: 14 additions & 9 deletions crates/optimism/trie/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,22 @@ pub enum OpProofsStorageError {
/// Error occurred while interacting with the database.
#[error(transparent)]
DatabaseError(#[from] DatabaseError),

/// Other error
#[error("Other error: {0}")]
Other(eyre::Error),
}

impl From<OpProofsStorageError> for DatabaseError {
fn from(error: OpProofsStorageError) -> Self {
Self::Other(error.to_string())
}
}

/// Result type for storage operations
pub type OpProofsStorageResult<T> = Result<T, OpProofsStorageError>;

/// Seeks and iterates over trie nodes in the database by path (lexicographical order)
pub trait OpProofsTrieCursor: Send + Sync {
pub trait OpProofsTrieCursorRO: Send + Sync {
/// Seek to an exact path, otherwise return None if not found.
fn seek_exact(
&mut self,
Expand All @@ -58,7 +63,7 @@ pub trait OpProofsTrieCursor: Send + Sync {
}

/// Seeks and iterates over hashed entries in the database by key.
pub trait OpProofsHashedCursor: Send + Sync {
pub trait OpProofsHashedCursorRO: Send + Sync {
/// Value returned by the cursor.
type Value: Debug;

Expand Down Expand Up @@ -89,29 +94,29 @@ pub struct BlockStateDiff {
/// Only leaf nodes and some branch nodes are stored. The bottom layer of branch nodes
/// are not stored to reduce write amplification. This matches Reth's non-historical trie storage.
#[auto_impl(Arc)]
pub trait OpProofsStorage: Send + Sync + Debug {
pub trait OpProofsStore: Send + Sync + Debug {
/// Cursor for iterating over trie branches.
type StorageTrieCursor<'tx>: OpProofsTrieCursor + 'tx
type StorageTrieCursor<'tx>: OpProofsTrieCursorRO + 'tx
where
Self: 'tx;

/// Cursor for iterating over account trie branches.
type AccountTrieCursor<'tx>: OpProofsTrieCursor + 'tx
type AccountTrieCursor<'tx>: OpProofsTrieCursorRO + 'tx
where
Self: 'tx;

/// Cursor for iterating over storage leaves.
type StorageCursor<'tx>: OpProofsHashedCursor<Value = U256> + 'tx
type StorageCursor<'tx>: OpProofsHashedCursorRO<Value = U256> + 'tx
where
Self: 'tx;

/// Cursor for iterating over account leaves.
type AccountHashedCursor<'tx>: OpProofsHashedCursor<Value = Account> + 'tx
type AccountHashedCursor<'tx>: OpProofsHashedCursorRO<Value = Account> + 'tx
where
Self: 'tx;

/// Store a batch of account trie branches. Used for saving existing state. For live state
/// capture, use [store_trie_updates](OpProofsStorage::store_trie_updates).
/// capture, use [store_trie_updates](OpProofsStore::store_trie_updates).
fn store_account_branches(
&self,
account_nodes: Vec<(Nibbles, Option<BranchNodeCompact>)>,
Expand Down
8 changes: 4 additions & 4 deletions crates/optimism/trie/src/backfill.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Backfill job for proofs storage. Handles storing the existing state into the proofs storage.

use crate::OpProofsStorage;
use crate::OpProofsStore;
use alloy_primitives::B256;
use reth_db::{
cursor::{DbCursorRO, DbDupCursorRO},
Expand All @@ -21,7 +21,7 @@ const BACKFILL_LOG_THRESHOLD: usize = 100000;

/// Backfill job for external storage.
#[derive(Debug)]
pub struct BackfillJob<'a, Tx: DbTx, S: OpProofsStorage + Send> {
pub struct BackfillJob<'a, Tx: DbTx, S: OpProofsStore + Send> {
storage: S,
tx: &'a Tx,
}
Expand Down Expand Up @@ -196,7 +196,7 @@ async fn backfill<
Ok(total_entries)
}

impl<'a, Tx: DbTx, S: OpProofsStorage + Send> BackfillJob<'a, Tx, S> {
impl<'a, Tx: DbTx, S: OpProofsStore + Send> BackfillJob<'a, Tx, S> {
/// Create a new backfill job.
pub const fn new(storage: S, tx: &'a Tx) -> Self {
Self { storage, tx }
Expand Down Expand Up @@ -348,7 +348,7 @@ impl<'a, Tx: DbTx, S: OpProofsStorage + Send> BackfillJob<'a, Tx, S> {
#[cfg(test)]
mod tests {
use super::*;
use crate::{InMemoryProofsStorage, OpProofsHashedCursor, OpProofsTrieCursor};
use crate::{InMemoryProofsStorage, OpProofsHashedCursorRO, OpProofsTrieCursorRO};
use alloy_primitives::{keccak256, Address, U256};
use reth_db::{
cursor::DbCursorRW, test_utils::create_test_rw_db, transaction::DbTxMut, Database,
Expand Down
100 changes: 100 additions & 0 deletions crates/optimism/trie/src/cursor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//! Implementation of [`HashedCursor`] and [`TrieCursor`] for
//! [`OpProofsStorage`](crate::OpProofsStorage).

use crate::{OpProofsHashedCursorRO, OpProofsTrieCursorRO};
use alloy_primitives::{B256, U256};
use derive_more::{Constructor, From};
use reth_db::DatabaseError;
use reth_primitives_traits::Account;
use reth_trie::{
hashed_cursor::{HashedCursor, HashedStorageCursor},
trie_cursor::TrieCursor,
BranchNodeCompact, Nibbles,
};

/// Manages reading storage or account trie nodes from [`OpProofsTrieCursor`].
#[derive(Debug, Clone, Constructor, From)]
pub struct OpProofsTrieCursor<C: OpProofsTrieCursorRO>(pub C);

impl<C> TrieCursor for OpProofsTrieCursor<C>
where
C: OpProofsTrieCursorRO,
{
#[inline]
fn seek_exact(
&mut self,
key: Nibbles,
) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek_exact(key)?)
}

#[inline]
fn seek(
&mut self,
key: Nibbles,
) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.seek(key)?)
}

#[inline]
fn next(&mut self) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
Ok(self.0.next()?)
}

#[inline]
fn current(&mut self) -> Result<Option<Nibbles>, DatabaseError> {
Ok(self.0.current()?)
}
}

/// Manages reading hashed account nodes from external storage.
#[derive(Debug, Clone, Constructor)]
pub struct OpProofsHashedAccountCursor<C>(pub C);

impl<C> HashedCursor for OpProofsHashedAccountCursor<C>
where
C: OpProofsHashedCursorRO<Value = Account> + Send + Sync,
{
type Value = Account;

#[inline]
fn seek(&mut self, key: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
Ok(self.0.seek(key)?)
}

#[inline]
fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
Ok(self.0.next()?)
}
}

/// Manages reading hashed storage nodes from external storage.
#[derive(Debug, Clone, Constructor)]
pub struct OpProofsHashedStorageCursor<C>(pub C);

impl<C> HashedCursor for OpProofsHashedStorageCursor<C>
where
C: OpProofsHashedCursorRO<Value = U256> + Send + Sync,
{
type Value = U256;

#[inline]
fn seek(&mut self, key: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
Ok(self.0.seek(key)?)
}

#[inline]
fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> {
Ok(self.0.next()?)
}
}

impl<C> HashedStorageCursor for OpProofsHashedStorageCursor<C>
where
C: OpProofsHashedCursorRO<Value = U256> + Send + Sync,
{
#[inline]
fn is_storage_empty(&mut self) -> Result<bool, DatabaseError> {
Ok(self.0.is_storage_empty()?)
}
}
Loading
Loading