partner_chains_node_commands/
lib.rs1use authority_selection_inherents::authority_selection_inputs::AuthoritySelectionDataSource;
2use authority_selection_inherents::authority_selection_inputs::AuthoritySelectionInputs;
3use authority_selection_inherents::filter_invalid_candidates::CandidateValidationApi;
4use clap::Parser;
5use cli_commands::address_association_signatures::AddressAssociationSignaturesCmd;
6use cli_commands::block_producer_metadata_signatures::BlockProducerMetadataSignatureCmd;
7use cli_commands::registration_signatures::RegistrationSignaturesCmd;
8use frame_support::sp_runtime::traits::NumberFor;
9use parity_scale_codec::{Decode, Encode};
10use partner_chains_cli::io::DefaultCmdRunContext;
11pub use partner_chains_cli::{
12 PartnerChainRuntime, PartnerChainRuntimeBindings, RuntimeTypeWrapper,
13};
14use partner_chains_smart_contracts_commands::SmartContractsCmd;
15use sc_cli::{CliConfiguration, SharedParams, SubstrateCli};
16use sc_service::TaskManager;
17use sidechain_domain::{McEpochNumber, ScEpochNumber, StakePoolPublicKey};
18use sp_api::ProvideRuntimeApi;
19use sp_blockchain::HeaderBackend;
20use sp_runtime::DeserializeOwned;
21use sp_runtime::Serialize;
22use sp_runtime::traits::Block as BlockT;
23use sp_session_validator_management::CommitteeMember as CommitteeMemberT;
24use sp_session_validator_management::SessionValidatorManagementApi;
25use sp_session_validator_management_query::SessionValidatorManagementQuery;
26use sp_session_validator_management_query::commands::*;
27#[allow(deprecated)]
28use sp_sidechain::{GetGenesisUtxo, GetSidechainStatus};
29use std::future::Future;
30use std::str::FromStr;
31use std::sync::Arc;
32
33#[derive(Debug, Clone, Parser)]
34pub struct AriadneParametersCmd {
35 #[arg(long)]
36 pub mc_epoch_number: McEpochNumber,
37 #[allow(missing_docs)]
38 #[clap(flatten)]
39 pub shared_params: SharedParams,
40}
41
42impl CliConfiguration for AriadneParametersCmd {
43 fn shared_params(&self) -> &SharedParams {
44 &self.shared_params
45 }
46}
47
48#[derive(Debug, Clone, Parser)]
49pub struct SidechainParamsCmd {
50 #[allow(missing_docs)]
51 #[clap(flatten)]
52 pub shared_params: SharedParams,
53}
54
55impl CliConfiguration for SidechainParamsCmd {
56 fn shared_params(&self) -> &SharedParams {
57 &self.shared_params
58 }
59}
60
61#[derive(Debug, Clone, Parser)]
62pub struct RegistrationStatusCmd {
63 #[arg(long)]
64 #[arg(long, alias = "mainchain-pub-key")]
65 pub stake_pool_pub_key: StakePoolPublicKey,
66 #[arg(long)]
67 pub mc_epoch_number: McEpochNumber,
68 #[allow(missing_docs)]
69 #[clap(flatten)]
70 pub shared_params: SharedParams,
71}
72
73impl CliConfiguration for RegistrationStatusCmd {
74 fn shared_params(&self) -> &SharedParams {
75 &self.shared_params
76 }
77}
78
79#[derive(Clone, Debug, clap::Subcommand)]
80#[allow(clippy::large_enum_variant)]
81pub enum PartnerChainsSubcommand<
82 RuntimeBindings: PartnerChainRuntime + PartnerChainRuntimeBindings,
83 PartnerchainAddress: Clone + Sync + Send + FromStr + 'static,
84> {
85 SidechainParams(SidechainParamsCmd),
87
88 #[clap(
92 after_help = "Example: partner-chains-node -- registration-status --stake-pool-pub-key 0x702b81ab2e86cf73a87062af1eb0da666d451976d9d91c63a119ed94e6a33dc0 --mc-epoch-number 586"
93 )]
94 RegistrationStatus(RegistrationStatusCmd),
95
96 AriadneParameters(AriadneParametersCmd),
99
100 RegistrationSignatures(RegistrationSignaturesCmd),
102
103 SignAddressAssociation(AddressAssociationSignaturesCmd<PartnerchainAddress>),
105
106 SignBlockProducerMetadata(BlockProducerMetadataSignatureCmd),
108
109 #[command(subcommand)]
111 SmartContracts(SmartContractsCmd),
112
113 #[command(subcommand)]
115 Wizards(partner_chains_cli::Command<RuntimeBindings>),
116}
117
118#[allow(deprecated)]
119pub fn run<
120 Cli,
121 Block,
122 CommitteeMember,
123 Client,
124 BlockProducerMetadata,
125 RuntimeBindings: PartnerChainRuntime + PartnerChainRuntimeBindings,
126 PartnerchainAddress,
127>(
128 cli: &Cli,
129 get_deps: impl FnOnce(
130 sc_service::Configuration,
131 ) -> Result<
132 (Arc<Client>, TaskManager, Arc<dyn AuthoritySelectionDataSource + Send + Sync>),
133 sc_service::error::Error,
134 >,
135 cmd: PartnerChainsSubcommand<RuntimeBindings, PartnerchainAddress>,
136) -> sc_cli::Result<()>
137where
138 Cli: SubstrateCli,
139 Client: ProvideRuntimeApi<Block> + HeaderBackend<Block> + 'static,
140 Client::Api: GetGenesisUtxo<Block>
141 + GetSidechainStatus<Block>
142 + SessionValidatorManagementApi<
143 Block,
144 CommitteeMember,
145 AuthoritySelectionInputs,
146 ScEpochNumber,
147 > + CandidateValidationApi<Block>,
148 Block: BlockT,
149 NumberFor<Block>: From<u32> + Into<u32>,
150 CommitteeMember: CommitteeMemberT + Encode + Decode + Send + Sync + 'static,
151 CommitteeMember::AuthorityId: Decode + Encode + AsRef<[u8]> + Send + Sync + 'static,
152 CommitteeMember::AuthorityKeys: Decode + Encode,
153 BlockProducerMetadata: DeserializeOwned + Encode + Send + Sync,
154 PartnerchainAddress: Serialize + Clone + Sync + Send + FromStr + Encode + 'static,
155{
156 match cmd {
157 PartnerChainsSubcommand::SidechainParams(cmd) => {
158 let runner = cli.create_runner(&cmd)?;
159 runner.async_run(|config| {
160 let (client, task_manager, _) = get_deps(config)?;
161 Ok((print_result(cli_commands::get_genesis_utxo::execute(client)), task_manager))
162 })
163 },
164 PartnerChainsSubcommand::RegistrationStatus(cmd) => {
165 let runner = cli.create_runner(&cmd)?;
166 runner.async_run(move |config| {
167 let (client, task_manager, ds) = get_deps(config)?;
168 let query = SessionValidatorManagementQuery::new(client.clone(), ds.clone());
169 Ok((
170 print_result(cli_get_registration_status(
171 query,
172 cmd.mc_epoch_number,
173 cmd.stake_pool_pub_key.clone(),
174 )),
175 task_manager,
176 ))
177 })
178 },
179 PartnerChainsSubcommand::AriadneParameters(cmd) => {
180 let runner = cli.create_runner(&cmd)?;
181 runner.async_run(move |config| {
182 let (client, task_manager, ds) = get_deps(config)?;
183 let query = SessionValidatorManagementQuery::new(client.clone(), ds.clone());
184 Ok((
185 print_result(cli_get_ariadne_parameters(query, cmd.mc_epoch_number)),
186 task_manager,
187 ))
188 })
189 },
190 PartnerChainsSubcommand::RegistrationSignatures(cmd) => Ok(println!("{}", cmd.execute())),
191 PartnerChainsSubcommand::SignAddressAssociation(cmd) => {
192 cmd.execute().map_err(|e| sc_service::Error::Application(e.into()))?;
193 Ok(())
194 },
195 PartnerChainsSubcommand::SignBlockProducerMetadata(cmd) => {
196 cmd.execute::<BlockProducerMetadata>()
197 .map_err(|e| sc_service::Error::Application(e.into()))?;
198 Ok(())
199 },
200 PartnerChainsSubcommand::SmartContracts(cmd) => {
201 setup_log4rs()?;
202 Ok(cmd.execute_blocking()?)
203 },
204 PartnerChainsSubcommand::Wizards(cmd) => {
205 setup_log4rs()?;
206 Ok(cmd
207 .run(&DefaultCmdRunContext)
208 .map_err(|e| sc_cli::Error::Application(e.into()))?)
209 },
210 }
211}
212
213fn setup_log4rs() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
216 let stderr = log4rs::append::console::ConsoleAppender::builder()
217 .target(log4rs::append::console::Target::Stderr)
218 .build();
219 let ogmios_log = log4rs::append::file::FileAppender::builder().build("ogmios_client.log")?;
220
221 let log_config = log4rs::config::Config::builder()
222 .appender(log4rs::config::Appender::builder().build("stderr", Box::new(stderr)))
223 .appender(log4rs::config::Appender::builder().build("ogmios-log", Box::new(ogmios_log)))
224 .logger(
225 log4rs::config::Logger::builder()
226 .appender("ogmios-log")
227 .additive(false)
228 .build("ogmios_client::jsonrpsee", log::LevelFilter::Debug),
229 )
230 .build(log4rs::config::Root::builder().appender("stderr").build(log::LevelFilter::Info))?;
231
232 log4rs::init_config(log_config)?;
233
234 Ok(())
235}
236
237async fn print_result<FIn>(command_future: FIn) -> Result<(), sc_cli::Error>
238where
239 FIn: Future<Output = Result<String, String>>,
240{
241 let result = command_future.await.unwrap_or_else(|e| e);
242 println!("{}", result);
243 Ok(())
244}
245
246#[cfg(test)]
247mod tests {
248
249 async fn some_err() -> Result<String, String> {
250 Err("some err".to_string())
251 }
252
253 #[tokio::test]
254 async fn print_async_doesnt_fail_if_result_is_error() {
255 let result = super::print_result(some_err()).await;
256 assert!(result.is_ok());
257 }
258}