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}