try_runtime_core/commands/
mod.rs

1// This file is part of try-runtime-cli.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use std::{fmt::Debug, str::FromStr};
19
20use sc_executor::sp_wasm_interface::HostFunctions;
21use sp_core::H256;
22use sp_runtime::{
23    traits::{Block as BlockT, NumberFor},
24    DeserializeOwned,
25};
26
27use crate::common::shared_parameters::SharedParams;
28
29pub mod create_snapshot;
30pub mod execute_block;
31pub mod fast_forward;
32pub mod follow_chain;
33pub mod offchain_worker;
34pub mod on_runtime_upgrade;
35
36/// Ready to use, vanilla command combining common actions.
37#[derive(Debug, Clone, clap::Parser)]
38#[command(author, version, about)]
39pub struct TryRuntime {
40    #[clap(flatten)]
41    pub shared: SharedParams,
42
43    #[command(subcommand)]
44    pub action: Action,
45}
46
47impl TryRuntime {
48    pub async fn run<Block, HostFns>(&self) -> sc_cli::Result<()>
49    where
50        Block: BlockT<Hash = H256> + DeserializeOwned,
51        Block::Header: DeserializeOwned,
52        Block::Hash: FromStr,
53        <Block::Hash as FromStr>::Err: Debug,
54        <NumberFor<Block> as FromStr>::Err: Debug,
55        <NumberFor<Block> as TryInto<u64>>::Error: Debug,
56        NumberFor<Block>: FromStr,
57        HostFns: HostFunctions,
58    {
59        self.action.run::<Block, HostFns>(&self.shared).await
60    }
61}
62
63/// Possible actions of `try-runtime`.
64#[derive(Debug, Clone, clap::Subcommand)]
65pub enum Action {
66    /// Execute the migrations of the given runtime
67    ///
68    /// This uses a custom runtime api call, namely "TryRuntime_on_runtime_upgrade". The code path
69    /// only triggers all of the `on_runtime_upgrade` hooks in the runtime, and optionally
70    /// `try_state`.
71    ///
72    /// See [`TryRuntime`] and [`on_runtime_upgrade::Command`] for more information.
73    OnRuntimeUpgrade(on_runtime_upgrade::Command),
74
75    /// Executes the given block against some state.
76    ///
77    /// This uses a custom runtime api call, namely "TryRuntime_execute_block". Some checks, such
78    /// as state-root and signature checks are always disabled, and additional checks like
79    /// `try-state` can be enabled.
80    ///
81    /// See [`TryRuntime`] and [`execute_block::Command`] for more information.
82    ExecuteBlock(execute_block::Command),
83
84    /// Executes *the offchain worker hooks* of a given block against some state.
85    ///
86    /// This executes the same runtime api as normal block import, namely
87    /// `OffchainWorkerApi_offchain_worker`.
88    ///
89    /// See [`frame_try_runtime::TryRuntime`] and [`offchain_worker::Command`]
90    /// for more information.
91    OffchainWorker(offchain_worker::Command),
92
93    /// Follow the given chain's finalized blocks and apply all of its extrinsics.
94    ///
95    /// This is essentially repeated calls to [`Action::ExecuteBlock`].
96    ///
97    /// This allows the behavior of a new runtime to be inspected over a long period of time, with
98    /// realistic transactions coming as input.
99    ///
100    /// NOTE: this does NOT execute the offchain worker hooks of mirrored blocks. This might be
101    /// added in the future.
102    ///
103    /// This does not support snapshot states, and can only work with a remote chain. Upon first
104    /// connections, starts listening for finalized block events. Upon first block notification, it
105    /// initializes the state from the remote node, and starts applying that block, plus all the
106    /// blocks that follow, to the same growing state.
107    ///
108    /// This can only work if the block format between the remote chain and the new runtime being
109    /// tested has remained the same, otherwise block decoding might fail.
110    FollowChain(follow_chain::Command),
111
112    /// Create snapshot files.
113    ///
114    /// The `create-snapshot` subcommand facilitates the creation of a snapshot from a node's
115    /// state. This snapshot can be loaded rapidly into memory from disk, providing an
116    /// efficient alternative to downloading state from the node for every new command
117    /// execution.
118    ///
119    /// **Usage**:
120    ///
121    /// 1. Create a snapshot from a remote node:
122    ///
123    /// try-runtime create-snapshot --uri ws://remote-node-uri my_state.snap
124    ///
125    /// 2. Utilize the snapshot with `on-runtime-upgrade`:
126    ///
127    /// try-runtime --runtime ./path/to/runtime.wasm on-runtime-upgrade snap --path my_state.snap
128    CreateSnapshot(create_snapshot::Command),
129
130    /// Executes a runtime upgrade (optional), then mines a number of blocks while performing
131    /// try-state checks.
132    ///
133    /// The try-state checks are performed using the `TryRuntime_execute_block` runtime api.
134    ///
135    /// See [`TryRuntime`] and [`fast_forward::Command`] for more information.
136    FastForward(fast_forward::Command),
137}
138
139impl Action {
140    pub async fn run<Block, HostFns>(&self, shared: &SharedParams) -> sc_cli::Result<()>
141    where
142        Block: BlockT<Hash = H256> + DeserializeOwned,
143        Block::Header: DeserializeOwned,
144        Block::Hash: FromStr,
145        <Block::Hash as FromStr>::Err: Debug,
146        <NumberFor<Block> as FromStr>::Err: Debug,
147        <NumberFor<Block> as TryInto<u64>>::Error: Debug,
148        NumberFor<Block>: FromStr,
149        HostFns: HostFunctions,
150    {
151        match &self {
152            Action::OnRuntimeUpgrade(ref cmd) => {
153                on_runtime_upgrade::CheckOnRuntimeUpgrade::<Block, HostFns> {
154                    shared: shared.clone(),
155                    command: cmd.clone(),
156                    _phantom: Default::default(),
157                }
158                .run()
159                .await
160            }
161            Action::ExecuteBlock(cmd) => {
162                execute_block::run::<Block, HostFns>(shared.clone(), cmd.clone()).await
163            }
164            Action::OffchainWorker(cmd) => {
165                offchain_worker::run::<Block, HostFns>(shared.clone(), cmd.clone()).await
166            }
167            Action::FollowChain(cmd) => {
168                follow_chain::run::<Block, HostFns>(shared.clone(), cmd.clone()).await
169            }
170            Action::CreateSnapshot(cmd) => {
171                create_snapshot::run::<Block, HostFns>(shared.clone(), cmd.clone()).await
172            }
173            Action::FastForward(cmd) => {
174                fast_forward::run::<Block, HostFns>(shared.clone(), cmd.clone()).await
175            }
176        }
177    }
178}