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
40 changes: 35 additions & 5 deletions crates/cli/commands/src/init_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::common::{AccessRights, CliHeader, CliNodeTypes, Environment, EnvironmentArgs};
use alloy_consensus::BlockHeader as AlloyBlockHeader;
use alloy_primitives::{B256, U256};
use alloy_primitives::{Sealable, B256, U256};
use clap::Parser;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_cli::chainspec::ChainSpecParser;
Expand Down Expand Up @@ -64,7 +64,7 @@ pub struct InitStateCommand<C: ChainSpecParser> {

/// Hash of the header.
#[arg(long, value_name = "HEADER_HASH", verbatim_doc_comment)]
pub header_hash: Option<String>,
pub header_hash: Option<B256>,
}

impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateCommand<C> {
Expand All @@ -90,9 +90,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> InitStateC
<N::Primitives as NodePrimitives>::BlockHeader,
>(header)?;

let header_hash =
self.header_hash.ok_or_else(|| eyre::eyre!("Header hash must be provided"))?;
let header_hash = B256::from_str(&header_hash)?;
let header_hash = self.header_hash.unwrap_or_else(|| header.hash_slow());

let total_difficulty = self
.total_difficulty
Expand Down Expand Up @@ -146,3 +144,35 @@ impl<C: ChainSpecParser> InitStateCommand<C> {
Some(&self.env.chain)
}
}

#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::b256;
use reth_ethereum_cli::chainspec::EthereumChainSpecParser;

#[test]
fn parse_init_state_command_with_without_evm() {
let cmd: InitStateCommand<EthereumChainSpecParser> = InitStateCommand::parse_from([
"reth",
"--chain",
"sepolia",
"--without-evm",
"--header",
"header.rlp",
"--total-difficulty",
"12345",
"--header-hash",
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"state.jsonl",
]);
assert_eq!(cmd.state.to_str().unwrap(), "state.jsonl");
assert!(cmd.without_evm);
assert_eq!(cmd.header.unwrap().to_str().unwrap(), "header.rlp");
assert_eq!(cmd.total_difficulty.unwrap(), "12345");
assert_eq!(
cmd.header_hash.unwrap(),
b256!("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
);
}
}
14 changes: 10 additions & 4 deletions crates/storage/db-common/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use reth_config::config::EtlConfig;
use reth_db_api::{tables, transaction::DbTxMut, DatabaseError};
use reth_etl::Collector;
use reth_execution_errors::StateRootError;
use reth_primitives_traits::{Account, Bytecode, GotExpected, NodePrimitives, StorageEntry};
use reth_primitives_traits::{
Account, Bytecode, GotExpected, NodePrimitives, SealedHeader, StorageEntry,
};
use reth_provider::{
errors::provider::ProviderResult, providers::StaticFileWriter, BlockHashReader, BlockNumReader,
BundleStateInit, ChainSpecProvider, DBProvider, DatabaseProviderFactory, ExecutionOutcome,
Expand Down Expand Up @@ -389,20 +391,24 @@ where
}

let block = provider_rw.last_block_number()?;

let hash = provider_rw
.block_hash(block)?
.ok_or_else(|| eyre::eyre!("Block hash not found for block {}", block))?;
let expected_state_root = provider_rw
let header = provider_rw
.header_by_number(block)?
.ok_or_else(|| ProviderError::HeaderNotFound(block.into()))?
.state_root();
.map(SealedHeader::seal_slow)
.ok_or_else(|| ProviderError::HeaderNotFound(block.into()))?;

let expected_state_root = header.state_root();

// first line can be state root
let dump_state_root = parse_state_root(&mut reader)?;
if expected_state_root != dump_state_root {
error!(target: "reth::cli",
?dump_state_root,
?expected_state_root,
header=?header.num_hash(),
"State root from state dump does not match state root in current header."
);
return Err(InitStorageError::StateRootMismatch(GotExpected {
Expand Down
Loading