reth_cli_commands/
export_era.rs1use crate::common::{AccessRights, CliNodeTypes, Environment, EnvironmentArgs};
4use clap::{Args, Parser};
5use reth_chainspec::{EthChainSpec, EthereumHardforks};
6use reth_cli::chainspec::ChainSpecParser;
7use reth_era::execution_types::MAX_BLOCKS_PER_ERA1;
8use reth_era_utils as era1;
9use reth_provider::DatabaseProviderFactory;
10use std::{path::PathBuf, sync::Arc};
11use tracing::info;
12
13const ERA1_EXPORT_FOLDER_NAME: &str = "era1-export";
15
16#[derive(Debug, Parser)]
17pub struct ExportEraCommand<C: ChainSpecParser> {
18 #[command(flatten)]
19 env: EnvironmentArgs<C>,
20
21 #[clap(flatten)]
22 export: ExportArgs,
23}
24
25#[derive(Debug, Args)]
26pub struct ExportArgs {
27 #[arg(long, value_name = "first-block-number", verbatim_doc_comment)]
30 first_block_number: Option<u64>,
31 #[arg(long, value_name = "last-block-number", verbatim_doc_comment)]
34 last_block_number: Option<u64>,
35 #[arg(long, value_name = "max-blocks-per-file", verbatim_doc_comment)]
38 max_blocks_per_file: Option<u64>,
39 #[arg(long, value_name = "EXPORT_ERA1_PATH", verbatim_doc_comment)]
42 path: Option<PathBuf>,
43}
44
45impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> ExportEraCommand<C> {
46 pub async fn execute<N>(self) -> eyre::Result<()>
48 where
49 N: CliNodeTypes<ChainSpec = C::ChainSpec>,
50 {
51 let Environment { provider_factory, .. } = self.env.init::<N>(AccessRights::RO)?;
52
53 let data_dir = match &self.export.path {
55 Some(path) => path.clone(),
56 None => self
57 .env
58 .datadir
59 .resolve_datadir(self.env.chain.chain())
60 .data_dir()
61 .join(ERA1_EXPORT_FOLDER_NAME),
62 };
63
64 let export_config = era1::ExportConfig {
65 network: self.env.chain.chain().to_string(),
66 first_block_number: self.export.first_block_number.unwrap_or(0),
67 last_block_number: self
68 .export
69 .last_block_number
70 .unwrap_or(MAX_BLOCKS_PER_ERA1 as u64 - 1),
71 max_blocks_per_file: self
72 .export
73 .max_blocks_per_file
74 .unwrap_or(MAX_BLOCKS_PER_ERA1 as u64),
75 dir: data_dir,
76 };
77
78 export_config.validate()?;
79
80 info!(
81 target: "reth::cli",
82 "Starting ERA1 block export: blocks {}-{} to {}",
83 export_config.first_block_number,
84 export_config.last_block_number,
85 export_config.dir.display()
86 );
87
88 let provider = provider_factory.database_provider_ro()?;
90
91 let exported_files = era1::export(&provider, &export_config)?;
92
93 info!(
94 target: "reth::cli",
95 "Successfully exported {} ERA1 files to {}",
96 exported_files.len(),
97 export_config.dir.display()
98 );
99
100 Ok(())
101 }
102}
103
104impl<C: ChainSpecParser> ExportEraCommand<C> {
105 pub fn chain_spec(&self) -> Option<&Arc<C::ChainSpec>> {
107 Some(&self.env.chain)
108 }
109}