fix(db): write genesis history to correct storage backend (#21471)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
joshieDo
2026-01-27 11:59:06 +00:00
committed by GitHub
parent ed40ce8c4c
commit c8245594bc

View File

@@ -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::ProviderRW>,
PF::ChainSpec: EthChainSpec<Header = <PF::Primitives as NodePrimitives>::BlockHeader>,
{
@@ -138,6 +146,9 @@ where
+ TrieWriter
+ MetadataWriter
+ ChainSpecProvider
+ StorageSettingsCache
+ RocksDBProviderFactory
+ NodePrimitivesProvider
+ AsRef<PF::ProviderRW>,
PF::ChainSpec: EthChainSpec<Header = <PF::Primitives as NodePrimitives>::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<Item = (&'a Address, &'b GenesisAccount)> + Clone,
) -> ProviderResult<()>
where
Provider: DBProvider<Tx: DbTxMut> + HistoryWriter + ChainSpecProvider,
Provider: DBProvider<Tx: DbTxMut>
+ 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<Item = (&'a Address, &'b GenesisAccount)> + Clone,
block: u64,
) -> ProviderResult<()>
where
Provider: DBProvider<Tx: DbTxMut> + HistoryWriter,
Provider: DBProvider<Tx: DbTxMut>
+ 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<Provider>,
{
if etl_config.file_size == 0 {
@@ -628,6 +669,9 @@ where
+ HashingWriter
+ HistoryWriter
+ StateWriter
+ StorageSettingsCache
+ RocksDBProviderFactory
+ NodePrimitivesProvider
+ AsRef<Provider>,
{
let accounts_len = collector.len();