Files
pezkuwi-subxt/cumulus/test/service/src/cli.rs
T
Joshy Orndorff 8683bbeefb Rename ExportGenesisStateCommand to ExportGenesisHeadCommand and make it respect custom genesis block builders (#2331)
Closes #2326.

This PR both fixes a logic bug and replaces an incorrect name.

## Bug Fix: Respecting custom genesis builder

Prior to this PR the standard logic for creating a genesis block was
repeated inside of cumulus. This PR removes that duplicated logic, and
calls into the proper `BuildGenesisBlock` implementation.

One consequence is that if the genesis block has already been
initialized, it will not be re-created, but rather read from the
database like it is for other node invocations. So you need to watch out
for old unpurged data during the development process. Offchain tools may
need to be updated accordingly. I've already filed
https://github.com/paritytech/zombienet/issues/1519

## Rename: It doesn't export state. It exports head data.

The name export-genesis-state was always wrong, nad it's never too late
to right a wrong. I've changed the name of the struct to
`ExportGenesisHeadCommand`.

There is still the question of what to do with individual nodes' public
CLIs. I have updated the parachain template to a reasonable default that
preserves compatibility with tools that will expect
`export-genesis-state` to still work. And I've chosen not to modify the
public CLIs of any other nodes in the repo. I'll leave it up to their
individual owners/maintains to decide whether that is appropriate.

---------

Co-authored-by: Joshy Orndorff <git-user-email.h0ly5@simplelogin.com>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Bastian Köcher <info@kchr.de>
2023-12-13 11:18:33 +02:00

307 lines
7.6 KiB
Rust

// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.
use std::{net::SocketAddr, path::PathBuf};
use cumulus_client_cli::{ExportGenesisHeadCommand, ExportGenesisWasmCommand};
use polkadot_service::{ChainSpec, ParaId, PrometheusConfig};
use sc_cli::{
CliConfiguration, DefaultConfigurationValues, ImportParams, KeystoreParams, NetworkParams,
Result as CliResult, SharedParams, SubstrateCli,
};
use sc_service::BasePath;
#[derive(Debug, clap::Parser)]
#[command(
version,
propagate_version = true,
args_conflicts_with_subcommands = true,
subcommand_negates_reqs = true
)]
pub struct TestCollatorCli {
#[command(subcommand)]
pub subcommand: Option<Subcommand>,
#[command(flatten)]
pub run: cumulus_client_cli::RunCmd,
#[arg(default_value_t = 2000u32)]
pub parachain_id: u32,
/// Relay chain arguments
#[arg(raw = true)]
pub relaychain_args: Vec<String>,
#[arg(long)]
pub use_null_consensus: bool,
#[arg(long)]
pub disable_block_announcements: bool,
#[arg(long)]
pub fail_pov_recovery: bool,
}
#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
/// Build a chain specification.
BuildSpec(sc_cli::BuildSpecCmd),
/// Export the genesis state of the parachain.
#[command(alias = "export-genesis-state")]
ExportGenesisHead(ExportGenesisHeadCommand),
/// Export the genesis wasm of the parachain.
ExportGenesisWasm(ExportGenesisWasmCommand),
}
#[derive(Debug)]
pub struct RelayChainCli {
/// The actual relay chain cli object.
pub base: polkadot_cli::RunCmd,
/// Optional chain id that should be passed to the relay chain.
pub chain_id: Option<String>,
/// The base path that should be used by the relay chain.
pub base_path: Option<PathBuf>,
}
impl RelayChainCli {
/// Parse the relay chain CLI parameters using the para chain `Configuration`.
pub fn new<'a>(
para_config: &sc_service::Configuration,
relay_chain_args: impl Iterator<Item = &'a String>,
) -> Self {
let base_path = para_config.base_path.path().join("polkadot");
Self {
base_path: Some(base_path),
chain_id: None,
base: clap::Parser::parse_from(relay_chain_args),
}
}
}
impl CliConfiguration<Self> for RelayChainCli {
fn shared_params(&self) -> &SharedParams {
self.base.base.shared_params()
}
fn import_params(&self) -> Option<&ImportParams> {
self.base.base.import_params()
}
fn network_params(&self) -> Option<&NetworkParams> {
self.base.base.network_params()
}
fn keystore_params(&self) -> Option<&KeystoreParams> {
self.base.base.keystore_params()
}
fn base_path(&self) -> CliResult<Option<BasePath>> {
Ok(self
.shared_params()
.base_path()?
.or_else(|| self.base_path.clone().map(Into::into)))
}
fn rpc_addr(&self, default_listen_port: u16) -> CliResult<Option<SocketAddr>> {
self.base.base.rpc_addr(default_listen_port)
}
fn prometheus_config(
&self,
default_listen_port: u16,
chain_spec: &Box<dyn ChainSpec>,
) -> CliResult<Option<PrometheusConfig>> {
self.base.base.prometheus_config(default_listen_port, chain_spec)
}
fn init<F>(
&self,
_support_url: &String,
_impl_version: &String,
_logger_hook: F,
_config: &sc_service::Configuration,
) -> CliResult<()>
where
F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration),
{
unreachable!("PolkadotCli is never initialized; qed");
}
fn chain_id(&self, is_dev: bool) -> CliResult<String> {
let chain_id = self.base.base.chain_id(is_dev)?;
Ok(if chain_id.is_empty() { self.chain_id.clone().unwrap_or_default() } else { chain_id })
}
fn role(&self, is_dev: bool) -> CliResult<sc_service::Role> {
self.base.base.role(is_dev)
}
fn transaction_pool(
&self,
is_dev: bool,
) -> CliResult<sc_service::config::TransactionPoolOptions> {
self.base.base.transaction_pool(is_dev)
}
fn trie_cache_maximum_size(&self) -> CliResult<Option<usize>> {
self.base.base.trie_cache_maximum_size()
}
fn rpc_methods(&self) -> CliResult<sc_service::config::RpcMethods> {
self.base.base.rpc_methods()
}
fn rpc_max_connections(&self) -> CliResult<u32> {
self.base.base.rpc_max_connections()
}
fn rpc_cors(&self, is_dev: bool) -> CliResult<Option<Vec<String>>> {
self.base.base.rpc_cors(is_dev)
}
fn default_heap_pages(&self) -> CliResult<Option<u64>> {
self.base.base.default_heap_pages()
}
fn force_authoring(&self) -> CliResult<bool> {
self.base.base.force_authoring()
}
fn disable_grandpa(&self) -> CliResult<bool> {
self.base.base.disable_grandpa()
}
fn max_runtime_instances(&self) -> CliResult<Option<usize>> {
self.base.base.max_runtime_instances()
}
fn announce_block(&self) -> CliResult<bool> {
self.base.base.announce_block()
}
fn telemetry_endpoints(
&self,
chain_spec: &Box<dyn ChainSpec>,
) -> CliResult<Option<sc_telemetry::TelemetryEndpoints>> {
self.base.base.telemetry_endpoints(chain_spec)
}
fn node_name(&self) -> CliResult<String> {
self.base.base.node_name()
}
}
impl DefaultConfigurationValues for RelayChainCli {
fn p2p_listen_port() -> u16 {
30334
}
fn rpc_listen_port() -> u16 {
9945
}
fn prometheus_listen_port() -> u16 {
9616
}
}
impl SubstrateCli for TestCollatorCli {
fn impl_name() -> String {
"Cumulus zombienet test parachain".into()
}
fn impl_version() -> String {
String::new()
}
fn description() -> String {
format!(
"Cumulus zombienet test parachain\n\nThe command-line arguments provided first will be \
passed to the parachain node, while the arguments provided after -- will be passed \
to the relaychain node.\n\n\
{} [parachain-args] -- [relaychain-args]",
Self::executable_name()
)
}
fn author() -> String {
env!("CARGO_PKG_AUTHORS").into()
}
fn support_url() -> String {
"https://github.com/paritytech/polkadot-sdk/issues/new".into()
}
fn copyright_start_year() -> i32 {
2017
}
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
Ok(match id {
"" => Box::new(cumulus_test_service::get_chain_spec(Some(ParaId::from(
self.parachain_id,
)))) as Box<_>,
path => {
let chain_spec =
cumulus_test_service::chain_spec::ChainSpec::from_json_file(path.into())?;
Box::new(chain_spec)
},
})
}
}
impl SubstrateCli for RelayChainCli {
fn impl_name() -> String {
"Polkadot collator".into()
}
fn impl_version() -> String {
String::new()
}
fn description() -> String {
format!(
"Polkadot collator\n\nThe command-line arguments provided first will be \
passed to the parachain node, while the arguments provided after -- will be passed \
to the relay chain node.\n\n\
{} [parachain-args] -- [relay_chain-args]",
Self::executable_name()
)
}
fn author() -> String {
env!("CARGO_PKG_AUTHORS").into()
}
fn support_url() -> String {
"https://github.com/paritytech/polkadot-sdk/issues/new".into()
}
fn copyright_start_year() -> i32 {
2017
}
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
<polkadot_cli::Cli as SubstrateCli>::from_iter([RelayChainCli::executable_name()].iter())
.load_spec(id)
}
}