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
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/cli/commands/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ reth-stages-types = { workspace = true, optional = true }
reth-static-file-types = { workspace = true, features = ["clap"] }
reth-static-file.workspace = true
reth-tasks.workspace = true
reth-storage-api.workspace = true
reth-trie = { workspace = true, features = ["metrics"] }
reth-trie-db = { workspace = true, features = ["metrics"] }
reth-trie-common.workspace = true
Expand Down
34 changes: 34 additions & 0 deletions crates/cli/commands/src/db/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use reth_node_builder::NodeTypesWithDB;
use reth_primitives_traits::ValueWithSubKey;
use reth_provider::{providers::ProviderNodeTypes, ChangeSetReader, StaticFileProviderFactory};
use reth_static_file_types::StaticFileSegment;
use reth_storage_api::StorageChangeSetReader;
use tracing::error;

/// The arguments for the `reth db get` command
Expand Down Expand Up @@ -82,6 +83,33 @@ impl Command {
table.view(&GetValueViewer { tool, key, subkey, end_key, end_subkey, raw })?
}
Subcommand::StaticFile { segment, key, subkey, raw } => {
if let StaticFileSegment::StorageChangeSets = segment {
let storage_key =
table_subkey::<tables::StorageChangeSets>(subkey.as_deref()).ok();
let key = table_key::<tables::StorageChangeSets>(&key)?;

let provider = tool.provider_factory.static_file_provider();

if let Some(storage_key) = storage_key {
let entry = provider.get_storage_before_block(
key.block_number(),
key.address(),
storage_key,
)?;

if let Some(entry) = entry {
println!("{}", serde_json::to_string_pretty(&entry)?);
} else {
error!(target: "reth::cli", "No content for the given table key.");
}
return Ok(());
}

let changesets = provider.storage_changeset(key.block_number())?;
println!("{}", serde_json::to_string_pretty(&changesets)?);
return Ok(());
}

let (key, subkey, mask): (u64, _, _) = match segment {
StaticFileSegment::Headers => (
table_key::<tables::Headers>(&key)?,
Expand Down Expand Up @@ -112,6 +140,9 @@ impl Command {
AccountChangesetMask::MASK,
)
}
StaticFileSegment::StorageChangeSets => {
unreachable!("storage changesets handled above");
}
};

// handle account changesets differently if a subkey is provided.
Expand Down Expand Up @@ -190,6 +221,9 @@ impl Command {
StaticFileSegment::AccountChangeSets => {
unreachable!("account changeset static files are special cased before this match")
}
StaticFileSegment::StorageChangeSets => {
unreachable!("storage changeset static files are special cased before this match")
}
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions crates/cli/commands/src/db/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ pub enum SetCommand {
#[clap(action(ArgAction::Set))]
value: bool,
},
/// Store storage changesets in static files instead of the database
StorageChangesets {
#[clap(action(ArgAction::Set))]
value: bool,
},
}

impl Command {
Expand Down Expand Up @@ -115,6 +120,7 @@ impl Command {
transaction_hash_numbers_in_rocksdb: _,
account_history_in_rocksdb: _,
account_changesets_in_static_files: _,
storage_changesets_in_static_files: _,
} = settings.unwrap_or_else(StorageSettings::legacy);

// Update the setting based on the key
Expand Down Expand Up @@ -167,6 +173,14 @@ impl Command {
settings.account_history_in_rocksdb = value;
println!("Set account_history_in_rocksdb = {}", value);
}
SetCommand::StorageChangesets { value } => {
if settings.storage_changesets_in_static_files == value {
println!("storage_changesets_in_static_files is already set to {}", value);
return Ok(());
}
settings.storage_changesets_in_static_files = value;
println!("Set storage_changesets_in_static_files = {}", value);
}
}

// Write updated settings
Expand Down
3 changes: 3 additions & 0 deletions crates/cli/commands/src/stage/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ impl<C: ChainSpecParser> Command<C> {
StaticFileSegment::AccountChangeSets => {
writer.prune_account_changesets(highest_block)?;
}
StaticFileSegment::StorageChangeSets => {
writer.prune_storage_changesets(highest_block)?;
}
}
}
}
Expand Down
9 changes: 9 additions & 0 deletions crates/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,8 @@ pub struct BlocksPerFileConfig {
pub transaction_senders: Option<u64>,
/// Number of blocks per file for the account changesets segment.
pub account_change_sets: Option<u64>,
/// Number of blocks per file for the storage changesets segment.
pub storage_change_sets: Option<u64>,
}

