use crate::common::{AccessRights, Environment, EnvironmentArgs};
use alloy_primitives::B256;
use clap::Parser;
use reth_chainspec::ChainSpec;
use reth_cli::chainspec::ChainSpecParser;
use reth_config::config::EtlConfig;
use reth_db_common::init::init_from_state_dump;
use reth_node_builder::{NodeTypesWithDB, NodeTypesWithEngine};
use reth_provider::ProviderFactory;
use std::{fs::File, io::BufReader, path::PathBuf};
use tracing::info;
#[derive(Debug, Parser)]
pub struct InitStateCommand<C: ChainSpecParser> {
#[command(flatten)]
pub env: EnvironmentArgs<C>,
#[arg(value_name = "STATE_DUMP_FILE", verbatim_doc_comment)]
pub state: PathBuf,
}
impl<C: ChainSpecParser<ChainSpec = ChainSpec>> InitStateCommand<C> {
pub async fn execute<N: NodeTypesWithEngine<ChainSpec = C::ChainSpec>>(
self,
) -> eyre::Result<()> {
info!(target: "reth::cli", "Reth init-state starting");
let Environment { config, provider_factory, .. } = self.env.init::<N>(AccessRights::RW)?;
info!(target: "reth::cli", "Initiating state dump");
let hash = init_at_state(self.state, provider_factory, config.stages.etl)?;
info!(target: "reth::cli", hash = ?hash, "Genesis block written");
Ok(())
}
}
pub fn init_at_state<N: NodeTypesWithDB<ChainSpec = ChainSpec>>(
state_dump_path: PathBuf,
factory: ProviderFactory<N>,
etl_config: EtlConfig,
) -> eyre::Result<B256> {
info!(target: "reth::cli",
path=?state_dump_path,
"Opening state dump");
let file = File::open(state_dump_path)?;
let reader = BufReader::new(file);
let provider_rw = factory.provider_rw()?;
let hash = init_from_state_dump(reader, &provider_rw.0, etl_config)?;
provider_rw.commit()?;
Ok(hash)
}