diff --git a/Cargo.lock b/Cargo.lock index 2145a870e75c9..1707bb505b98f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12450,7 +12450,6 @@ dependencies = [ "sp-runtime", "substrate-build-script-utils", "thiserror", - "try-runtime-cli", ] [[package]] @@ -18638,7 +18637,6 @@ dependencies = [ "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", - "try-runtime-cli", ] [[package]] @@ -19905,7 +19903,6 @@ dependencies = [ "tempfile", "tokio", "tokio-util", - "try-runtime-cli", "wait-timeout", "wat", ] @@ -21483,47 +21480,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "try-runtime-cli" -version = "0.38.0" -dependencies = [ - "assert_cmd", - "async-trait", - "clap 4.5.3", - "frame-remote-externalities", - "frame-try-runtime", - "hex", - "log", - "node-primitives", - "parity-scale-codec", - "regex", - "sc-cli", - "sc-executor", - "serde", - "serde_json", - "sp-api", - "sp-consensus-aura", - "sp-consensus-babe", - "sp-core", - "sp-debug-derive 14.0.0", - "sp-externalities 0.25.0", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-rpc", - "sp-runtime", - "sp-state-machine", - "sp-timestamp", - "sp-transaction-storage-proof", - "sp-version", - "sp-weights", - "substrate-cli-test-utils", - "substrate-rpc-client", - "tempfile", - "tokio", - "zstd 0.12.4", -] - [[package]] name = "trybuild" version = "1.0.89" diff --git a/Cargo.toml b/Cargo.toml index 52431a9cefeaf..862419e973085 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -498,7 +498,6 @@ members = [ "substrate/utils/frame/rpc/state-trie-migration-rpc", "substrate/utils/frame/rpc/support", "substrate/utils/frame/rpc/system", - "substrate/utils/frame/try-runtime/cli", "substrate/utils/prometheus", "substrate/utils/substrate-bip39", "substrate/utils/wasm-builder", diff --git a/cumulus/polkadot-parachain/src/cli.rs b/cumulus/polkadot-parachain/src/cli.rs index fec6e144e40f1..f7d2fd0f0be3c 100644 --- a/cumulus/polkadot-parachain/src/cli.rs +++ b/cumulus/polkadot-parachain/src/cli.rs @@ -55,11 +55,6 @@ pub enum Subcommand { /// The pallet benchmarking moved to the `pallet` sub-command. #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - - /// Try-runtime has migrated to a standalone - /// [CLI](). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, } const AFTER_HELP_EXAMPLE: &str = color_print::cstr!( diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index a897c7c534da7..ce0fea60d8957 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -549,9 +549,8 @@ pub fn run() -> Result<()> { }, Some(Subcommand::ExportGenesisHead(cmd)) => { let runner = cli.create_runner(cmd)?; - runner.sync_run(|config| { - construct_partials!(config, |partials| cmd.run(partials.client)) - }) + runner + .sync_run(|config| construct_partials!(config, |partials| cmd.run(partials.client))) }, Some(Subcommand::ExportGenesisWasm(cmd)) => { let runner = cli.create_runner(cmd)?; @@ -601,7 +600,6 @@ pub fn run() -> Result<()> { _ => Err("Benchmarking sub-command unsupported".into()), } }, - Some(Subcommand::TryRuntime) => Err("The `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI.".into()), Some(Subcommand::Key(cmd)) => Ok(cmd.run(&cli)?), None => { let runner = cli.create_runner(&cli.run.normalize())?; diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index b0c22c5a97fe8..719d00490a9d0 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -33,7 +33,6 @@ sp-io = { path = "../../substrate/primitives/io" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-maybe-compressed-blob = { path = "../../substrate/primitives/maybe-compressed-blob" } frame-benchmarking-cli = { path = "../../substrate/utils/frame/benchmarking-cli", optional = true } -try-runtime-cli = { path = "../../substrate/utils/frame/try-runtime/cli", optional = true } sc-cli = { path = "../../substrate/client/cli", optional = true } sc-service = { path = "../../substrate/client/service", optional = true } polkadot-node-metrics = { path = "../node/metrics" } @@ -57,7 +56,6 @@ cli = [ "sc-service", "sc-tracing", "service", - "try-runtime-cli", ] runtime-benchmarks = [ "frame-benchmarking-cli?/runtime-benchmarks", @@ -70,7 +68,6 @@ full-node = ["service/full-node"] try-runtime = [ "service/try-runtime", "sp-runtime/try-runtime", - "try-runtime-cli/try-runtime", ] fast-runtime = ["service/fast-runtime"] pyroscope = ["pyro", "pyroscope_pprofrs"] diff --git a/polkadot/cli/src/cli.rs b/polkadot/cli/src/cli.rs index 74e1904446931..3737942e6e53f 100644 --- a/polkadot/cli/src/cli.rs +++ b/polkadot/cli/src/cli.rs @@ -50,11 +50,6 @@ pub enum Subcommand { #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Try-runtime has migrated to a standalone CLI - /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, - /// Key management CLI utilities #[command(subcommand)] Key(sc_cli::KeySubcommand), diff --git a/polkadot/cli/src/command.rs b/polkadot/cli/src/command.rs index b163a2c1367db..6af93a7563889 100644 --- a/polkadot/cli/src/command.rs +++ b/polkadot/cli/src/command.rs @@ -476,13 +476,6 @@ pub fn run() -> Result<()> { } }, Some(Subcommand::Key(cmd)) => Ok(cmd.run(&cli)?), - #[cfg(feature = "try-runtime")] - Some(Subcommand::TryRuntime) => Err(try_runtime_cli::DEPRECATION_NOTICE.to_owned().into()), - #[cfg(not(feature = "try-runtime"))] - Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ - You can enable it with `--features try-runtime`." - .to_owned() - .into()), Some(Subcommand::ChainInfo(cmd)) => { let runner = cli.create_runner(cmd)?; Ok(runner.sync_run(|config| cmd.run::(&config))?) diff --git a/prdoc/pr_4017.prdoc b/prdoc/pr_4017.prdoc new file mode 100644 index 0000000000000..9e83d5d1642a6 --- /dev/null +++ b/prdoc/pr_4017.prdoc @@ -0,0 +1,15 @@ +title: Complete removal of `TryRuntime` subcommand + +doc: + - audience: Node Operator + description: | + The deprecated `try-runtime` subcommand and `try-runtime-cli` crate has been completely removed. + If you are not already, you should be using the standalone CLI at https://github.com/paritytech/try-runtime-cli. + +crates: + - name: polkadot-parachain-bin + bump: patch + - name: polkadot-cli + bump: patch + - name: staging-node-cli + bump: patch diff --git a/substrate/bin/node/cli/Cargo.toml b/substrate/bin/node/cli/Cargo.toml index 09fa64d589487..e6f754fa40b1b 100644 --- a/substrate/bin/node/cli/Cargo.toml +++ b/substrate/bin/node/cli/Cargo.toml @@ -116,7 +116,6 @@ node-primitives = { path = "../primitives" } sc-cli = { path = "../../../client/cli", optional = true } frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } node-inspect = { package = "staging-node-inspect", path = "../inspect", optional = true } -try-runtime-cli = { path = "../../../utils/frame/try-runtime/cli", optional = true } serde_json = { workspace = true, default-features = true } [dev-dependencies] @@ -172,7 +171,6 @@ node-inspect = { package = "staging-node-inspect", path = "../inspect", optional frame-benchmarking-cli = { path = "../../../utils/frame/benchmarking-cli", optional = true } substrate-build-script-utils = { path = "../../../utils/build-script-utils", optional = true } substrate-frame-cli = { path = "../../../utils/frame/frame-utilities-cli", optional = true } -try-runtime-cli = { path = "../../../utils/frame/try-runtime/cli", optional = true } sc-cli = { path = "../../../client/cli", optional = true } pallet-balances = { path = "../../../frame/balances" } sc-storage-monitor = { path = "../../../client/storage-monitor" } @@ -188,7 +186,6 @@ cli = [ "sc-service/rocksdb", "substrate-build-script-utils", "substrate-frame-cli", - "try-runtime-cli", ] runtime-benchmarks = [ "frame-benchmarking-cli/runtime-benchmarks", @@ -232,7 +229,6 @@ try-runtime = [ "pallet-treasury/try-runtime", "sp-runtime/try-runtime", "substrate-cli-test-utils/try-runtime", - "try-runtime-cli/try-runtime", ] [[bench]] diff --git a/substrate/bin/node/cli/src/cli.rs b/substrate/bin/node/cli/src/cli.rs index 56fbed51f8a45..1d1af6e03e9e6 100644 --- a/substrate/bin/node/cli/src/cli.rs +++ b/substrate/bin/node/cli/src/cli.rs @@ -61,11 +61,6 @@ pub enum Subcommand { #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Try-runtime has migrated to a standalone CLI - /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, - /// Key management cli utilities #[command(subcommand)] Key(sc_cli::KeySubcommand), diff --git a/substrate/bin/node/cli/src/command.rs b/substrate/bin/node/cli/src/command.rs index d37325c7187e6..d869b77e91228 100644 --- a/substrate/bin/node/cli/src/command.rs +++ b/substrate/bin/node/cli/src/command.rs @@ -221,12 +221,6 @@ pub fn run() -> Result<()> { Ok((cmd.run(client, backend, Some(aux_revert)), task_manager)) }) }, - #[cfg(feature = "try-runtime")] - Some(Subcommand::TryRuntime) => Err(try_runtime_cli::DEPRECATION_NOTICE.into()), - #[cfg(not(feature = "try-runtime"))] - Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ - You can enable it with `--features try-runtime`." - .into()), Some(Subcommand::ChainInfo(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| cmd.run::(&config)) diff --git a/substrate/utils/frame/try-runtime/cli/Cargo.toml b/substrate/utils/frame/try-runtime/cli/Cargo.toml deleted file mode 100644 index 618cb645475d7..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/Cargo.toml +++ /dev/null @@ -1,63 +0,0 @@ -[package] -name = "try-runtime-cli" -version = "0.38.0" -authors.workspace = true -edition.workspace = true -license = "Apache-2.0" -homepage = "https://substrate.io" -repository.workspace = true -description = "Cli command runtime testing and dry-running" - -[lints] -workspace = true - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -remote-externalities = { package = "frame-remote-externalities", path = "../../remote-externalities" } -sc-cli = { path = "../../../../client/cli" } -sc-executor = { path = "../../../../client/executor" } -sp-consensus-aura = { path = "../../../../primitives/consensus/aura" } -sp-consensus-babe = { path = "../../../../primitives/consensus/babe" } -sp-core = { path = "../../../../primitives/core" } -sp-externalities = { path = "../../../../primitives/externalities" } -sp-inherents = { path = "../../../../primitives/inherents" } -sp-io = { path = "../../../../primitives/io" } -sp-keystore = { path = "../../../../primitives/keystore" } -sp-runtime = { path = "../../../../primitives/runtime" } -sp-rpc = { path = "../../../../primitives/rpc" } -sp-state-machine = { path = "../../../../primitives/state-machine" } -sp-timestamp = { path = "../../../../primitives/timestamp" } -sp-transaction-storage-proof = { path = "../../../../primitives/transaction-storage-proof" } -sp-version = { path = "../../../../primitives/version" } -sp-debug-derive = { path = "../../../../primitives/debug-derive" } -sp-api = { path = "../../../../primitives/api" } -sp-weights = { path = "../../../../primitives/weights" } -frame-try-runtime = { path = "../../../../frame/try-runtime", optional = true } -substrate-rpc-client = { path = "../../rpc/client" } - -async-trait = "0.1.79" -clap = { version = "4.5.3", features = ["derive"] } -hex = { version = "0.4.3", default-features = false } -log = { workspace = true, default-features = true } -parity-scale-codec = "3.6.1" -serde = { workspace = true, default-features = true } -serde_json = { workspace = true, default-features = true } -zstd = { version = "0.12.4", default-features = false } - -[dev-dependencies] -assert_cmd = "2.0.10" -node-primitives = { path = "../../../../bin/node/primitives" } -regex = "1.7.3" -substrate-cli-test-utils = { path = "../../../../test-utils/cli" } -tempfile = "3.1.0" -tokio = "1.37" - -[features] -try-runtime = [ - "frame-try-runtime/try-runtime", - "sp-debug-derive/force-debug", - "sp-runtime/try-runtime", - "substrate-cli-test-utils/try-runtime", -] diff --git a/substrate/utils/frame/try-runtime/cli/src/block_building_info.rs b/substrate/utils/frame/try-runtime/cli/src/block_building_info.rs deleted file mode 100644 index db24d06ef0a15..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/block_building_info.rs +++ /dev/null @@ -1,152 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::BlockT; -use parity_scale_codec::Encode; -use sc_cli::Result; -use sp_consensus_aura::{Slot, SlotDuration, AURA_ENGINE_ID}; -use sp_consensus_babe::{ - digests::{PreDigest, SecondaryPlainPreDigest}, - BABE_ENGINE_ID, -}; -use sp_inherents::{InherentData, InherentDataProvider}; -use sp_runtime::{Digest, DigestItem}; -use sp_timestamp::TimestampInherentData; - -/// Something that can create inherent data providers and pre-runtime digest. -/// -/// It is possible for the caller to provide custom arguments to the callee by setting the -/// `ExtraArgs` generic parameter. -/// -/// This module already provides some convenience implementation of this trait for closures. So, it -/// should not be required to implement it directly. -#[async_trait::async_trait] -pub trait BlockBuildingInfoProvider { - type InherentDataProviders: InherentDataProvider; - - async fn get_inherent_providers_and_pre_digest( - &self, - parent_hash: Block::Hash, - extra_args: ExtraArgs, - ) -> Result<(Self::InherentDataProviders, Vec)>; -} - -#[async_trait::async_trait] -impl BlockBuildingInfoProvider for F -where - Block: BlockT, - F: Fn(Block::Hash, ExtraArgs) -> Fut + Sync + Send, - Fut: std::future::Future)>> + Send + 'static, - IDP: InherentDataProvider + 'static, - ExtraArgs: Send + 'static, -{ - type InherentDataProviders = IDP; - - async fn get_inherent_providers_and_pre_digest( - &self, - parent: Block::Hash, - extra_args: ExtraArgs, - ) -> Result<(Self::InherentDataProviders, Vec)> { - (*self)(parent, extra_args).await - } -} - -/// Provides [`BlockBuildingInfoProvider`] implementation for chains that include timestamp inherent -/// and use Aura for a block production. -/// -/// It depends only on the expected block production frequency, i.e. `blocktime_millis`. -pub fn timestamp_with_aura_info( - blocktime_millis: u64, -) -> impl BlockBuildingInfoProvider> { - move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move { - let timestamp_idp = match maybe_prev_info { - Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new( - inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis, - ), - None => sp_timestamp::InherentDataProvider::from_system_time(), - }; - - let slot = - Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis)); - let digest = vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())]; - - Ok((timestamp_idp, digest)) - } -} - -/// Provides [`BlockBuildingInfoProvider`] implementation for chains that include timestamp inherent -/// and use Babe for a block production. -/// -/// It depends only on the expected block production frequency, i.e. `blocktime_millis`. -pub fn timestamp_with_babe_info( - blocktime_millis: u64, -) -> impl BlockBuildingInfoProvider> { - move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move { - let timestamp_idp = match maybe_prev_info { - Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new( - inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis, - ), - None => sp_timestamp::InherentDataProvider::from_system_time(), - }; - - let slot = - Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis)); - let slot_idp = sp_consensus_babe::inherents::InherentDataProvider::new(slot); - - let digest = vec![DigestItem::PreRuntime( - BABE_ENGINE_ID, - PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 0 }) - .encode(), - )]; - - Ok(((slot_idp, timestamp_idp), digest)) - } -} - -/// Provides [`BlockBuildingInfoProvider`] implementation for chains that use: -/// - timestamp inherent, -/// - Babe for a block production (inherent + digest), -/// - uncles inherent, -/// - storage proof inherent -/// -/// It depends only on the expected block production frequency, i.e. `blocktime_millis`. -pub fn substrate_info( - blocktime_millis: u64, -) -> impl BlockBuildingInfoProvider> { - move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move { - let timestamp_idp = match maybe_prev_info { - Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new( - inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis, - ), - None => sp_timestamp::InherentDataProvider::from_system_time(), - }; - - let slot = - Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis)); - let slot_idp = sp_consensus_babe::inherents::InherentDataProvider::new(slot); - - let storage_proof_idp = sp_transaction_storage_proof::InherentDataProvider::new(None); - - let digest = vec![DigestItem::PreRuntime( - BABE_ENGINE_ID, - PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 0 }) - .encode(), - )]; - - Ok(((slot_idp, timestamp_idp, storage_proof_idp), digest)) - } -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/create_snapshot.rs b/substrate/utils/frame/try-runtime/cli/src/commands/create_snapshot.rs deleted file mode 100644 index 102336d644219..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/create_snapshot.rs +++ /dev/null @@ -1,78 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{build_executor, LiveState, SharedParams, State, LOG_TARGET}; -use sc_executor::sp_wasm_interface::HostFunctions; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use std::{fmt::Debug, str::FromStr}; -use substrate_rpc_client::{ws_client, StateApi}; - -/// Configurations of the [`crate::Command::CreateSnapshot`]. -#[derive(Debug, Clone, clap::Parser)] -pub struct CreateSnapshotCmd { - /// The source of the snapshot. Must be a remote node. - #[clap(flatten)] - pub from: LiveState, - - /// The snapshot path to write to. - /// - /// If not provided `-@.snap` will be used. - pub snapshot_path: Option, -} - -/// inner command for `Command::CreateSnapshot`. -pub(crate) async fn create_snapshot( - shared: SharedParams, - command: CreateSnapshotCmd, -) -> sc_cli::Result<()> -where - Block: BlockT + serde::de::DeserializeOwned, - Block::Hash: serde::de::DeserializeOwned, - Block::Header: serde::de::DeserializeOwned, - ::Err: Debug, - NumberFor: FromStr, - as FromStr>::Err: Debug, - HostFns: HostFunctions, -{ - let snapshot_path = command.snapshot_path; - if !matches!(shared.runtime, crate::Runtime::Existing) { - return Err("creating a snapshot is only possible with --runtime existing.".into()) - } - - let path = match snapshot_path { - Some(path) => path, - None => { - let rpc = ws_client(&command.from.uri).await.unwrap(); - let remote_spec = StateApi::::runtime_version(&rpc, None).await.unwrap(); - let path_str = format!( - "{}-{}@{}.snap", - remote_spec.spec_name.to_lowercase(), - remote_spec.spec_version, - command.from.at.clone().unwrap_or("latest".to_owned()) - ); - log::info!(target: LOG_TARGET, "snapshot path not provided (-s), using '{}'", path_str); - path_str.into() - }, - }; - - let executor = build_executor::(&shared); - let _ = State::Live(command.from) - .into_ext::(&shared, &executor, Some(path.into()), false) - .await?; - - Ok(()) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/execute_block.rs b/substrate/utils/frame/try-runtime/cli/src/commands/execute_block.rs deleted file mode 100644 index 1f1b6ec7d9b91..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/execute_block.rs +++ /dev/null @@ -1,170 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{ - build_executor, full_extensions, rpc_err_handler, state_machine_call_with_proof, LiveState, - SharedParams, State, LOG_TARGET, -}; -use parity_scale_codec::Encode; -use sc_executor::sp_wasm_interface::HostFunctions; -use sp_rpc::{list::ListOrValue, number::NumberOrHex}; -use sp_runtime::{ - generic::SignedBlock, - traits::{Block as BlockT, Header as HeaderT, NumberFor}, -}; -use std::{fmt::Debug, str::FromStr}; -use substrate_rpc_client::{ws_client, ChainApi}; - -/// Configurations of the [`crate::Command::ExecuteBlock`]. -/// -/// This will always call into `TryRuntime_execute_block`, which can optionally skip the state-root -/// check (useful for trying a unreleased runtime), and can execute runtime sanity checks as well. -#[derive(Debug, Clone, clap::Parser)] -pub struct ExecuteBlockCmd { - /// Which try-state targets to execute when running this command. - /// - /// Expected values: - /// - `all` - /// - `none` - /// - A comma separated list of pallets, as per pallet names in `construct_runtime!()` (e.g. - /// `Staking, System`). - /// - `rr-[x]` where `[x]` is a number. Then, the given number of pallets are checked in a - /// round-robin fashion. - #[arg(long, default_value = "all")] - pub try_state: frame_try_runtime::TryStateSelect, - - /// The ws uri from which to fetch the block. - /// - /// This will always fetch the next block of whatever `state` is referring to, because this is - /// the only sensible combination. In other words, if you have the state of block `n`, you - /// should execute block `n+1` on top of it. - /// - /// If `state` is `Live`, this can be ignored and the same uri is used for both. - #[arg( - long, - value_parser = crate::parse::url - )] - pub block_ws_uri: Option, - - /// The state type to use. - #[command(subcommand)] - pub state: State, -} - -impl ExecuteBlockCmd { - fn block_ws_uri(&self) -> String - where - ::Err: Debug, - { - match (&self.block_ws_uri, &self.state) { - (Some(block_ws_uri), State::Snap { .. }) => block_ws_uri.to_owned(), - (Some(block_ws_uri), State::Live { .. }) => { - log::error!(target: LOG_TARGET, "--block-uri is provided while state type is live, Are you sure you know what you are doing?"); - block_ws_uri.to_owned() - }, - (None, State::Live(LiveState { uri, .. })) => uri.clone(), - (None, State::Snap { .. }) => { - panic!("either `--block-uri` must be provided, or state must be `live`"); - }, - } - } -} - -pub(crate) async fn execute_block( - shared: SharedParams, - command: ExecuteBlockCmd, -) -> sc_cli::Result<()> -where - Block: BlockT + serde::de::DeserializeOwned, - ::Err: Debug, - Block::Hash: serde::de::DeserializeOwned, - Block::Header: serde::de::DeserializeOwned, - as TryInto>::Error: Debug, - HostFns: HostFunctions, -{ - let executor = build_executor::(&shared); - let ext = command.state.into_ext::(&shared, &executor, None, true).await?; - - // get the block number associated with this block. - let block_ws_uri = command.block_ws_uri::(); - let rpc = ws_client(&block_ws_uri).await?; - let next_hash = next_hash_of::(&rpc, ext.block_hash).await?; - - log::info!(target: LOG_TARGET, "fetching next block: {:?} ", next_hash); - - let block = ChainApi::<(), Block::Hash, Block::Header, SignedBlock>::block( - &rpc, - Some(next_hash), - ) - .await - .map_err(rpc_err_handler)? - .expect("header exists, block should also exist; qed") - .block; - - // A digest item gets added when the runtime is processing the block, so we need to pop - // the last one to be consistent with what a gossiped block would contain. - let (mut header, extrinsics) = block.deconstruct(); - header.digest_mut().pop(); - let block = Block::new(header, extrinsics); - - // for now, hardcoded for the sake of simplicity. We might customize them one day. - let state_root_check = false; - let signature_check = false; - let payload = (block.clone(), state_root_check, signature_check, command.try_state).encode(); - - let _ = state_machine_call_with_proof::( - &ext, - &executor, - "TryRuntime_execute_block", - &payload, - full_extensions(executor.clone()), - shared.export_proof, - )?; - - Ok(()) -} - -pub(crate) async fn next_hash_of( - rpc: &substrate_rpc_client::WsClient, - hash: Block::Hash, -) -> sc_cli::Result -where - Block: BlockT + serde::de::DeserializeOwned, - Block::Header: serde::de::DeserializeOwned, -{ - let number = ChainApi::<(), Block::Hash, Block::Header, ()>::header(rpc, Some(hash)) - .await - .map_err(rpc_err_handler) - .and_then(|maybe_header| maybe_header.ok_or("header_not_found").map(|h| *h.number()))?; - - let next = number + sp_runtime::traits::One::one(); - - let next_hash = match ChainApi::<(), Block::Hash, Block::Header, ()>::block_hash( - rpc, - Some(ListOrValue::Value(NumberOrHex::Number( - next.try_into().map_err(|_| "failed to convert number to block number")?, - ))), - ) - .await - .map_err(rpc_err_handler)? - { - ListOrValue::Value(t) => t.expect("value passed in; value comes out; qed"), - _ => unreachable!(), - }; - - Ok(next_hash) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/fast_forward.rs b/substrate/utils/frame/try-runtime/cli/src/commands/fast_forward.rs deleted file mode 100644 index f1dee16debe73..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/fast_forward.rs +++ /dev/null @@ -1,262 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{ - block_building_info::BlockBuildingInfoProvider, build_executor, full_extensions, - rpc_err_handler, state_machine_call, BlockT, LiveState, SharedParams, State, -}; -use parity_scale_codec::{Decode, Encode}; -use sc_cli::Result; -use sc_executor::{sp_wasm_interface::HostFunctions, WasmExecutor}; -use serde::de::DeserializeOwned; -use sp_core::H256; -use sp_inherents::{InherentData, InherentDataProvider}; -use sp_runtime::{ - traits::{HashingFor, Header, NumberFor, One}, - Digest, -}; -use sp_state_machine::TestExternalities; -use std::{fmt::Debug, str::FromStr}; -use substrate_rpc_client::{ws_client, ChainApi}; - -/// Configurations of the [`crate::Command::FastForward`]. -#[derive(Debug, Clone, clap::Parser)] -pub struct FastForwardCmd { - /// How many blocks should be processed. If `None`, then blocks will be produced and processed - /// in a loop. - #[arg(long)] - n_blocks: Option, - - /// The state type to use. - #[command(subcommand)] - state: State, - - /// The ws uri from which to fetch the block. - /// - /// If `state` is `Live`, this is ignored. Otherwise, it must not be empty. - #[arg(long, value_parser = crate::parse::url)] - block_ws_uri: Option, - - /// Which try-state targets to execute when running this command. - /// - /// Expected values: - /// - `all` - /// - `none` - /// - A comma separated list of pallets, as per pallet names in `construct_runtime!()` (e.g. - /// `Staking, System`). - /// - `rr-[x]` where `[x]` is a number. Then, the given number of pallets are checked in a - /// round-robin fashion. - #[arg(long, default_value = "all")] - try_state: frame_try_runtime::TryStateSelect, -} - -impl FastForwardCmd { - fn block_ws_uri(&self) -> &str { - match self.state { - State::Live(LiveState { ref uri, .. }) => &uri, - _ => self - .block_ws_uri - .as_ref() - .expect("Either `--block-uri` must be provided, or state must be `live`"), - } - } -} - -/// Read the block number corresponding to `hash` with an RPC call to `ws_uri`. -async fn get_block_number( - hash: Block::Hash, - ws_uri: &str, -) -> Result> -where - Block::Header: DeserializeOwned, -{ - let rpc = ws_client(ws_uri).await?; - Ok(ChainApi::<(), Block::Hash, Block::Header, ()>::header(&rpc, Some(hash)) - .await - .map_err(rpc_err_handler) - .and_then(|maybe_header| maybe_header.ok_or("header_not_found").map(|h| *h.number()))?) -} - -/// Call `method` with `data` and return the result. `externalities` will not change. -fn dry_run( - externalities: &TestExternalities>, - executor: &WasmExecutor, - method: &'static str, - data: &[u8], -) -> Result { - let (_, result) = state_machine_call::( - externalities, - executor, - method, - data, - full_extensions(executor.clone()), - )?; - - Ok(::decode(&mut &*result)?) -} - -/// Call `method` with `data` and actually save storage changes to `externalities`. -async fn run( - externalities: &mut TestExternalities>, - executor: &WasmExecutor, - method: &'static str, - data: &[u8], -) -> Result<()> { - let (mut changes, _) = state_machine_call::( - externalities, - executor, - method, - data, - full_extensions(executor.clone()), - )?; - - let storage_changes = - changes.drain_storage_changes(&externalities.backend, externalities.state_version)?; - - externalities - .backend - .apply_transaction(storage_changes.transaction_storage_root, storage_changes.transaction); - - Ok(()) -} - -/// Produce next empty block. -async fn next_empty_block< - Block: BlockT, - HostFns: HostFunctions, - BBIP: BlockBuildingInfoProvider>, ->( - externalities: &mut TestExternalities>, - executor: &WasmExecutor, - parent_height: NumberFor, - parent_hash: Block::Hash, - block_building_info_provider: &Option, - previous_block_building_info: Option<(InherentData, Digest)>, -) -> Result<(Block, Option<(InherentData, Digest)>)> { - let (maybe_inherent_data, pre_digest) = match &block_building_info_provider { - None => (None, Default::default()), - Some(bbip) => { - let (inherent_data_provider, pre_digest) = bbip - .get_inherent_providers_and_pre_digest(parent_hash, previous_block_building_info) - .await?; - let inherent_data = inherent_data_provider - .create_inherent_data() - .await - .map_err(|e| sc_cli::Error::Input(format!("I don't know how to convert {e:?}")))?; - - (Some(inherent_data), Digest { logs: pre_digest }) - }, - }; - - let header = Block::Header::new( - parent_height + One::one(), - Default::default(), - Default::default(), - parent_hash, - pre_digest.clone(), - ); - let mut extrinsics = >::new(); - - run::(externalities, executor, "Core_initialize_block", &header.encode()).await?; - - if let Some(ref inherent_data) = maybe_inherent_data { - extrinsics = dry_run::, Block, _>( - externalities, - executor, - "BlockBuilder_inherent_extrinsics", - &inherent_data.encode(), - )?; - } - - for xt in &extrinsics { - run::(externalities, executor, "BlockBuilder_apply_extrinsic", &xt.encode()) - .await?; - } - - let header = dry_run::( - externalities, - executor, - "BlockBuilder_finalize_block", - &[0u8; 0], - )?; - - run::(externalities, executor, "BlockBuilder_finalize_block", &[0u8; 0]).await?; - - Ok((Block::new(header, extrinsics), (maybe_inherent_data.map(|id| (id, pre_digest))))) -} - -pub(crate) async fn fast_forward( - shared: SharedParams, - command: FastForwardCmd, - block_building_info_provider: Option, -) -> Result<()> -where - Block: BlockT + DeserializeOwned, - Block::Header: DeserializeOwned, - ::Err: Debug, - NumberFor: FromStr, - as FromStr>::Err: Debug, - HostFns: HostFunctions, - BBIP: BlockBuildingInfoProvider>, -{ - let executor = build_executor::(&shared); - let ext = command.state.into_ext::(&shared, &executor, None, true).await?; - - let mut last_block_hash = ext.block_hash; - let mut last_block_number = - get_block_number::(last_block_hash, command.block_ws_uri()).await?; - let mut prev_block_building_info = None; - - let mut ext = ext.inner_ext; - - for _ in 1..=command.n_blocks.unwrap_or(u64::MAX) { - // We are saving state before we overwrite it while producing new block. - let backend = ext.as_backend(); - - log::info!("Producing new empty block at height {:?}", last_block_number + One::one()); - - let (next_block, new_block_building_info) = next_empty_block::( - &mut ext, - &executor, - last_block_number, - last_block_hash, - &block_building_info_provider, - prev_block_building_info, - ) - .await?; - - log::info!("Produced a new block: {:?}", next_block.header()); - - // And now we restore previous state. - ext.backend = backend; - - let state_root_check = true; - let signature_check = true; - let payload = - (next_block.clone(), state_root_check, signature_check, command.try_state.clone()) - .encode(); - run::(&mut ext, &executor, "TryRuntime_execute_block", &payload).await?; - - log::info!("Executed the new block"); - - prev_block_building_info = new_block_building_info; - last_block_hash = next_block.hash(); - last_block_number += One::one(); - } - - Ok(()) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/follow_chain.rs b/substrate/utils/frame/try-runtime/cli/src/commands/follow_chain.rs deleted file mode 100644 index 53db5e6434632..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/follow_chain.rs +++ /dev/null @@ -1,203 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{ - build_executor, full_extensions, parse, rpc_err_handler, state_machine_call_with_proof, - LiveState, SharedParams, State, LOG_TARGET, -}; -use parity_scale_codec::{Decode, Encode}; -use sc_executor::sp_wasm_interface::HostFunctions; -use serde::{de::DeserializeOwned, Serialize}; -use sp_core::H256; -use sp_runtime::{ - generic::SignedBlock, - traits::{Block as BlockT, Header as HeaderT, NumberFor}, -}; -use std::{fmt::Debug, str::FromStr}; -use substrate_rpc_client::{ws_client, ChainApi, FinalizedHeaders, Subscription, WsClient}; - -const SUB: &str = "chain_subscribeFinalizedHeads"; -const UN_SUB: &str = "chain_unsubscribeFinalizedHeads"; - -/// Configurations of the [`crate::Command::FollowChain`]. -#[derive(Debug, Clone, clap::Parser)] -pub struct FollowChainCmd { - /// The url to connect to. - #[arg(short, long, value_parser = parse::url)] - pub uri: String, - - /// If set, then the state root check is enabled. - #[arg(long)] - pub state_root_check: bool, - - /// Which try-state targets to execute when running this command. - /// - /// Expected values: - /// - `all` - /// - `none` - /// - A comma separated list of pallets, as per pallet names in `construct_runtime!()` (e.g. - /// `Staking, System`). - /// - `rr-[x]` where `[x]` is a number. Then, the given number of pallets are checked in a - /// round-robin fashion. - #[arg(long, default_value = "all")] - pub try_state: frame_try_runtime::TryStateSelect, - - /// If present, a single connection to a node will be kept and reused for fetching blocks. - #[arg(long)] - pub keep_connection: bool, -} - -/// Start listening for with `SUB` at `url`. -/// -/// Returns a pair `(client, subscription)` - `subscription` alone will be useless, because it -/// relies on the related alive `client`. -async fn start_subscribing( - url: &str, -) -> sc_cli::Result<(WsClient, Subscription
)> { - let client = ws_client(url).await.map_err(|e| sc_cli::Error::Application(e.into()))?; - - log::info!(target: LOG_TARGET, "subscribing to {:?} / {:?}", SUB, UN_SUB); - - let sub = ChainApi::<(), (), Header, ()>::subscribe_finalized_heads(&client) - .await - .map_err(|e| sc_cli::Error::Application(e.into()))?; - Ok((client, sub)) -} - -pub(crate) async fn follow_chain( - shared: SharedParams, - command: FollowChainCmd, -) -> sc_cli::Result<()> -where - Block: BlockT + DeserializeOwned, - Block::Header: DeserializeOwned, - ::Err: Debug, - NumberFor: FromStr, - as FromStr>::Err: Debug, - HostFns: HostFunctions, -{ - let (rpc, subscription) = start_subscribing::(&command.uri).await?; - let mut finalized_headers: FinalizedHeaders = - FinalizedHeaders::new(&rpc, subscription); - - let mut maybe_state_ext = None; - let executor = build_executor::(&shared); - - while let Some(header) = finalized_headers.next().await { - let hash = header.hash(); - let number = header.number(); - - let block = - ChainApi::<(), Block::Hash, Block::Header, SignedBlock>::block(&rpc, Some(hash)) - .await - .or_else(|e| { - if matches!(e, substrate_rpc_client::Error::ParseError(_)) { - log::error!( - target: LOG_TARGET, - "failed to parse the block format of remote against the local \ - codebase. The block format has changed, and follow-chain cannot run in \ - this case. Try running this command in a branch of your codebase that - has the same block format as the remote chain. For now, we replace the \ - block with an empty one." - ); - } - Err(rpc_err_handler(e)) - })? - .expect("if header exists, block should also exist.") - .block; - - log::debug!( - target: LOG_TARGET, - "new block event: {:?} => {:?}, extrinsics: {}", - hash, - number, - block.extrinsics().len() - ); - - // create an ext at the state of this block, whatever is the first subscription event. - if maybe_state_ext.is_none() { - let state = State::Live(LiveState { - uri: command.uri.clone(), - // a bit dodgy, we have to un-parse the has to a string again and re-parse it - // inside. - at: Some(hex::encode(header.parent_hash().encode())), - pallet: vec![], - child_tree: true, - }); - let ext = state.into_ext::(&shared, &executor, None, true).await?; - maybe_state_ext = Some(ext); - } - - let state_ext = - maybe_state_ext.as_mut().expect("state_ext either existed or was just created"); - - let result = state_machine_call_with_proof::( - state_ext, - &executor, - "TryRuntime_execute_block", - (block, command.state_root_check, true, command.try_state.clone()) - .encode() - .as_ref(), - full_extensions(executor.clone()), - shared - .export_proof - .as_ref() - .map(|path| path.as_path().join(&format!("{}.json", number))), - ); - - if let Err(why) = result { - log::error!( - target: LOG_TARGET, - "failed to execute block {:?} due to {:?}", - number, - why - ); - continue - } - - let (mut changes, encoded_result) = result.expect("checked to be Ok; qed"); - - let consumed_weight = ::decode(&mut &*encoded_result) - .map_err(|e| format!("failed to decode weight: {:?}", e))?; - - let storage_changes = changes - .drain_storage_changes( - &state_ext.backend, - // Note that in case a block contains a runtime upgrade, state version could - // potentially be incorrect here, this is very niche and would only result in - // unaligned roots, so this use case is ignored for now. - state_ext.state_version, - ) - .unwrap(); - - state_ext.backend.apply_transaction( - storage_changes.transaction_storage_root, - storage_changes.transaction, - ); - - log::info!( - target: LOG_TARGET, - "executed block {}, consumed weight {}, new storage root {:?}", - number, - consumed_weight, - state_ext.as_backend().root(), - ); - } - - log::error!(target: LOG_TARGET, "ws subscription must have terminated."); - Ok(()) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/mod.rs b/substrate/utils/frame/try-runtime/cli/src/commands/mod.rs deleted file mode 100644 index 37902e676e3db..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub mod create_snapshot; -pub mod execute_block; -pub mod fast_forward; -pub mod follow_chain; -pub mod offchain_worker; -pub mod on_runtime_upgrade; diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/offchain_worker.rs b/substrate/utils/frame/try-runtime/cli/src/commands/offchain_worker.rs deleted file mode 100644 index ac95384fb8aa5..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/offchain_worker.rs +++ /dev/null @@ -1,102 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{ - build_executor, commands::execute_block::next_hash_of, full_extensions, parse, rpc_err_handler, - state_machine_call, LiveState, SharedParams, State, LOG_TARGET, -}; -use parity_scale_codec::Encode; -use sc_executor::sp_wasm_interface::HostFunctions; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use std::{fmt::Debug, str::FromStr}; -use substrate_rpc_client::{ws_client, ChainApi}; - -/// Configurations of the [`crate::Command::OffchainWorker`]. -#[derive(Debug, Clone, clap::Parser)] -pub struct OffchainWorkerCmd { - /// The ws uri from which to fetch the header. - /// - /// If the `live` state type is being used, then this can be omitted, and is equal to whatever - /// the `state::uri` is. Only use this (with care) when combined with a snapshot. - #[arg( - long, - value_parser = parse::url - )] - pub header_ws_uri: Option, - - /// The state type to use. - #[command(subcommand)] - pub state: State, -} - -impl OffchainWorkerCmd { - fn header_ws_uri(&self) -> String - where - ::Err: Debug, - { - match (&self.header_ws_uri, &self.state) { - (Some(header_ws_uri), State::Snap { .. }) => header_ws_uri.to_owned(), - (Some(header_ws_uri), State::Live { .. }) => { - log::error!(target: LOG_TARGET, "--header-uri is provided while state type is live, this will most likely lead to a nonsensical result."); - header_ws_uri.to_owned() - }, - (None, State::Live(LiveState { uri, .. })) => uri.clone(), - (None, State::Snap { .. }) => { - panic!("either `--header-uri` must be provided, or state must be `live`"); - }, - } - } -} - -pub(crate) async fn offchain_worker( - shared: SharedParams, - command: OffchainWorkerCmd, -) -> sc_cli::Result<()> -where - Block: BlockT + serde::de::DeserializeOwned, - Block::Header: serde::de::DeserializeOwned, - ::Err: Debug, - NumberFor: FromStr, - as FromStr>::Err: Debug, - HostFns: HostFunctions, -{ - let executor = build_executor(&shared); - // we first build the externalities with the remote code. - let ext = command.state.into_ext::(&shared, &executor, None, true).await?; - - let header_ws_uri = command.header_ws_uri::(); - - let rpc = ws_client(&header_ws_uri).await?; - let next_hash = next_hash_of::(&rpc, ext.block_hash).await?; - log::info!(target: LOG_TARGET, "fetching next header: {:?} ", next_hash); - - let header = ChainApi::<(), Block::Hash, Block::Header, ()>::header(&rpc, Some(next_hash)) - .await - .map_err(rpc_err_handler) - .map(|maybe_header| maybe_header.ok_or("Header does not exist"))??; - let payload = header.encode(); - - let _ = state_machine_call::( - &ext, - &executor, - "OffchainWorkerApi_offchain_worker", - &payload, - full_extensions(executor.clone()), - )?; - - Ok(()) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/commands/on_runtime_upgrade.rs b/substrate/utils/frame/try-runtime/cli/src/commands/on_runtime_upgrade.rs deleted file mode 100644 index 67988a3d1aada..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/commands/on_runtime_upgrade.rs +++ /dev/null @@ -1,89 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::{build_executor, state_machine_call_with_proof, SharedParams, State, LOG_TARGET}; -use frame_try_runtime::UpgradeCheckSelect; -use parity_scale_codec::{Decode, Encode}; -use sc_executor::sp_wasm_interface::HostFunctions; -use sp_runtime::traits::{Block as BlockT, NumberFor}; -use sp_weights::Weight; -use std::{fmt::Debug, str::FromStr}; - -/// Configurations of the [`crate::Command::OnRuntimeUpgrade`]. -#[derive(Debug, Clone, clap::Parser)] -pub struct OnRuntimeUpgradeCmd { - /// The state type to use. - #[command(subcommand)] - pub state: State, - - /// Select which optional checks to perform. Selects all when no value is given. - /// - /// - `none`: Perform no checks. - /// - `all`: Perform all checks (default when --checks is present with no value). - /// - `pre-and-post`: Perform pre- and post-upgrade checks (default when the arg is not - /// present). - /// - `try-state`: Perform the try-state checks. - /// - /// Performing any checks will potentially invalidate the measured PoV/Weight. - // NOTE: The clap attributes make it backwards compatible with the previous `--checks` flag. - #[clap(long, - default_value = "pre-and-post", - default_missing_value = "all", - num_args = 0..=1, - require_equals = true, - verbatim_doc_comment)] - pub checks: UpgradeCheckSelect, -} - -pub(crate) async fn on_runtime_upgrade( - shared: SharedParams, - command: OnRuntimeUpgradeCmd, -) -> sc_cli::Result<()> -where - Block: BlockT + serde::de::DeserializeOwned, - ::Err: Debug, - Block::Header: serde::de::DeserializeOwned, - NumberFor: FromStr, - as FromStr>::Err: Debug, - HostFns: HostFunctions, -{ - let executor = build_executor(&shared); - let ext = command.state.into_ext::(&shared, &executor, None, true).await?; - - let (_, encoded_result) = state_machine_call_with_proof::( - &ext, - &executor, - "TryRuntime_on_runtime_upgrade", - command.checks.encode().as_ref(), - Default::default(), // we don't really need any extensions here. - shared.export_proof, - )?; - - let (weight, total_weight) = <(Weight, Weight) as Decode>::decode(&mut &*encoded_result) - .map_err(|e| format!("failed to decode weight: {:?}", e))?; - - log::info!( - target: LOG_TARGET, - "TryRuntime_on_runtime_upgrade executed without errors. Consumed weight = ({} ps, {} byte), total weight = ({} ps, {} byte) ({:.2} %, {:.2} %).", - weight.ref_time(), weight.proof_size(), - total_weight.ref_time(), total_weight.proof_size(), - (weight.ref_time() as f64 / total_weight.ref_time().max(1) as f64) * 100.0, - (weight.proof_size() as f64 / total_weight.proof_size().max(1) as f64) * 100.0, - ); - - Ok(()) -} diff --git a/substrate/utils/frame/try-runtime/cli/src/lib.rs b/substrate/utils/frame/try-runtime/cli/src/lib.rs deleted file mode 100644 index 606cf8a1e144c..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/lib.rs +++ /dev/null @@ -1,701 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! # Try-runtime -//! -//! Substrate's `try-runtime` subcommand has been migrated to a [standalone -//! CLI](https://github.com/paritytech/try-runtime-cli). -//! -//! It is no longer maintained here and will be removed in the future. - -#![cfg(feature = "try-runtime")] - -use crate::block_building_info::BlockBuildingInfoProvider; -use parity_scale_codec::Decode; -use remote_externalities::{ - Builder, Mode, OfflineConfig, OnlineConfig, RemoteExternalities, SnapshotConfig, -}; -use sc_cli::{ - execution_method_from_cli, CliConfiguration, RuntimeVersion, WasmExecutionMethod, - WasmtimeInstantiationStrategy, DEFAULT_WASMTIME_INSTANTIATION_STRATEGY, - DEFAULT_WASM_EXECUTION_METHOD, -}; -use sc_executor::{ - sp_wasm_interface::HostFunctions, HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY, -}; -use sp_core::{ - hexdisplay::HexDisplay, - offchain::{ - testing::{TestOffchainExt, TestTransactionPoolExt}, - OffchainDbExt, OffchainWorkerExt, TransactionPoolExt, - }, - storage::well_known_keys, - traits::{CallContext, ReadRuntimeVersion, ReadRuntimeVersionExt}, - twox_128, H256, -}; -use sp_externalities::Extensions; -use sp_inherents::InherentData; -use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; -use sp_runtime::{ - traits::{BlakeTwo256, Block as BlockT, Hash as HashT, HashingFor, NumberFor}, - DeserializeOwned, Digest, -}; -use sp_state_machine::{ - CompactProof, OverlayedChanges, StateMachine, TestExternalities, TrieBackendBuilder, -}; -use sp_version::StateVersion; -use std::{fmt::Debug, path::PathBuf, str::FromStr}; - -pub mod block_building_info; -pub mod commands; -pub(crate) mod parse; -pub(crate) const LOG_TARGET: &str = "try-runtime::cli"; - -/// Possible commands of `try-runtime`. -#[derive(Debug, Clone, clap::Subcommand)] -pub enum Command { - /// Execute the migrations of the given runtime - /// - /// This uses a custom runtime api call, namely "TryRuntime_on_runtime_upgrade". The code path - /// only triggers all of the `on_runtime_upgrade` hooks in the runtime, and optionally - /// `try_state`. - /// - /// See [`frame_try_runtime::TryRuntime`] and - /// [`commands::on_runtime_upgrade::OnRuntimeUpgradeCmd`] for more information. - OnRuntimeUpgrade(commands::on_runtime_upgrade::OnRuntimeUpgradeCmd), - - /// Executes the given block against some state. - /// - /// This uses a custom runtime api call, namely "TryRuntime_execute_block". Some checks, such - /// as state-root and signature checks are always disabled, and additional checks like - /// `try-state` can be enabled. - /// - /// See [`frame_try_runtime::TryRuntime`] and [`commands::execute_block::ExecuteBlockCmd`] for - /// more information. - ExecuteBlock(commands::execute_block::ExecuteBlockCmd), - - /// Executes *the offchain worker hooks* of a given block against some state. - /// - /// This executes the same runtime api as normal block import, namely - /// `OffchainWorkerApi_offchain_worker`. - /// - /// See [`frame_try_runtime::TryRuntime`] and [`commands::offchain_worker::OffchainWorkerCmd`] - /// for more information. - OffchainWorker(commands::offchain_worker::OffchainWorkerCmd), - - /// Follow the given chain's finalized blocks and apply all of its extrinsics. - /// - /// This is essentially repeated calls to [`Command::ExecuteBlock`]. - /// - /// This allows the behavior of a new runtime to be inspected over a long period of time, with - /// realistic transactions coming as input. - /// - /// NOTE: this does NOT execute the offchain worker hooks of mirrored blocks. This might be - /// added in the future. - /// - /// This does not support snapshot states, and can only work with a remote chain. Upon first - /// connections, starts listening for finalized block events. Upon first block notification, it - /// initializes the state from the remote node, and starts applying that block, plus all the - /// blocks that follow, to the same growing state. - /// - /// This can only work if the block format between the remote chain and the new runtime being - /// tested has remained the same, otherwise block decoding might fail. - FollowChain(commands::follow_chain::FollowChainCmd), - - /// Produce a series of empty, consecutive blocks and execute them one-by-one. - /// - /// To compare it with [`Command::FollowChain`]: - /// - we don't have the delay of the original blocktime (for Polkadot 6s), but instead, we - /// execute every block immediately - /// - the only data that will be put into blocks are pre-runtime digest items and inherent - /// extrinsics; both things should be defined in your node CLI handling level - FastForward(commands::fast_forward::FastForwardCmd), - - /// Create a new snapshot file. - CreateSnapshot(commands::create_snapshot::CreateSnapshotCmd), -} - -#[derive(Debug, Clone)] -pub enum Runtime { - /// Use the given path to the wasm binary file. - /// - /// It must have been compiled with `try-runtime`. - Path(PathBuf), - - /// Use the code of the remote node, or the snapshot. - /// - /// In almost all cases, this is not what you want, because the code in the remote node does - /// not have any of the try-runtime custom runtime APIs. - Existing, -} - -impl FromStr for Runtime { - type Err = String; - - fn from_str(s: &str) -> Result { - Ok(match s.to_lowercase().as_ref() { - "existing" => Runtime::Existing, - x @ _ => Runtime::Path(x.into()), - }) - } -} - -/// Shared parameters of the `try-runtime` commands -#[derive(Debug, Clone, clap::Parser)] -#[group(skip)] -pub struct SharedParams { - /// Shared parameters of substrate cli. - /// - /// TODO: this is only needed because try-runtime is embedded in the substrate CLI. It should - /// go away. - #[allow(missing_docs)] - #[clap(flatten)] - pub shared_params: sc_cli::SharedParams, - - /// The runtime to use. - /// - /// Must be a path to a wasm blob, compiled with `try-runtime` feature flag. - /// - /// Or, `existing`, indicating that you don't want to overwrite the runtime. This will use - /// whatever comes from the remote node, or the snapshot file. This will most likely not work - /// against a remote node, as no (sane) blockchain should compile its onchain wasm with - /// `try-runtime` feature. - #[arg(long)] - pub runtime: Runtime, - - /// Type of wasm execution used. - #[arg( - long = "wasm-execution", - value_name = "METHOD", - value_enum, - ignore_case = true, - default_value_t = DEFAULT_WASM_EXECUTION_METHOD, - )] - pub wasm_method: WasmExecutionMethod, - - /// The WASM instantiation method to use. - /// - /// Only has an effect when `wasm-execution` is set to `compiled`. - #[arg( - long = "wasm-instantiation-strategy", - value_name = "STRATEGY", - default_value_t = DEFAULT_WASMTIME_INSTANTIATION_STRATEGY, - value_enum, - )] - pub wasmtime_instantiation_strategy: WasmtimeInstantiationStrategy, - - /// The number of 64KB pages to allocate for Wasm execution. Defaults to - /// [`sc_service::Configuration.default_heap_pages`]. - #[arg(long)] - pub heap_pages: Option, - - /// Path to a file to export the storage proof into (as a JSON). - /// If several blocks are executed, the path is interpreted as a folder - /// where one file per block will be written (named `{block_number}-{block_hash}`). - #[clap(long)] - pub export_proof: Option, - - /// Overwrite the `state_version`. - /// - /// Otherwise `remote-externalities` will automatically set the correct state version. - #[arg(long, value_parser = parse::state_version)] - pub overwrite_state_version: Option, -} - -/// Our `try-runtime` command. -/// -/// See [`Command`] for more info. -#[derive(Debug, Clone, clap::Parser)] -pub struct TryRuntimeCmd { - #[clap(flatten)] - pub shared: SharedParams, - - #[command(subcommand)] - pub command: Command, -} - -/// A `Live` variant [`State`] -#[derive(Debug, Clone, clap::Args)] -pub struct LiveState { - /// The url to connect to. - #[arg( - short, - long, - value_parser = parse::url, - )] - uri: String, - - /// The block hash at which to fetch the state. - /// - /// If non provided, then the latest finalized head is used. - #[arg( - short, - long, - value_parser = parse::hash, - )] - at: Option, - - /// A pallet to scrape. Can be provided multiple times. If empty, entire chain state will - /// be scraped. - #[arg(short, long, num_args = 1..)] - pallet: Vec, - - /// Fetch the child-keys as well. - /// - /// Default is `false`, if specific `--pallets` are specified, `true` otherwise. In other - /// words, if you scrape the whole state the child tree data is included out of the box. - /// Otherwise, it must be enabled explicitly using this flag. - #[arg(long)] - child_tree: bool, -} - -/// The source of runtime *state* to use. -#[derive(Debug, Clone, clap::Subcommand)] -pub enum State { - /// Use a state snapshot as the source of runtime state. - Snap { - #[arg(short, long)] - snapshot_path: PathBuf, - }, - - /// Use a live chain as the source of runtime state. - Live(LiveState), -} - -impl State { - /// Create the [`remote_externalities::RemoteExternalities`] using [`remote-externalities`] from - /// self. - /// - /// This will override the code as it sees fit based on [`SharedParams::Runtime`]. It will also - /// check the spec-version and name. - pub(crate) async fn into_ext( - &self, - shared: &SharedParams, - executor: &WasmExecutor, - state_snapshot: Option, - try_runtime_check: bool, - ) -> sc_cli::Result>> - where - Block::Header: DeserializeOwned, - ::Err: Debug, - { - let builder = match self { - State::Snap { snapshot_path } => - Builder::::new().mode(Mode::Offline(OfflineConfig { - state_snapshot: SnapshotConfig::new(snapshot_path), - })), - State::Live(LiveState { pallet, uri, at, child_tree }) => { - let at = match at { - Some(at_str) => Some(hash_of::(at_str)?), - None => None, - }; - Builder::::new().mode(Mode::Online(OnlineConfig { - at, - transport: uri.to_owned().into(), - state_snapshot, - pallets: pallet.clone(), - child_trie: *child_tree, - hashed_keys: vec![ - // we always download the code, but we almost always won't use it, based on - // `Runtime`. - well_known_keys::CODE.to_vec(), - // we will always download this key, since it helps detect if we should do - // runtime migration or not. - [twox_128(b"System"), twox_128(b"LastRuntimeUpgrade")].concat(), - [twox_128(b"System"), twox_128(b"Number")].concat(), - ], - hashed_prefixes: vec![], - })) - }, - }; - - // possibly overwrite the state version, should hardly be needed. - let builder = if let Some(state_version) = shared.overwrite_state_version { - log::warn!( - target: LOG_TARGET, - "overwriting state version to {:?}, you better know what you are doing.", - state_version - ); - builder.overwrite_state_version(state_version) - } else { - builder - }; - - // then, we prepare to replace the code based on what the CLI wishes. - let maybe_code_to_overwrite = match shared.runtime { - Runtime::Path(ref path) => Some(std::fs::read(path).map_err(|e| { - format!("error while reading runtime file from {:?}: {:?}", path, e) - })?), - Runtime::Existing => None, - }; - - // build the main ext. - let mut ext = builder.build().await?; - - // actually replace the code if needed. - if let Some(new_code) = maybe_code_to_overwrite { - let original_code = ext - .execute_with(|| sp_io::storage::get(well_known_keys::CODE)) - .expect("':CODE:' is always downloaded in try-runtime-cli; qed"); - - // NOTE: see the impl notes of `read_runtime_version`, the ext is almost not used here, - // only as a backup. - ext.insert(well_known_keys::CODE.to_vec(), new_code.clone()); - let old_version = ::decode( - &mut &*executor.read_runtime_version(&original_code, &mut ext.ext()).unwrap(), - ) - .unwrap(); - log::info!( - target: LOG_TARGET, - "original spec: {:?}-{:?}, code hash: {:?}", - old_version.spec_name, - old_version.spec_version, - HexDisplay::from(BlakeTwo256::hash(&original_code).as_fixed_bytes()), - ); - let new_version = ::decode( - &mut &*executor.read_runtime_version(&new_code, &mut ext.ext()).unwrap(), - ) - .unwrap(); - log::info!( - target: LOG_TARGET, - "new spec: {:?}-{:?}, code hash: {:?}", - new_version.spec_name, - new_version.spec_version, - HexDisplay::from(BlakeTwo256::hash(&new_code).as_fixed_bytes()) - ); - - if new_version.spec_name != old_version.spec_name { - return Err("Spec names must match.".into()) - } - } - - // whatever runtime we have in store now must have been compiled with try-runtime feature. - if try_runtime_check { - if !ensure_try_runtime::(&executor, &mut ext) { - return Err("given runtime is NOT compiled with try-runtime feature!".into()) - } - } - - Ok(ext) - } -} - -pub const DEPRECATION_NOTICE: &str = "Substrate's `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI."; - -impl TryRuntimeCmd { - // Can't reuse DEPRECATION_NOTICE in the deprecated macro - #[deprecated( - note = "Substrate's `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI." - )] - pub async fn run( - &self, - block_building_info_provider: Option, - ) -> sc_cli::Result<()> - where - Block: BlockT + DeserializeOwned, - Block::Header: DeserializeOwned, - ::Err: Debug, - as FromStr>::Err: Debug, - as TryInto>::Error: Debug, - NumberFor: FromStr, - HostFns: HostFunctions, - BBIP: BlockBuildingInfoProvider>, - { - match &self.command { - Command::OnRuntimeUpgrade(ref cmd) => - commands::on_runtime_upgrade::on_runtime_upgrade::( - self.shared.clone(), - cmd.clone(), - ) - .await, - Command::OffchainWorker(cmd) => - commands::offchain_worker::offchain_worker::( - self.shared.clone(), - cmd.clone(), - ) - .await, - Command::ExecuteBlock(cmd) => - commands::execute_block::execute_block::( - self.shared.clone(), - cmd.clone(), - ) - .await, - Command::FollowChain(cmd) => - commands::follow_chain::follow_chain::( - self.shared.clone(), - cmd.clone(), - ) - .await, - Command::FastForward(cmd) => - commands::fast_forward::fast_forward::( - self.shared.clone(), - cmd.clone(), - block_building_info_provider, - ) - .await, - Command::CreateSnapshot(cmd) => - commands::create_snapshot::create_snapshot::( - self.shared.clone(), - cmd.clone(), - ) - .await, - } - } -} - -impl CliConfiguration for TryRuntimeCmd { - fn shared_params(&self) -> &sc_cli::SharedParams { - &self.shared.shared_params - } - - fn chain_id(&self, _is_dev: bool) -> sc_cli::Result { - Ok(match self.shared.shared_params.chain { - Some(ref chain) => chain.clone(), - None => "dev".into(), - }) - } -} - -/// Get the hash type of the generic `Block` from a `hash_str`. -pub(crate) fn hash_of(hash_str: &str) -> sc_cli::Result -where - ::Err: Debug, -{ - hash_str - .parse::<::Hash>() - .map_err(|e| format!("Could not parse block hash: {:?}", e).into()) -} - -/// Build all extensions that we typically use. -pub(crate) fn full_extensions(wasm_executor: WasmExecutor) -> Extensions { - let mut extensions = Extensions::default(); - let (offchain, _offchain_state) = TestOffchainExt::new(); - let (pool, _pool_state) = TestTransactionPoolExt::new(); - let keystore = MemoryKeystore::new(); - extensions.register(OffchainDbExt::new(offchain.clone())); - extensions.register(OffchainWorkerExt::new(offchain)); - extensions.register(KeystoreExt::new(keystore)); - extensions.register(TransactionPoolExt::new(pool)); - extensions.register(ReadRuntimeVersionExt::new(wasm_executor)); - - extensions -} - -/// Build wasm executor by default config. -pub(crate) fn build_executor(shared: &SharedParams) -> WasmExecutor { - let heap_pages = shared - .heap_pages - .map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |p| HeapAllocStrategy::Static { extra_pages: p as _ }); - - WasmExecutor::builder() - .with_execution_method(execution_method_from_cli( - shared.wasm_method, - shared.wasmtime_instantiation_strategy, - )) - .with_onchain_heap_alloc_strategy(heap_pages) - .with_offchain_heap_alloc_strategy(heap_pages) - .build() -} - -/// Ensure that the given `ext` is compiled with `try-runtime` -fn ensure_try_runtime( - executor: &WasmExecutor, - ext: &mut TestExternalities>, -) -> bool { - use sp_api::RuntimeApiInfo; - let final_code = ext - .execute_with(|| sp_io::storage::get(well_known_keys::CODE)) - .expect("':CODE:' is always downloaded in try-runtime-cli; qed"); - let final_version = ::decode( - &mut &*executor.read_runtime_version(&final_code, &mut ext.ext()).unwrap(), - ) - .unwrap(); - final_version - .api_version(&>::ID) - .is_some() -} - -/// Execute the given `method` and `data` on top of `ext`, returning the results (encoded) and the -/// state `changes`. -pub(crate) fn state_machine_call( - ext: &TestExternalities>, - executor: &WasmExecutor, - method: &'static str, - data: &[u8], - mut extensions: Extensions, -) -> sc_cli::Result<(OverlayedChanges>, Vec)> { - let mut changes = Default::default(); - let encoded_results = StateMachine::new( - &ext.backend, - &mut changes, - executor, - method, - data, - &mut extensions, - &sp_state_machine::backend::BackendRuntimeCode::new(&ext.backend).runtime_code()?, - CallContext::Offchain, - ) - .execute() - .map_err(|e| format!("failed to execute '{}': {}", method, e)) - .map_err::(Into::into)?; - - Ok((changes, encoded_results)) -} - -/// Same as [`state_machine_call`], but it also computes and prints the storage proof in different -/// size and formats. -/// -/// Make sure [`LOG_TARGET`] is enabled in logging. -pub(crate) fn state_machine_call_with_proof( - ext: &TestExternalities>, - executor: &WasmExecutor, - method: &'static str, - data: &[u8], - mut extensions: Extensions, - maybe_export_proof: Option, -) -> sc_cli::Result<(OverlayedChanges>, Vec)> { - use parity_scale_codec::Encode; - - let mut changes = Default::default(); - let backend = ext.backend.clone(); - let runtime_code_backend = sp_state_machine::backend::BackendRuntimeCode::new(&backend); - let proving_backend = - TrieBackendBuilder::wrap(&backend).with_recorder(Default::default()).build(); - let runtime_code = runtime_code_backend.runtime_code()?; - - let pre_root = *backend.root(); - let encoded_results = StateMachine::new( - &proving_backend, - &mut changes, - executor, - method, - data, - &mut extensions, - &runtime_code, - CallContext::Offchain, - ) - .execute() - .map_err(|e| format!("failed to execute {}: {}", method, e)) - .map_err::(Into::into)?; - - let proof = proving_backend - .extract_proof() - .expect("A recorder was set and thus, a storage proof can be extracted; qed"); - - if let Some(path) = maybe_export_proof { - let mut file = std::fs::File::create(&path).map_err(|e| { - log::error!( - target: LOG_TARGET, - "Failed to create file {}: {:?}", - path.to_string_lossy(), - e - ); - e - })?; - - log::info!(target: LOG_TARGET, "Writing storage proof to {}", path.to_string_lossy()); - - use std::io::Write as _; - file.write_all(storage_proof_to_raw_json(&proof).as_bytes()).map_err(|e| { - log::error!( - target: LOG_TARGET, - "Failed to write storage proof to {}: {:?}", - path.to_string_lossy(), - e - ); - e - })?; - } - - let proof_size = proof.encoded_size(); - let compact_proof = proof - .clone() - .into_compact_proof::>(pre_root) - .map_err(|e| { - log::error!(target: LOG_TARGET, "failed to generate compact proof {}: {:?}", method, e); - e - }) - .unwrap_or(CompactProof { encoded_nodes: Default::default() }); - - let compact_proof_size = compact_proof.encoded_size(); - let compressed_proof = zstd::stream::encode_all(&compact_proof.encode()[..], 0) - .map_err(|e| { - log::error!( - target: LOG_TARGET, - "failed to generate compressed proof {}: {:?}", - method, - e - ); - e - }) - .unwrap_or_default(); - - let proof_nodes = proof.into_nodes(); - - let humanize = |s| { - if s < 1024 * 1024 { - format!("{:.2} KB ({} bytes)", s as f64 / 1024f64, s) - } else { - format!( - "{:.2} MB ({} KB) ({} bytes)", - s as f64 / (1024f64 * 1024f64), - s as f64 / 1024f64, - s - ) - } - }; - log::debug!( - target: LOG_TARGET, - "proof: 0x{}... / {} nodes", - HexDisplay::from(&proof_nodes.iter().flatten().cloned().take(10).collect::>()), - proof_nodes.len() - ); - log::debug!(target: LOG_TARGET, "proof size: {}", humanize(proof_size)); - log::debug!(target: LOG_TARGET, "compact proof size: {}", humanize(compact_proof_size),); - log::debug!( - target: LOG_TARGET, - "zstd-compressed compact proof {}", - humanize(compressed_proof.len()), - ); - - log::debug!(target: LOG_TARGET, "{} executed without errors.", method); - - Ok((changes, encoded_results)) -} - -pub(crate) fn rpc_err_handler(error: impl Debug) -> &'static str { - log::error!(target: LOG_TARGET, "rpc error: {:?}", error); - "rpc error." -} - -/// Converts a [`sp_state_machine::StorageProof`] into a JSON string. -fn storage_proof_to_raw_json(storage_proof: &sp_state_machine::StorageProof) -> String { - serde_json::Value::Object( - storage_proof - .to_memory_db::() - .drain() - .iter() - .map(|(key, (value, _n))| { - ( - format!("0x{}", hex::encode(key.as_bytes())), - serde_json::Value::String(format!("0x{}", hex::encode(value))), - ) - }) - .collect(), - ) - .to_string() -} diff --git a/substrate/utils/frame/try-runtime/cli/src/parse.rs b/substrate/utils/frame/try-runtime/cli/src/parse.rs deleted file mode 100644 index 336a36baf2416..0000000000000 --- a/substrate/utils/frame/try-runtime/cli/src/parse.rs +++ /dev/null @@ -1,53 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Utils for parsing user input - -use sp_version::StateVersion; - -pub(crate) fn hash(block_hash: &str) -> Result { - let (block_hash, offset) = if let Some(block_hash) = block_hash.strip_prefix("0x") { - (block_hash, 2) - } else { - (block_hash, 0) - }; - - if let Some(pos) = block_hash.chars().position(|c| !c.is_ascii_hexdigit()) { - Err(format!( - "Expected block hash, found illegal hex character at position: {}", - offset + pos, - )) - } else { - Ok(block_hash.into()) - } -} - -pub(crate) fn url(s: &str) -> Result { - if s.starts_with("ws://") || s.starts_with("wss://") { - // could use Url crate as well, but lets keep it simple for now. - Ok(s.to_string()) - } else { - Err("not a valid WS(S) url: must start with 'ws://' or 'wss://'") - } -} - -pub(crate) fn state_version(s: &str) -> Result { - s.parse::() - .map_err(|_| ()) - .and_then(StateVersion::try_from) - .map_err(|_| "Invalid state version.") -} diff --git a/templates/parachain/node/src/cli.rs b/templates/parachain/node/src/cli.rs index a5c55b8118a89..cffbfbc1db23f 100644 --- a/templates/parachain/node/src/cli.rs +++ b/templates/parachain/node/src/cli.rs @@ -37,11 +37,6 @@ pub enum Subcommand { /// The pallet benchmarking moved to the `pallet` sub-command. #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - - /// Try-runtime has migrated to a standalone - /// [CLI](). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, } const AFTER_HELP_EXAMPLE: &str = color_print::cstr!( diff --git a/templates/parachain/node/src/command.rs b/templates/parachain/node/src/command.rs index 4c36fae30a269..9e7c43e15b064 100644 --- a/templates/parachain/node/src/command.rs +++ b/templates/parachain/node/src/command.rs @@ -217,7 +217,6 @@ pub fn run() -> Result<()> { _ => Err("Benchmarking sub-command unsupported".into()), } }, - Some(Subcommand::TryRuntime) => Err("The `try-runtime` subcommand has been migrated to a standalone CLI (https://github.com/paritytech/try-runtime-cli). It is no longer being maintained here and will be removed entirely some time after January 2024. Please remove this subcommand from your runtime and use the standalone CLI.".into()), None => { let runner = cli.create_runner(&cli.run.normalize())?; let collator_options = cli.run.collator_options(); diff --git a/templates/solochain/node/Cargo.toml b/templates/solochain/node/Cargo.toml index 1ddd1cb3a7b4e..9332da3a6549c 100644 --- a/templates/solochain/node/Cargo.toml +++ b/templates/solochain/node/Cargo.toml @@ -64,9 +64,6 @@ frame-benchmarking-cli = { path = "../../../substrate/utils/frame/benchmarking-c # Local Dependencies solochain-template-runtime = { path = "../runtime" } -# CLI-specific dependencies -try-runtime-cli = { path = "../../../substrate/utils/frame/try-runtime/cli", optional = true } - [build-dependencies] substrate-build-script-utils = { path = "../../../substrate/utils/build-script-utils" } @@ -87,5 +84,4 @@ try-runtime = [ "pallet-transaction-payment/try-runtime", "solochain-template-runtime/try-runtime", "sp-runtime/try-runtime", - "try-runtime-cli/try-runtime", ] diff --git a/templates/solochain/node/src/cli.rs b/templates/solochain/node/src/cli.rs index 7f1b67b3696e6..b2c53aa70949d 100644 --- a/templates/solochain/node/src/cli.rs +++ b/templates/solochain/node/src/cli.rs @@ -41,11 +41,6 @@ pub enum Subcommand { #[command(subcommand)] Benchmark(frame_benchmarking_cli::BenchmarkCmd), - /// Try-runtime has migrated to a standalone CLI - /// (). The subcommand exists as a stub and - /// deprecation notice. It will be removed entirely some time after January 2024. - TryRuntime, - /// Db meta columns information. ChainInfo(sc_cli::ChainInfoCmd), } diff --git a/templates/solochain/node/src/command.rs b/templates/solochain/node/src/command.rs index 7f6df42fb0f97..e46fedc91f0e2 100644 --- a/templates/solochain/node/src/command.rs +++ b/templates/solochain/node/src/command.rs @@ -170,12 +170,6 @@ pub fn run() -> sc_cli::Result<()> { } }) }, - #[cfg(feature = "try-runtime")] - Some(Subcommand::TryRuntime) => Err(try_runtime_cli::DEPRECATION_NOTICE.into()), - #[cfg(not(feature = "try-runtime"))] - Some(Subcommand::TryRuntime) => Err("TryRuntime wasn't enabled when building the node. \ - You can enable it with `--features try-runtime`." - .into()), Some(Subcommand::ChainInfo(cmd)) => { let runner = cli.create_runner(cmd)?; runner.sync_run(|config| cmd.run::(&config))