impl StaticFilesConfig {
Expand All @@ -451,6 +453,7 @@ impl StaticFilesConfig {
receipts,
transaction_senders,
account_change_sets,
storage_change_sets,
} = self.blocks_per_file;
eyre::ensure!(headers != Some(0), "Headers segment blocks per file must be greater than 0");
eyre::ensure!(
Expand All @@ -469,6 +472,10 @@ impl StaticFilesConfig {
account_change_sets != Some(0),
"Account changesets segment blocks per file must be greater than 0"
);
eyre::ensure!(
storage_change_sets != Some(0),
"Storage changesets segment blocks per file must be greater than 0"
);
Ok(())
}

Expand All @@ -480,6 +487,7 @@ impl StaticFilesConfig {
receipts,
transaction_senders,
account_change_sets,
storage_change_sets,
} = self.blocks_per_file;

let mut map = StaticFileMap::default();
Expand All @@ -492,6 +500,7 @@ impl StaticFilesConfig {
StaticFileSegment::Receipts => receipts,
StaticFileSegment::TransactionSenders => transaction_senders,
StaticFileSegment::AccountChangeSets => account_change_sets,
StaticFileSegment::StorageChangeSets => storage_change_sets,
};

if let Some(blocks_per_file) = blocks_per_file {
Expand Down
4 changes: 3 additions & 1 deletion crates/engine/tree/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedBlock, Sealed
use reth_provider::{
BlockExecutionOutput, BlockExecutionResult, BlockNumReader, BlockReader, ChangeSetReader,
DatabaseProviderFactory, HashedPostStateProvider, ProviderError, StageCheckpointReader,
StateProviderBox, StateProviderFactory, StateReader, TransactionVariant,
StateProviderBox, StateProviderFactory, StateReader, StorageChangeSetReader,
TransactionVariant,
};
use reth_revm::database::StateProviderDatabase;
use reth_stages_api::ControlFlow;
Expand Down Expand Up @@ -317,6 +318,7 @@ where
<P as DatabaseProviderFactory>::Provider: BlockReader<Block = N::Block, Header = N::BlockHeader>
+ StageCheckpointReader
+ ChangeSetReader
+ StorageChangeSetReader
+ BlockNumReader,
C: ConfigureEvm<Primitives = N> + 'static,
T: PayloadTypes<BuiltPayload: BuiltPayload<Primitives = N>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ mod tests {
use reth_provider::{
providers::OverlayStateProviderFactory, test_utils::create_test_provider_factory,
BlockNumReader, BlockReader, ChangeSetReader, DatabaseProviderFactory, LatestStateProvider,
PruneCheckpointReader, StageCheckpointReader, StateProviderBox,
PruneCheckpointReader, StageCheckpointReader, StateProviderBox, StorageChangeSetReader,
};
use reth_trie::MultiProof;
use reth_trie_db::ChangesetCache;
Expand All @@ -1550,6 +1550,7 @@ mod tests {
+ StageCheckpointReader
+ PruneCheckpointReader
+ ChangeSetReader
+ StorageChangeSetReader
+ BlockNumReader,
> + Clone
+ Send
Expand Down
4 changes: 3 additions & 1 deletion crates/engine/tree/src/tree/payload_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use reth_provider::{
providers::OverlayStateProviderFactory, BlockExecutionOutput, BlockNumReader, BlockReader,
ChangeSetReader, DatabaseProviderFactory, DatabaseProviderROFactory, HashedPostStateProvider,
ProviderError, PruneCheckpointReader, StageCheckpointReader, StateProvider,
StateProviderFactory, StateReader,
StateProviderFactory, StateReader, StorageChangeSetReader,
};
use reth_revm::db::{states::bundle_state::BundleRetention, State};
use reth_trie::{updates::TrieUpdates, HashedPostState, StateRoot};
Expand Down Expand Up @@ -144,6 +144,7 @@ where
+ StageCheckpointReader
+ PruneCheckpointReader
+ ChangeSetReader
+ StorageChangeSetReader
+ BlockNumReader,
> + BlockReader<Header = N::BlockHeader>
+ ChangeSetReader
Expand Down Expand Up @@ -1332,6 +1333,7 @@ where
+ StageCheckpointReader
+ PruneCheckpointReader
+ ChangeSetReader
+ StorageChangeSetReader
+ BlockNumReader,
> + BlockReader<Header = N::BlockHeader>
+ StateProviderFactory
Expand Down
33 changes: 33 additions & 0 deletions crates/node/core/src/args/static_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use clap::Args;
use reth_config::config::{BlocksPerFileConfig, StaticFilesConfig};
use reth_storage_api::StorageSettings;

/// Blocks per static file when running in `--minimal` node.
///
Expand Down Expand Up @@ -40,6 +41,10 @@ pub struct StaticFilesArgs {
#[arg(long = "static-files.blocks-per-file.account-change-sets")]
pub blocks_per_file_account_change_sets: Option<u64>,

/// Number of blocks per file for the storage changesets segment.
#[arg(long = "static-files.blocks-per-file.storage-change-sets")]
pub blocks_per_file_storage_change_sets: Option<u64>,

/// Store receipts in static files instead of the database.
///
/// When enabled, receipts will be written to static files on disk instead of the database.
Expand Down Expand Up @@ -68,6 +73,16 @@ pub struct StaticFilesArgs {
/// the node has been initialized, changing this flag requires re-syncing from scratch.
#[arg(long = "static-files.account-change-sets", default_value_t = default_static_file_flag(), action = clap::ArgAction::Set)]
pub account_changesets: bool,

/// Store storage changesets in static files.
///
/// When enabled, storage changesets will be written to static files on disk instead of the
/// database.
///
/// Note: This setting can only be configured at genesis initialization. Once
/// the node has been initialized, changing this flag requires re-syncing from scratch.
#[arg(long = "static-files.storage-change-sets", default_value_t = default_static_file_flag(), action = clap::ArgAction::Set)]
pub storage_changesets: bool,
}

impl StaticFilesArgs {
Expand Down Expand Up @@ -98,9 +113,25 @@ impl StaticFilesArgs {
account_change_sets: self
.blocks_per_file_account_change_sets
.or(config.blocks_per_file.account_change_sets),
storage_change_sets: self
.blocks_per_file_storage_change_sets
.or(config.blocks_per_file.storage_change_sets),
},
}
}

/// Converts the static files arguments into [`StorageSettings`].
pub const fn to_settings(&self) -> StorageSettings {
#[cfg(feature = "edge")]
let base = StorageSettings::edge();
#[cfg(not(feature = "edge"))]
let base = StorageSettings::legacy();

base.with_receipts_in_static_files(self.receipts)
.with_transaction_senders_in_static_files(self.transaction_senders)
.with_account_changesets_in_static_files(self.account_changesets)
.with_storage_changesets_in_static_files(self.storage_changesets)
}
}

impl Default for StaticFilesArgs {
Expand All @@ -111,9 +142,11 @@ impl Default for StaticFilesArgs {
blocks_per_file_receipts: None,
blocks_per_file_transaction_senders: None,
blocks_per_file_account_change_sets: None,
blocks_per_file_storage_change_sets: None,
receipts: default_static_file_flag(),
transaction_senders: default_static_file_flag(),
account_changesets: default_static_file_flag(),
storage_changesets: default_static_file_flag(),
}
}
}
1 change: 1 addition & 0 deletions crates/node/core/src/node_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
.with_receipts_in_static_files(self.static_files.receipts)
.with_transaction_senders_in_static_files(self.static_files.transaction_senders)
.with_account_changesets_in_static_files(self.static_files.account_changesets)
.with_storage_changesets_in_static_files(self.static_files.storage_changesets)
.with_transaction_hash_numbers_in_rocksdb(self.rocksdb.all || self.rocksdb.tx_hash)
.with_storages_history_in_rocksdb(self.rocksdb.all || self.rocksdb.storages_history)
.with_account_history_in_rocksdb(self.rocksdb.all || self.rocksdb.account_history)
Expand Down
14 changes: 10 additions & 4 deletions crates/stages/stages/src/stages/index_storage_history.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::collect_history_indices;
use super::{collect_history_indices, collect_storage_history_indices};
use crate::{stages::utils::load_storage_history, StageCheckpoint, StageId};
use reth_config::config::{EtlConfig, IndexHistoryConfig};
use reth_db_api::{
Expand All @@ -8,7 +8,8 @@ use reth_db_api::{
};
use reth_provider::{
DBProvider, EitherWriter, HistoryWriter, PruneCheckpointReader, PruneCheckpointWriter,
RocksDBProviderFactory, StorageSettingsCache,
RocksDBProviderFactory, StaticFileProviderFactory, StorageChangeSetReader,
StorageSettingsCache,
};
use reth_prune_types::{PruneCheckpoint, PruneMode, PrunePurpose, PruneSegment};
use reth_stages_api::{ExecInput, ExecOutput, Stage, StageError, UnwindInput, UnwindOutput};
Expand Down Expand Up @@ -54,6 +55,8 @@ where
+ PruneCheckpointWriter
+ StorageSettingsCache
+ RocksDBProviderFactory
+ StorageChangeSetReader
+ StaticFileProviderFactory
+ reth_provider::NodePrimitivesProvider,
{
/// Return the id of the stage
Expand Down Expand Up @@ -121,7 +124,9 @@ where
}

info!(target: "sync::stages::index_storage_history::exec", ?first_sync, ?use_rocksdb, "Collecting indices");
let collector =
let collector = if provider.cached_storage_settings().storage_changesets_in_static_files {
collect_storage_history_indices(provider, range.clone(), &self.etl_config)?
} else {
collect_history_indices::<_, tables::StorageChangeSets, tables::StoragesHistory, _>(
provider,
BlockNumberAddress::range(range.clone()),
Expand All @@ -130,7 +135,8 @@ where
},
|(key, value)| (key.block_number(), AddressStorageKey((key.address(), value.key))),
&self.etl_config,
)?;
)?
};

info!(target: "sync::stages::index_storage_history::exec", "Loading indices into database");

Expand Down
3 changes: 2 additions & 1 deletion crates/stages/stages/src/stages/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reth_db_api::{
use reth_primitives_traits::{GotExpected, SealedHeader};
use reth_provider::{
ChangeSetReader, DBProvider, HeaderProvider, ProviderError, StageCheckpointReader,
StageCheckpointWriter, StatsReader, TrieWriter,
StageCheckpointWriter, StatsReader, StorageChangeSetReader, TrieWriter,
};
use reth_stages_api::{
BlockErrorKind, EntitiesCheckpoint, ExecInput, ExecOutput, MerkleCheckpoint, Stage,
Expand Down Expand Up @@ -159,6 +159,7 @@ where
+ StatsReader
+ HeaderProvider
+ ChangeSetReader
+ StorageChangeSetReader
+ StageCheckpointReader
+ StageCheckpointWriter,
{
Expand Down
6 changes: 4 additions & 2 deletions crates/stages/stages/src/stages/merkle_changesets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use reth_primitives_traits::{GotExpected, SealedHeader};
use reth_provider::{
BlockNumReader, ChainStateBlockReader, ChangeSetReader, DBProvider, HeaderProvider,
ProviderError, PruneCheckpointReader, PruneCheckpointWriter, StageCheckpointReader,
StageCheckpointWriter, TrieWriter,
StageCheckpointWriter, StorageChangeSetReader, TrieWriter,
};
use reth_prune_types::{
PruneCheckpoint, PruneMode, PruneSegment, MERKLE_CHANGESETS_RETENTION_BLOCKS,
Expand Down Expand Up @@ -167,7 +167,8 @@ impl MerkleChangeSets {
+ HeaderProvider
+ ChainStateBlockReader
+ BlockNumReader
+ ChangeSetReader,
+ ChangeSetReader
+ StorageChangeSetReader,
{
let target_start = target_range.start;
let target_end = target_range.end;
Expand Down Expand Up @@ -308,6 +309,7 @@ where
+ PruneCheckpointReader
+ PruneCheckpointWriter
+ ChangeSetReader
+ StorageChangeSetReader
+ BlockNumReader,
{
fn id(&self) -> StageId {
Expand Down
Loading
Loading