mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
feat(trie): in-memory trie changesets (#20997)
This commit is contained in:
@@ -54,6 +54,7 @@ reth-tasks.workspace = true
|
||||
reth-tokio-util.workspace = true
|
||||
reth-tracing.workspace = true
|
||||
reth-transaction-pool.workspace = true
|
||||
reth-trie-db = { workspace = true, features = ["metrics"] }
|
||||
reth-basic-payload-builder.workspace = true
|
||||
reth-node-ethstats.workspace = true
|
||||
|
||||
@@ -115,6 +116,7 @@ test-utils = [
|
||||
"reth-db-api/test-utils",
|
||||
"reth-provider/test-utils",
|
||||
"reth-transaction-pool/test-utils",
|
||||
"reth-trie-db/test-utils",
|
||||
"reth-evm-ethereum/test-utils",
|
||||
"reth-node-ethereum/test-utils",
|
||||
"reth-primitives-traits/test-utils",
|
||||
|
||||
@@ -84,6 +84,7 @@ use reth_tracing::{
|
||||
tracing::{debug, error, info, warn},
|
||||
};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use reth_trie_db::ChangesetCache;
|
||||
use std::{sync::Arc, thread::available_parallelism, time::Duration};
|
||||
use tokio::sync::{
|
||||
mpsc::{unbounded_channel, UnboundedSender},
|
||||
@@ -470,7 +471,10 @@ where
|
||||
/// Returns the [`ProviderFactory`] for the attached storage after executing a consistent check
|
||||
/// between the database and static files. **It may execute a pipeline unwind if it fails this
|
||||
/// check.**
|
||||
pub async fn create_provider_factory<N, Evm>(&self) -> eyre::Result<ProviderFactory<N>>
|
||||
pub async fn create_provider_factory<N, Evm>(
|
||||
&self,
|
||||
changeset_cache: ChangesetCache,
|
||||
) -> eyre::Result<ProviderFactory<N>>
|
||||
where
|
||||
N: ProviderNodeTypes<DB = DB, ChainSpec = ChainSpec>,
|
||||
Evm: ConfigureEvm<Primitives = N::Primitives> + 'static,
|
||||
@@ -500,7 +504,8 @@ where
|
||||
static_file_provider,
|
||||
rocksdb_provider,
|
||||
)?
|
||||
.with_prune_modes(self.prune_modes());
|
||||
.with_prune_modes(self.prune_modes())
|
||||
.with_changeset_cache(changeset_cache);
|
||||
|
||||
// Keep MDBX, static files, and RocksDB aligned. If any check fails, unwind to the
|
||||
// earliest consistent block.
|
||||
@@ -593,12 +598,13 @@ where
|
||||
/// Creates a new [`ProviderFactory`] and attaches it to the launch context.
|
||||
pub async fn with_provider_factory<N, Evm>(
|
||||
self,
|
||||
changeset_cache: ChangesetCache,
|
||||
) -> eyre::Result<LaunchContextWith<Attached<WithConfigs<ChainSpec>, ProviderFactory<N>>>>
|
||||
where
|
||||
N: ProviderNodeTypes<DB = DB, ChainSpec = ChainSpec>,
|
||||
Evm: ConfigureEvm<Primitives = N::Primitives> + 'static,
|
||||
{
|
||||
let factory = self.create_provider_factory::<N, Evm>().await?;
|
||||
let factory = self.create_provider_factory::<N, Evm>(changeset_cache).await?;
|
||||
let ctx = LaunchContextWith {
|
||||
inner: self.inner,
|
||||
attachment: self.attachment.map_right(|_| factory),
|
||||
|
||||
@@ -37,6 +37,7 @@ use reth_provider::{
|
||||
use reth_tasks::TaskExecutor;
|
||||
use reth_tokio_util::EventSender;
|
||||
use reth_tracing::tracing::{debug, error, info};
|
||||
use reth_trie_db::ChangesetCache;
|
||||
use std::{future::Future, pin::Pin, sync::Arc};
|
||||
use tokio::sync::{mpsc::unbounded_channel, oneshot};
|
||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||
@@ -87,6 +88,9 @@ impl EngineNodeLauncher {
|
||||
} = target;
|
||||
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;
|
||||
|
||||
// Create changeset cache that will be shared across the engine
|
||||
let changeset_cache = ChangesetCache::new();
|
||||
|
||||
// setup the launch context
|
||||
let ctx = ctx
|
||||
.with_configured_globals(engine_tree_config.reserved_cpu_cores())
|
||||
@@ -98,8 +102,8 @@ impl EngineNodeLauncher {
|
||||
.attach(database.clone())
|
||||
// ensure certain settings take effect
|
||||
.with_adjusted_configs()
|
||||
// Create the provider factory
|
||||
.with_provider_factory::<_, <CB::Components as NodeComponents<T>>::Evm>().await?
|
||||
// Create the provider factory with changeset cache
|
||||
.with_provider_factory::<_, <CB::Components as NodeComponents<T>>::Evm>(changeset_cache.clone()).await?
|
||||
.inspect(|ctx| {
|
||||
info!(target: "reth::cli", "Database opened");
|
||||
match ctx.provider_factory().storage_settings() {
|
||||
@@ -204,7 +208,7 @@ impl EngineNodeLauncher {
|
||||
// Build the engine validator with all required components
|
||||
let engine_validator = validator_builder
|
||||
.clone()
|
||||
.build_tree_validator(&add_ons_ctx, engine_tree_config.clone())
|
||||
.build_tree_validator(&add_ons_ctx, engine_tree_config.clone(), changeset_cache.clone())
|
||||
.await?;
|
||||
|
||||
// Create the consensus engine stream with optional reorg
|
||||
@@ -214,7 +218,13 @@ impl EngineNodeLauncher {
|
||||
.maybe_reorg(
|
||||
ctx.blockchain_db().clone(),
|
||||
ctx.components().evm_config().clone(),
|
||||
|| validator_builder.build_tree_validator(&add_ons_ctx, engine_tree_config.clone()),
|
||||
|| async {
|
||||
// Create a separate cache for reorg validator (not shared with main engine)
|
||||
let reorg_cache = ChangesetCache::new();
|
||||
validator_builder
|
||||
.build_tree_validator(&add_ons_ctx, engine_tree_config.clone(), reorg_cache)
|
||||
.await
|
||||
},
|
||||
node_config.debug.reorg_frequency,
|
||||
node_config.debug.reorg_depth,
|
||||
)
|
||||
@@ -239,6 +249,7 @@ impl EngineNodeLauncher {
|
||||
engine_tree_config,
|
||||
ctx.sync_metrics_tx(),
|
||||
ctx.components().evm_config().clone(),
|
||||
changeset_cache,
|
||||
);
|
||||
|
||||
info!(target: "reth::cli", "Consensus engine initialized");
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
pub use jsonrpsee::server::middleware::rpc::{RpcService, RpcServiceBuilder};
|
||||
pub use reth_engine_tree::tree::{BasicEngineValidator, EngineValidator};
|
||||
pub use reth_rpc_builder::{middleware::RethRpcMiddleware, Identity, Stack};
|
||||
pub use reth_trie_db::ChangesetCache;
|
||||
|
||||
use crate::{
|
||||
invalid_block_hook::InvalidBlockHookExt, ConfigureEngineEvm, ConsensusEngineEvent,
|
||||
@@ -1288,6 +1289,7 @@ pub trait EngineValidatorBuilder<Node: FullNodeComponents>: Send + Sync + Clone
|
||||
self,
|
||||
ctx: &AddOnsContext<'_, Node>,
|
||||
tree_config: TreeConfig,
|
||||
changeset_cache: ChangesetCache,
|
||||
) -> impl Future<Output = eyre::Result<Self::EngineValidator>> + Send;
|
||||
}
|
||||
|
||||
@@ -1335,10 +1337,12 @@ where
|
||||
self,
|
||||
ctx: &AddOnsContext<'_, Node>,
|
||||
tree_config: TreeConfig,
|
||||
changeset_cache: ChangesetCache,
|
||||
) -> eyre::Result<Self::EngineValidator> {
|
||||
let validator = self.payload_validator_builder.build(ctx).await?;
|
||||
let data_dir = ctx.config.datadir.clone().resolve_datadir(ctx.config.chain.chain());
|
||||
let invalid_block_hook = ctx.create_invalid_block_hook(&data_dir).await?;
|
||||
|
||||
Ok(BasicEngineValidator::new(
|
||||
ctx.node.provider().clone(),
|
||||
std::sync::Arc::new(ctx.node.consensus().clone()),
|
||||
@@ -1346,6 +1350,7 @@ where
|
||||
validator,
|
||||
tree_config,
|
||||
invalid_block_hook,
|
||||
changeset_cache,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@ use alloy_primitives::{Address, BlockNumber};
|
||||
use clap::{builder::RangedU64ValueParser, Args};
|
||||
use reth_chainspec::EthereumHardforks;
|
||||
use reth_config::config::PruneConfig;
|
||||
use reth_prune_types::{
|
||||
PruneMode, PruneModes, ReceiptsLogPruneConfig, MERKLE_CHANGESETS_RETENTION_BLOCKS,
|
||||
MINIMUM_PRUNING_DISTANCE,
|
||||
};
|
||||
use reth_prune_types::{PruneMode, PruneModes, ReceiptsLogPruneConfig, MINIMUM_PRUNING_DISTANCE};
|
||||
use std::{collections::BTreeMap, ops::Not};
|
||||
|
||||
/// Parameters for pruning and full node
|
||||
@@ -143,7 +140,6 @@ impl PruningArgs {
|
||||
.ethereum_fork_activation(EthereumHardfork::Paris)
|
||||
.block_number()
|
||||
.map(PruneMode::Before),
|
||||
merkle_changesets: PruneMode::Distance(MERKLE_CHANGESETS_RETENTION_BLOCKS),
|
||||
receipts_log_filter: Default::default(),
|
||||
},
|
||||
}
|
||||
@@ -160,7 +156,6 @@ impl PruningArgs {
|
||||
account_history: Some(PruneMode::Distance(10064)),
|
||||
storage_history: Some(PruneMode::Distance(10064)),
|
||||
bodies_history: Some(PruneMode::Distance(10064)),
|
||||
merkle_changesets: PruneMode::Distance(MERKLE_CHANGESETS_RETENTION_BLOCKS),
|
||||
receipts_log_filter: Default::default(),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -38,11 +38,6 @@ pub enum StageEnum {
|
||||
///
|
||||
/// Handles Merkle tree-related computations and data processing.
|
||||
Merkle,
|
||||
/// The merkle changesets stage within the pipeline.
|
||||
///
|
||||
/// Handles Merkle trie changesets for storage and accounts.
|
||||
#[value(name = "merkle-changesets")]
|
||||
MerkleChangeSets,
|
||||
/// The transaction lookup stage within the pipeline.
|
||||
///
|
||||
/// Deals with the retrieval and processing of transactions.
|
||||
|
||||
Reference in New Issue
Block a user