From c8245594bcedeba153a52d854cc7e305308206c3 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Tue, 27 Jan 2026 11:59:06 +0000 Subject: [PATCH] fix(db): write genesis history to correct storage backend (#21471) Co-authored-by: Georgios Konstantopoulos Co-authored-by: Amp --- crates/storage/db-common/src/init.rs | 80 +++++++++++++++++++++------- 1 file changed, 62 insertions(+), 18 deletions(-) diff --git a/crates/storage/db-common/src/init.rs b/crates/storage/db-common/src/init.rs index e5cc7da755..b4dfea23bb 100644 --- a/crates/storage/db-common/src/init.rs +++ b/crates/storage/db-common/src/init.rs @@ -6,7 +6,12 @@ use alloy_primitives::{keccak256, map::HashMap, Address, B256, U256}; use reth_chainspec::EthChainSpec; use reth_codecs::Compact; use reth_config::config::EtlConfig; -use reth_db_api::{tables, transaction::DbTxMut, DatabaseError}; +use reth_db_api::{ + models::{storage_sharded_key::StorageShardedKey, ShardedKey}, + tables, + transaction::DbTxMut, + BlockNumberList, DatabaseError, +}; use reth_etl::Collector; use reth_execution_errors::StateRootError; use reth_primitives_traits::{ @@ -14,11 +19,11 @@ use reth_primitives_traits::{ }; use reth_provider::{ errors::provider::ProviderResult, providers::StaticFileWriter, BlockHashReader, BlockNumReader, - BundleStateInit, ChainSpecProvider, DBProvider, DatabaseProviderFactory, ExecutionOutcome, - HashingWriter, HeaderProvider, HistoryWriter, MetadataProvider, MetadataWriter, - OriginalValuesKnown, ProviderError, RevertsInit, StageCheckpointReader, StageCheckpointWriter, - StateWriteConfig, StateWriter, StaticFileProviderFactory, StorageSettings, - StorageSettingsCache, TrieWriter, + BundleStateInit, ChainSpecProvider, DBProvider, DatabaseProviderFactory, EitherWriter, + ExecutionOutcome, HashingWriter, HeaderProvider, HistoryWriter, MetadataProvider, + MetadataWriter, NodePrimitivesProvider, OriginalValuesKnown, ProviderError, RevertsInit, + RocksDBProviderFactory, StageCheckpointReader, StageCheckpointWriter, StateWriteConfig, + StateWriter, StaticFileProviderFactory, StorageSettings, StorageSettingsCache, TrieWriter, }; use reth_stages_types::{StageCheckpoint, StageId}; use reth_static_file_types::StaticFileSegment; @@ -103,6 +108,9 @@ where + TrieWriter + MetadataWriter + ChainSpecProvider + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider + AsRef, PF::ChainSpec: EthChainSpec
::BlockHeader>, { @@ -138,6 +146,9 @@ where + TrieWriter + MetadataWriter + ChainSpecProvider + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider + AsRef, PF::ChainSpec: EthChainSpec
::BlockHeader>, { @@ -386,37 +397,64 @@ where } /// Inserts history indices for genesis accounts and storage. +/// +/// Writes to either MDBX or `RocksDB` based on storage settings configuration, +/// using [`EitherWriter`] to abstract over the storage backend. pub fn insert_genesis_history<'a, 'b, Provider>( provider: &Provider, alloc: impl Iterator + Clone, ) -> ProviderResult<()> where - Provider: DBProvider + HistoryWriter + ChainSpecProvider, + Provider: DBProvider + + HistoryWriter + + ChainSpecProvider + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider, { let genesis_block_number = provider.chain_spec().genesis_header().number(); insert_history(provider, alloc, genesis_block_number) } /// Inserts history indices for genesis accounts and storage. +/// +/// Writes to either MDBX or `RocksDB` based on storage settings configuration, +/// using [`EitherWriter`] to abstract over the storage backend. pub fn insert_history<'a, 'b, Provider>( provider: &Provider, alloc: impl Iterator + Clone, block: u64, ) -> ProviderResult<()> where - Provider: DBProvider + HistoryWriter, + Provider: DBProvider + + HistoryWriter + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider, { - let account_transitions = alloc.clone().map(|(addr, _)| (*addr, [block])); - provider.insert_account_history_index(account_transitions)?; + provider.with_rocksdb_batch(|batch| { + let mut writer = EitherWriter::new_accounts_history(provider, batch)?; + let list = BlockNumberList::new([block]).expect("single block always fits"); + for (addr, _) in alloc.clone() { + writer.upsert_account_history(ShardedKey::last(*addr), &list)?; + } + trace!(target: "reth::cli", "Inserted account history"); + Ok(((), writer.into_raw_rocksdb_batch())) + })?; - trace!(target: "reth::cli", "Inserted account history"); - - let storage_transitions = alloc - .filter_map(|(addr, account)| account.storage.as_ref().map(|storage| (addr, storage))) - .flat_map(|(addr, storage)| storage.keys().map(|key| ((*addr, *key), [block]))); - provider.insert_storage_history_index(storage_transitions)?; - - trace!(target: "reth::cli", "Inserted storage history"); + provider.with_rocksdb_batch(|batch| { + let mut writer = EitherWriter::new_storages_history(provider, batch)?; + let list = BlockNumberList::new([block]).expect("single block always fits"); + for (addr, account) in alloc { + if let Some(storage) = &account.storage { + for key in storage.keys() { + writer.upsert_storage_history(StorageShardedKey::last(*addr, *key), &list)?; + } + } + } + trace!(target: "reth::cli", "Inserted storage history"); + Ok(((), writer.into_raw_rocksdb_batch())) + })?; Ok(()) } @@ -492,6 +530,9 @@ where + HashingWriter + TrieWriter + StateWriter + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider + AsRef, { if etl_config.file_size == 0 { @@ -628,6 +669,9 @@ where + HashingWriter + HistoryWriter + StateWriter + + StorageSettingsCache + + RocksDBProviderFactory + + NodePrimitivesProvider + AsRef, { let accounts_len = collector.len();