1pub mod subcoin_params;
2
3use crate::commands::blockchain::{Blockchain, BlockchainCmd};
4use crate::commands::import_blocks::{ImportBlocks, ImportBlocksCmd};
5use crate::commands::run::{Run, RunCmd};
6use crate::commands::tools::Tools;
7use crate::substrate_cli::SubstrateCli;
8use clap::Parser;
9use sc_cli::SubstrateCli as SubstrateCliT;
12use sc_client_api::UsageProvider;
13use sc_consensus_nakamoto::ImportConfig;
14use sc_service::PartialComponents;
15use std::sync::Arc;
16use subcoin_primitives::CONFIRMATION_DEPTH;
17
18#[derive(Debug, clap::Subcommand)]
19pub enum Command {
20 Run(Box<Run>),
22
23 ImportBlocks(ImportBlocks),
25
26 #[command(subcommand)]
28 Tools(Tools),
29
30 #[command(subcommand)]
32 Blockchain(Blockchain),
33
34 BuildSpec(sc_cli::BuildSpecCmd),
36
37 CheckBlock(Box<sc_cli::CheckBlockCmd>),
39
40 ExportBlocks(sc_cli::ExportBlocksCmd),
42
43 ExportState(sc_cli::ExportStateCmd),
45
46 PurgeChain(sc_cli::PurgeChainCmd),
48
49 Revert(sc_cli::RevertCmd),
51
52 ChainInfo(sc_cli::ChainInfoCmd),
58}
59
60#[derive(Debug, Parser)]
62#[clap(version = env!("SUBSTRATE_CLI_IMPL_VERSION"))]
63pub struct Cli {
64 #[command(subcommand)]
65 pub command: Command,
66
67 #[allow(missing_docs)]
68 #[clap(flatten)]
69 pub storage_monitor: sc_storage_monitor::StorageMonitorParams,
70}
71
72pub fn run() -> sc_cli::Result<()> {
74 let Cli {
75 command,
76 storage_monitor,
77 } = Cli::parse();
78
79 match command {
80 Command::Run(run) => {
81 let run_cmd = RunCmd::new(*run);
82 let runner = SubstrateCli.create_runner(&run_cmd)?;
83 runner.run_node_until_exit(|config| async move {
84 run_cmd.start(config, storage_monitor).await
85 })
86 }
87 Command::ImportBlocks(cmd) => {
88 let bitcoin_network = cmd.common_params.bitcoin_network();
89 let import_config = ImportConfig {
90 execute_block: cmd.execute_transactions,
91 ..cmd.common_params.import_config(true)
92 };
93 let chain_spec_id = cmd.common_params.chain.chain_spec_id();
94 let maybe_prometheus_config = cmd
95 .prometheus_params
96 .prometheus_config(9615, chain_spec_id.to_string());
97 let import_blocks_cmd = ImportBlocksCmd::new(&cmd);
98 let runner = SubstrateCli.create_runner(&import_blocks_cmd)?;
99 let data_dir = cmd.data_dir;
100 runner.async_run(|config| {
101 let subcoin_service::NodeComponents {
102 client,
103 task_manager,
104 ..
105 } = subcoin_service::new_node(subcoin_service::SubcoinConfiguration {
106 network: bitcoin_network,
107 config: &config,
108 no_hardware_benchmarks: true,
109 storage_monitor,
110 })?;
111 let spawn_handle = task_manager.spawn_handle();
112 spawn_handle.spawn("finalizer", None, {
113 let client = client.clone();
114 let spawn_handle = task_manager.spawn_handle();
115 subcoin_service::SubcoinFinalizer::new(
116 client,
117 spawn_handle,
118 CONFIRMATION_DEPTH,
119 Arc::new(subcoin_network::OfflineSync),
120 None,
121 )
122 .run()
123 });
124 Ok((
125 import_blocks_cmd.run(
126 client,
127 data_dir,
128 import_config,
129 spawn_handle,
130 maybe_prometheus_config,
131 ),
132 task_manager,
133 ))
134 })
135 }
136 Command::Tools(tools) => tools.run(),
137 Command::Blockchain(blockchain) => {
138 let cmd = BlockchainCmd::new(blockchain);
139 let runner = SubstrateCli.create_runner(&cmd)?;
140 runner.async_run(|config| {
141 let subcoin_service::NodeComponents {
142 client,
143 task_manager,
144 ..
145 } = subcoin_service::new_node(subcoin_service::SubcoinConfiguration {
146 network: bitcoin::Network::Bitcoin,
147 config: &config,
148 no_hardware_benchmarks: true,
149 storage_monitor,
150 })?;
151 Ok((cmd.run(client), task_manager))
152 })
153 }
154 Command::BuildSpec(cmd) => {
155 let runner = SubstrateCli.create_runner(&cmd)?;
156 runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
157 }
158 Command::CheckBlock(cmd) => {
159 let runner = SubstrateCli.create_runner(&*cmd)?;
160 runner.async_run(|config| {
161 let PartialComponents {
162 client,
163 task_manager,
164 import_queue,
165 ..
166 } = subcoin_service::new_partial(&config, bitcoin::Network::Bitcoin)?;
167 Ok((cmd.run(client, import_queue), task_manager))
168 })
169 }
170 Command::ExportBlocks(cmd) => {
171 let runner = SubstrateCli.create_runner(&cmd)?;
172 runner.async_run(|config| {
173 let PartialComponents {
174 client,
175 task_manager,
176 ..
177 } = subcoin_service::new_partial(&config, bitcoin::Network::Bitcoin)?;
178 Ok((cmd.run(client, config.database), task_manager))
179 })
180 }
181 Command::ExportState(cmd) => {
182 let runner = SubstrateCli.create_runner(&cmd)?;
183 runner.async_run(|config| {
184 let PartialComponents {
185 client,
186 task_manager,
187 ..
188 } = subcoin_service::new_partial(&config, bitcoin::Network::Bitcoin)?;
189
190 let run_cmd = async move {
191 tracing::info!("Exporting raw state...");
192 let hash = client.usage_info().chain.best_hash;
197 let _raw_state = sc_service::chain_ops::export_raw_state(client, hash).unwrap();
199
200 tracing::info!("Raw state exported successfully");
201
202 Ok(())
203 };
204
205 Ok((run_cmd, task_manager))
206 })
207 }
208 Command::PurgeChain(cmd) => {
209 let runner = SubstrateCli.create_runner(&cmd)?;
210 runner.sync_run(|config| cmd.run(config.database))
211 }
212 Command::Revert(cmd) => {
213 let runner = SubstrateCli.create_runner(&cmd)?;
214 runner.async_run(|config| {
215 let PartialComponents {
216 client,
217 task_manager,
218 backend,
219 ..
220 } = subcoin_service::new_partial(&config, bitcoin::Network::Bitcoin)?;
221 Ok((cmd.run(client, backend, None), task_manager))
222 })
223 }
224 Command::ChainInfo(cmd) => {
268 let runner = SubstrateCli.create_runner(&cmd)?;
269 runner.sync_run(|config| cmd.run::<subcoin_runtime::interface::OpaqueBlock>(&config))
270 }
271 }
272}