Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -62,3 +62,4 @@ serde-bincode-compat = [
"reth-trie/serde-bincode-compat",
"alloy-eips/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