1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
use {
18
    clap::Parser,
19
    node_common::service::Sealing,
20
    sc_cli::{CliConfiguration, NodeKeyParams, SharedParams},
21
    std::path::PathBuf,
22
    url::Url,
23
};
24

            
25
/// Sub-commands supported by the collator.
26
#[derive(Debug, clap::Subcommand)]
27
#[allow(clippy::large_enum_variant)]
28
pub enum Subcommand {
29
    /// Build a chain specification.
30
    BuildSpec(BuildSpecCmd),
31

            
32
    /// Validate blocks.
33
    CheckBlock(sc_cli::CheckBlockCmd),
34

            
35
    /// Export blocks.
36
    ExportBlocks(sc_cli::ExportBlocksCmd),
37

            
38
    /// Export the state of a given block into a chain spec.
39
    ExportState(sc_cli::ExportStateCmd),
40

            
41
    /// Import blocks.
42
    ImportBlocks(sc_cli::ImportBlocksCmd),
43

            
44
    /// Revert the chain to a previous state.
45
    Revert(sc_cli::RevertCmd),
46

            
47
    /// Remove the whole chain.
48
    PurgeChain(cumulus_client_cli::PurgeChainCmd),
49

            
50
    /// Export the genesis state of the parachain.
51
    #[command(alias = "export-genesis-state")]
52
    ExportGenesisHead(cumulus_client_cli::ExportGenesisHeadCommand),
53

            
54
    /// Export the genesis wasm of the parachain.
55
    ExportGenesisWasm(cumulus_client_cli::ExportGenesisWasmCommand),
56

            
57
    /// Sub-commands concerned with benchmarking.
58
    /// The pallet benchmarking moved to the `pallet` sub-command.
59
    #[command(subcommand)]
60
    Benchmark(frame_benchmarking_cli::BenchmarkCmd),
61

            
62
    /// Precompile the WASM runtime into native code
63
    PrecompileWasm(sc_cli::PrecompileWasmCmd),
64
}
65

            
66
#[derive(Debug, Parser)]
67
#[group(skip)]
68
pub struct RunCmd {
69
    #[clap(flatten)]
70
    pub base: cumulus_client_cli::RunCmd,
71

            
72
    /// Size in bytes of the LRU cache for block data.
73
    #[arg(long, default_value = "300000000")]
74
    pub eth_log_block_cache: usize,
75

            
76
    /// Size in bytes of the LRU cache for transactions statuses data.
77
    #[arg(long, default_value = "300000000")]
78
    pub eth_statuses_cache: usize,
79

            
80
    /// Maximum number of logs in a query.
81
    #[arg(long, default_value = "10000")]
82
    pub max_past_logs: u32,
83

            
84
    /// Id of the parachain this collator collates for.
85
    #[arg(long)]
86
    pub parachain_id: Option<u32>,
87

            
88
    /// Maximum fee history cache size.
89
    #[arg(long, default_value = "2048")]
90
    pub fee_history_limit: u64,
91

            
92
    /// When blocks should be sealed in the dev service.
93
    ///
94
    /// Options are "instant", "manual", or timer interval in milliseconds
95
    #[arg(long, default_value = "instant")]
96
    pub sealing: Sealing,
97
}
98

            
99
impl std::ops::Deref for RunCmd {
100
    type Target = cumulus_client_cli::RunCmd;
101

            
102
276
    fn deref(&self) -> &Self::Target {
103
276
        &self.base
104
276
    }
105
}
106

            
107
#[derive(Debug, clap::Parser)]
108
#[command(
109
    propagate_version = true,
110
    args_conflicts_with_subcommands = true,
111
    subcommand_negates_reqs = true
112
)]
113
pub struct Cli {
114
    #[command(subcommand)]
115
    pub subcommand: Option<Subcommand>,
116

            
117
    #[command(flatten)]
118
    pub run: RunCmd,
119

            
120
    /// Disable automatic hardware benchmarks.
121
    ///
122
    /// By default these benchmarks are automatically ran at startup and measure
123
    /// the CPU speed, the memory bandwidth and the disk speed.
124
    ///
125
    /// The results are then printed out in the logs, and also sent as part of
126
    /// telemetry, if telemetry is enabled.
127
    #[arg(long)]
128
    pub no_hardware_benchmarks: bool,
129

            
130
    /// Profile id associated with the node, whose assignements will be followed to provide RPC services.
131
    #[arg(long)]
132
    pub rpc_provider_profile_id: Option<u64>,
133

            
134
    /// Endpoints to connect to orchestrator nodes, avoiding to start a local orchestrator node.
135
    /// If this list is empty, a local embeded orchestrator node is started.
136
    #[arg(long)]
137
    pub orchestrator_endpoints: Vec<Url>,
138

            
139
    /// Optional parachain id that should be used to build chain spec.
140
    #[arg(long)]
141
    pub para_id: Option<u32>,
142

            
143
    /// Relay chain arguments, optionally followed by "--" and container chain arguments
144
    #[arg(raw = true)]
145
    extra_args: Vec<String>,
146
}
147

            
148
impl Cli {
149
138
    pub fn relaychain_args(&self) -> &[String] {
150
138
        let (relay_chain_args, _) = self.split_extra_args_at_first_dashdash();
151
138

            
152
138
        relay_chain_args
153
138
    }
154

            
155
    pub fn container_chain_args(&self) -> &[String] {
156
        let (_, container_chain_args) = self.split_extra_args_at_first_dashdash();
157

            
158
        container_chain_args
159
    }
160

            
161
138
    fn split_extra_args_at_first_dashdash(&self) -> (&[String], &[String]) {
162
138
        let index_of_dashdash = self.extra_args.iter().position(|x| *x == "--");
163

            
164
138
        if let Some(i) = index_of_dashdash {
165
            let (container_chain_args, extra_extra) = self.extra_args.split_at(i);
166
            (&extra_extra[1..], container_chain_args)
167
        } else {
168
            // Only relay chain args
169
138
            (&self.extra_args, &[])
170
        }
171
138
    }
172
}
173

            
174
#[derive(Debug)]
175
pub struct RelayChainCli {
176
    /// The actual relay chain cli object.
177
    pub base: polkadot_cli::RunCmd,
178

            
179
    /// Optional chain id that should be passed to the relay chain.
180
    pub chain_id: Option<String>,
181

            
182
    /// The base path that should be used by the relay chain.
183
    pub base_path: PathBuf,
184
}
185

            
186
impl RelayChainCli {
187
    /// Parse the relay chain CLI parameters using the para chain `Configuration`.
188
138
    pub fn new<'a>(
189
138
        para_config: &sc_service::Configuration,
190
138
        relay_chain_args: impl Iterator<Item = &'a String>,
191
138
    ) -> Self {
192
138
        let extension = crate::chain_spec::Extensions::try_get(&*para_config.chain_spec);
193
138
        let chain_id = extension.map(|e| e.relay_chain.clone());
194
138
        let base_path = para_config.base_path.path().join("polkadot");
195
138
        Self {
196
138
            base_path,
197
138
            chain_id,
198
138
            base: clap::Parser::parse_from(relay_chain_args),
199
138
        }
200
138
    }
201
}
202

            
203
/// The `build-spec` command used to build a specification.
204
#[derive(Debug, Clone, clap::Parser)]
205
pub struct BuildSpecCmd {
206
    #[clap(flatten)]
207
    pub base: sc_cli::BuildSpecCmd,
208

            
209
    /// Id of the parachain this spec is for. Note that this overrides the `--chain` param.
210
    #[arg(long, conflicts_with = "chain")]
211
    #[arg(long)]
212
    pub parachain_id: Option<u32>,
213

            
214
    /// List of bootnodes to add to chain spec
215
    #[arg(long)]
216
    pub add_bootnode: Vec<String>,
217
}
218

            
219
impl CliConfiguration for BuildSpecCmd {
220
48
    fn shared_params(&self) -> &SharedParams {
221
48
        &self.base.shared_params
222
48
    }
223

            
224
4
    fn node_key_params(&self) -> Option<&NodeKeyParams> {
225
4
        Some(&self.base.node_key_params)
226
4
    }
227
}
228

            
229
#[derive(Clone)]
230
pub struct RpcConfig {
231
    pub eth_log_block_cache: usize,
232
    pub eth_statuses_cache: usize,
233
    pub fee_history_limit: u64,
234
    pub max_past_logs: u32,
235
}