diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index d3dd3bac79..b108c832b7 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -38,7 +38,6 @@ jobs: - name: Test All run: | make test-all - make test-benchmarking - name: Inform buddies online uses: 8398a7/action-slack@v3 if: always() && (github.event_name == 'pull_request' && github.event.pull_request.draft == false) diff --git a/.gitignore b/.gitignore index 74bc9bf241..7fc7d3b594 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ yarn.lock *.log output deploy +snapshot.bin +*.wasm diff --git a/Cargo.lock b/Cargo.lock index 8614cf053b..c023bad6b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,6 +199,7 @@ dependencies = [ "frame-support", "frame-system", "frame-system-rpc-runtime-api", + "frame-try-runtime", "hex-literal 0.3.2", "log", "max-encoded-len", @@ -744,6 +745,8 @@ dependencies = [ "frame-support", "frame-system", "frame-system-rpc-runtime-api", + "frame-try-runtime", + "log", "node-primitives", "pallet-aura", "pallet-authorship", @@ -2142,6 +2145,7 @@ dependencies = [ "frame-support", "frame-system", "frame-system-rpc-runtime-api", + "frame-try-runtime", "hex-literal 0.3.2", "log", "max-encoded-len", @@ -4927,6 +4931,7 @@ dependencies = [ "cumulus-client-service", "cumulus-primitives-core", "frame-benchmarking-cli", + "frame-try-runtime", "log", "node-inspect 0.8.0 (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.8)", "node-primitives", @@ -4942,6 +4947,7 @@ dependencies = [ "sp-runtime", "structopt", "substrate-build-script-utils", + "try-runtime-cli", ] [[package]] @@ -5072,6 +5078,7 @@ dependencies = [ "sp-trie", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", + "try-runtime-cli", "zenlink-protocol-runtime-api", ] diff --git a/Cargo.toml b/Cargo.toml index a138e36199..16d45c2a6e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,8 @@ incremental = true node-inspect = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } +try-runtime-cli = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } +frame-try-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } frame-executive = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } frame-metadata = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8" } diff --git a/Makefile b/Makefile index 846b498925..e7a6acfe5c 100644 --- a/Makefile +++ b/Makefile @@ -117,3 +117,11 @@ build-bifrost-wasm: .PHONY: build-asgard-wasm build-asgard-wasm: .maintain/build-wasm.sh asgard + +.PHONY: try-bifrost-runtime-upgrade +try-bifrost-runtime-upgrade: + ./scripts/try-runtime.sh bifrost + +.PHONY: try-asgard-runtime-upgrade +try-asgard-runtime-upgrade: + ./scripts/try-runtime.sh asgard diff --git a/README.md b/README.md index b9a6e75105..291a8f8133 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,12 @@ curl https://sh.rustup.rs -sSf | sh make init ``` +## Build binary + +```bash +make build-all-release +``` + ## Testing ```bash @@ -49,10 +55,12 @@ if runtime logic change we may do the benchmarking to regenerate WeightInfo for make run-benchmarking ``` -## Build binary +## Testing runtime migration + +If modify the storage, should test the data migration before production upgrade. ```bash -make build-all-release +make try-bifrost-runtime-upgrade ``` ## Run development chain diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 0565ae3704..d38fba66a6 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -35,6 +35,8 @@ node-primitives = { path = "../primitives" } # CLI-specific dependencies sc-cli = { version = "0.9.0", optional = true } +try-runtime-cli = { version = "0.9.0", optional = true } +frame-try-runtime = { version = "0.9.0", optional = true } frame-benchmarking-cli = { version = "3.0.0", optional = true } node-inspect = { version = "0.8.0", optional = true } @@ -58,6 +60,7 @@ cli = [ "node-inspect", "sc-cli", "frame-benchmarking-cli", + 'try-runtime-cli', "sc-service", "structopt", "substrate-build-script-utils", @@ -76,3 +79,7 @@ with-all-runtime = [ "with-asgard-runtime", "with-bifrost-runtime", ] +try-runtime = [ + "node-service/try-runtime", + "try-runtime-cli", +] diff --git a/node/cli/src/cli.rs b/node/cli/src/cli.rs index cbd134c822..70a50bb34e 100644 --- a/node/cli/src/cli.rs +++ b/node/cli/src/cli.rs @@ -38,6 +38,11 @@ pub enum Subcommand { #[structopt(name = "benchmark", about = "Benchmark runtime pallets.")] Benchmark(frame_benchmarking_cli::BenchmarkCmd), + /// Try some experimental command on the runtime. This includes migration and runtime-upgrade + /// testing. + #[cfg(feature = "try-runtime")] + TryRuntime(try_runtime_cli::TryRuntimeCmd), + /// Verify a signature for a message, provided on STDIN, with a given (public or secret) key. Verify(VerifyCmd), diff --git a/node/cli/src/command.rs b/node/cli/src/command.rs index d5c4e17ea2..19ab434a4d 100644 --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -83,21 +83,21 @@ fn load_spec( Box::new(service::chain_spec::asgard::ChainSpec::from_json_file(path)?) } #[cfg(not(feature = "with-asgard-runtime"))] - return Err("Asgard runtime is not available. Please compile the node with `--features with-asgard-runtime` to enable it.".into()); + return Err(service::ASGARD_RUNTIME_NOT_AVAILABLE.into()); } else if path.to_str().map(|s| s.contains("bifrost")) == Some(true) { #[cfg(feature = "with-bifrost-runtime")] { Box::new(service::chain_spec::bifrost::ChainSpec::from_json_file(path)?) } #[cfg(not(feature = "with-bifrost-runtime"))] - return Err("Bifrost runtime is not available. Please compile the node with `--features with-bifrost-runtime` to enable it.".into()); - } else if path.to_str().map(|s| s.contains("dev")) == Some(true) { + return Err(service::BIFROST_RUNTIME_NOT_AVAILABLE.into()); + } else if path.to_str().map(|s| s.contains("asgard-dev")) == Some(true) { #[cfg(feature = "with-dev-runtime")] { Box::new(service::chain_spec::dev::ChainSpec::from_json_file(path)?) } - #[cfg(not(feature = "with-dev-runtime"))] - return Err("Dev runtime is not available. Please compile the node with `--features with-dev-runtime` to enable it.".into()); + #[cfg(not(feature = "with-dev-runtime"))] + return Err(service::DEV_RUNTIME_NOT_AVAILABLE.into()); } else { return Err("Unknown runtime is not available.".into()); } @@ -147,21 +147,21 @@ impl SubstrateCli for Cli { &service::collator::asgard_runtime::VERSION } #[cfg(not(feature = "with-asgard-runtime"))] - panic!("Asgard runtime is not available. Please compile the node with `--features with-asgard-runtime` to enable it."); + panic!("{}", service::ASGARD_RUNTIME_NOT_AVAILABLE); } else if spec.is_bifrost() { #[cfg(feature = "with-bifrost-runtime")] { &service::collator::bifrost_runtime::VERSION } #[cfg(not(feature = "with-bifrost-runtime"))] - panic!("Bifrost runtime is not available. Please compile the node with `--features with-bifrost-runtime` to enable it."); + panic!("{}", service::BIFROST_RUNTIME_NOT_AVAILABLE); } else { #[cfg(feature = "with-dev-runtime")] { &service::dev::dev_runtime::VERSION } #[cfg(not(feature = "with-dev-runtime"))] - panic!("Asgard dev runtime is not available. Please compile the node with `--features with-dev-runtime` to enable it."); + panic!("{}", service::DEV_RUNTIME_NOT_AVAILABLE); } } } @@ -252,6 +252,60 @@ macro_rules! construct_async_run { }} } +macro_rules! with_runtime_or_err { + ($chain_spec:expr, { $( $code:tt )* }) => { + if $chain_spec.is_bifrost() { + #[cfg(feature = "with-bifrost-runtime")] + #[allow(unused_imports)] + use bifrost_runtime::{Block, RuntimeApi}; + #[cfg(feature = "with-bifrost-runtime")] + #[allow(unused_imports)] + use BifrostExecutor as Executor; + #[cfg(feature = "with-bifrost-runtime")] + $( $code )* + + #[cfg(not(feature = "with-bifrost-runtime"))] + return Err(service::BIFROST_RUNTIME_NOT_AVAILABLE.into()); + } else if $chain_spec.is_asgard() { + #[cfg(feature = "with-asgard-runtime")] + #[allow(unused_imports)] + use asgard_runtime::{Block, RuntimeApi}; + #[cfg(feature = "with-asgard-runtime")] + #[allow(unused_imports)] + use AsgardExecutor as Executor; + #[cfg(feature = "with-asgard-runtime")] + $( $code )* + + #[cfg(not(feature = "with-asgard-runtime"))] + return Err(service::ASGARD_RUNTIME_NOT_AVAILABLE.into()); + } else { + #[cfg(feature = "with-dev-runtime")] + #[allow(unused_imports)] + use service::dev::dev_runtime::{Block, RuntimeApi}; + #[cfg(feature = "with-dev-runtime")] + #[allow(unused_imports)] + use service::dev::DevExecutor as Executor; + #[cfg(feature = "with-dev-runtime")] + $( $code )* + + #[cfg(not(feature = "with-dev-runtime"))] + return Err(service::DEV_RUNTIME_NOT_AVAILABLE.into()); + } + } +} + +fn set_default_ss58_version(spec: &Box) { + use sp_core::crypto::Ss58AddressFormat; + + let ss58_version = if spec.is_bifrost() { + Ss58AddressFormat::BifrostAccount + } else { + Ss58AddressFormat::SubstrateAccount + }; + + sp_core::crypto::set_default_ss58_version(ss58_version); +} + /// Parse command line arguments into service configuration. #[allow(unreachable_code)] pub fn run() -> Result<()> { @@ -309,39 +363,22 @@ pub fn run() -> Result<()> { }, Some(Subcommand::Inspect(cmd)) => { let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + set_default_ss58_version(chain_spec); - return runner.sync_run(|config| { - #[cfg(feature = "with-asgard-runtime")] - return cmd - .run::( - config, - ); - #[cfg(feature = "with-bifrost-runtime")] - return cmd - .run::( - config, - ); - #[cfg(feature = "with-dev-runtime")] - return cmd - .run::( - config, - ); - }); + with_runtime_or_err!(chain_spec, { + return runner.sync_run(|config| cmd.run::(config)); + }) }, Some(Subcommand::Benchmark(cmd)) => if cfg!(feature = "runtime-benchmarks") { let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + set_default_ss58_version(chain_spec); - return runner.sync_run(|config| { - #[cfg(feature = "with-asgard-runtime")] - return cmd - .run::(config); - #[cfg(feature = "with-bifrost-runtime")] - return cmd - .run::(config); - #[cfg(feature = "with-dev-runtime")] - return cmd.run::(config); - }); + with_runtime_or_err!(chain_spec, { + return runner.sync_run(|config| cmd.run::(config)); + }) } else { Err("Benchmarking wasn't enabled when building the node. \ You can enable it with `--features runtime-benchmarks`." @@ -446,6 +483,25 @@ pub fn run() -> Result<()> { Ok(()) }, + #[cfg(feature = "try-runtime")] + Some(Subcommand::TryRuntime(cmd)) => { + let runner = cli.create_runner(cmd)?; + let chain_spec = &runner.config().chain_spec; + + set_default_ss58_version(chain_spec); + + with_runtime_or_err!(chain_spec, { + return runner.async_run(|config| { + let registry = config.prometheus_config.as_ref().map(|cfg| &cfg.registry); + let task_manager = + sc_service::TaskManager::new(config.task_executor.clone(), registry) + .map_err(|e| { + sc_cli::Error::Service(sc_service::Error::Prometheus(e)) + })?; + Ok((cmd.run::(config), task_manager)) + }); + }) + }, } } diff --git a/node/service/Cargo.toml b/node/service/Cargo.toml index f365508ef3..06de23cefd 100644 --- a/node/service/Cargo.toml +++ b/node/service/Cargo.toml @@ -50,7 +50,7 @@ pallet-transaction-payment-rpc-runtime-api = { version = "3.0.0" } frame-system-rpc-runtime-api = { version = "3.0.0" } substrate-prometheus-endpoint = { version = "0.9.0" } substrate-frame-rpc-system = { version = "3.0.0" } - +try-runtime-cli = { version = "0.9.0", optional = true } # Cumulus dependencies cumulus-client-consensus-aura = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } cumulus-client-consensus-common = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } @@ -108,4 +108,8 @@ with-all-runtime = [ "with-asgard-runtime", "with-bifrost-runtime", ] +try-runtime = [ + "asgard-runtime/try-runtime", + "bifrost-runtime/try-runtime", +] diff --git a/node/service/src/lib.rs b/node/service/src/lib.rs index aeb8a25652..7423eabba0 100644 --- a/node/service/src/lib.rs +++ b/node/service/src/lib.rs @@ -61,3 +61,10 @@ impl IdentifyVariant for Box { self.id().starts_with("asgard-dev") || self.id().starts_with("dev") } } + +pub const BIFROST_RUNTIME_NOT_AVAILABLE: &str = + "Bifrost runtime is not available. Please compile the node with `--features with-bifrost-runtime` to enable it."; +pub const ASGARD_RUNTIME_NOT_AVAILABLE: &str = + "Asgard runtime is not available. Please compile the node with `--features with-asgard-runtime` to enable it."; +pub const DEV_RUNTIME_NOT_AVAILABLE: &str = + "Dev runtime is not available. Please compile the node with `--features with-dev-runtime` to enable it."; diff --git a/pallets/salp/src/lib.rs b/pallets/salp/src/lib.rs index 337ad0f6b8..da8c8bbae6 100644 --- a/pallets/salp/src/lib.rs +++ b/pallets/salp/src/lib.rs @@ -19,6 +19,12 @@ // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] +pub mod migration { + pub fn migrate() { + log::info!("salp migration..."); + } +} + #[cfg(feature = "runtime-benchmarks")] pub mod benchmarking; #[cfg(test)] diff --git a/runtime/asgard/Cargo.toml b/runtime/asgard/Cargo.toml index 3b51f55ac5..2712b87a89 100644 --- a/runtime/asgard/Cargo.toml +++ b/runtime/asgard/Cargo.toml @@ -30,6 +30,7 @@ sp-arithmetic = { version = "3.0.0", default-features = false } # frame dependencies frame-benchmarking = { version = "3.0.0", default-features = false, optional = true } +frame-try-runtime = { version = "0.9.0", default-features = false, optional = true } frame-executive = { version = "3.0.0", default-features = false } frame-support = { version = "3.0.0", default-features = false } frame-system = { version = "3.0.0", default-features = false } @@ -108,6 +109,7 @@ std = [ "codec/std", "log/std", "frame-benchmarking/std", + "frame-try-runtime/std", "frame-executive/std", "frame-support/std", "frame-system-rpc-runtime-api/std", @@ -190,3 +192,10 @@ runtime-benchmarks = [ "bifrost-vtoken-mint/runtime-benchmarks", "bifrost-minter-reward/runtime-benchmarks", ] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "pallet-vesting/try-runtime", +] diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 63861efcf5..5778d57ef6 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -76,6 +76,7 @@ use bifrost_runtime_common::xcm_impl::{ use codec::{Decode, Encode}; use constants::{currency::*, time::*}; use cumulus_primitives_core::ParaId as CumulusParaId; +use frame_support::traits::OnRuntimeUpgrade; use node_primitives::{ Amount, CurrencyId, Moment, Nonce, TokenSymbol, TransferOriginType, XcmBaseWeight, }; @@ -1250,6 +1251,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPallets, + CustomOnRuntimeUpgrade, >; impl_runtime_apis! { @@ -1506,6 +1508,36 @@ impl_runtime_apis! { Ok(batches) } } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade() -> Result<(Weight, Weight), sp_runtime::RuntimeString> { + let weight = Executive::try_runtime_upgrade()?; + Ok((weight, RuntimeBlockWeights::get().max_block)) + } + } +} + +pub struct CustomOnRuntimeUpgrade; +impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + #[allow(unused_imports)] + use frame_support::{migration, Identity}; + + log::info!("Asgard `pre_upgrade`..."); + + bifrost_salp::migration::migrate(); + + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn on_runtime_upgrade() -> Weight { + log::info!("Asgard `on_runtime_upgrade`..."); + + RuntimeBlockWeights::get().max_block + } } struct CheckInherents; diff --git a/runtime/bifrost/Cargo.toml b/runtime/bifrost/Cargo.toml index 9aba38d97e..0c409dc0c0 100644 --- a/runtime/bifrost/Cargo.toml +++ b/runtime/bifrost/Cargo.toml @@ -8,7 +8,7 @@ build = "build.rs" [dependencies] # third-party dependencies codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive", "max-encoded-len"] } - +log = { version = "0.4.14", default-features = false } # primitives node-primitives = { default-features = false, path = "../../node/primitives" } sp-block-builder = { default-features = false, version = "3.0.0"} @@ -25,6 +25,7 @@ sp-consensus-aura = { version = "0.9.0", default-features = false } # frame dependencies frame-benchmarking = { version = "3.0.0", default-features = false, optional = true } +frame-try-runtime = { version = "0.9.0", default-features = false, optional = true } frame-executive = { version = "3.0.0", default-features = false } frame-support = { version = "3.0.0", default-features = false } frame-system = { version = "3.0.0", default-features = false } @@ -74,7 +75,9 @@ default = ["std"] with-tracing = [ "frame-executive/with-tracing" ] std = [ "codec/std", + "log/std", "frame-executive/std", + "frame-try-runtime/std", "frame-support/std", "frame-system-rpc-runtime-api/std", "frame-system/std", @@ -125,3 +128,10 @@ runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", ] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "pallet-vesting/try-runtime", +] diff --git a/runtime/bifrost/src/lib.rs b/runtime/bifrost/src/lib.rs index efd47b1518..b26ae8f644 100644 --- a/runtime/bifrost/src/lib.rs +++ b/runtime/bifrost/src/lib.rs @@ -59,6 +59,7 @@ use sp_version::RuntimeVersion; /// Constant values used within the runtime. pub mod constants; use constants::{currency::*, time::*}; +use frame_support::traits::OnRuntimeUpgrade; use frame_system::EnsureRoot; use node_primitives::{Moment, Nonce}; use pallet_xcm::XcmPassthrough; @@ -591,6 +592,7 @@ pub type Executive = frame_executive::Executive< frame_system::ChainContext, Runtime, AllPallets, + CustomOnRuntimeUpgrade, >; impl_runtime_apis! { @@ -696,6 +698,34 @@ impl_runtime_apis! { Aura::authorities() } } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade() -> Result<(Weight, Weight), sp_runtime::RuntimeString> { + log::info!("try-runtime::on_runtime_upgrade bifrost."); + let weight = Executive::try_runtime_upgrade()?; + Ok((weight, RuntimeBlockWeights::get().max_block)) + } + } +} + +pub struct CustomOnRuntimeUpgrade; +impl OnRuntimeUpgrade for CustomOnRuntimeUpgrade { + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + #[allow(unused_imports)] + use frame_support::{migration, Identity}; + + log::info!("Bifrost `pre_upgrade`..."); + + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn on_runtime_upgrade() -> Weight { + log::info!("Bifrost `on_runtime_upgrade`..."); + RuntimeBlockWeights::get().max_block + } } struct CheckInherents; diff --git a/runtime/dev/Cargo.toml b/runtime/dev/Cargo.toml index 01a5143f01..075a3ec795 100644 --- a/runtime/dev/Cargo.toml +++ b/runtime/dev/Cargo.toml @@ -30,6 +30,7 @@ sp-arithmetic = { version = "3.0.0", default-features = false } # frame dependencies frame-benchmarking = { version = "3.0.0", default-features = false, optional = true } +frame-try-runtime = { version = "0.9.0", default-features = false, optional = true } frame-executive = { version = "3.0.0", default-features = false } frame-support = { version = "3.0.0", default-features = false } frame-system = { version = "3.0.0", default-features = false } @@ -109,6 +110,7 @@ std = [ "codec/std", "log/std", "frame-benchmarking/std", + "frame-try-runtime/std", "frame-executive/std", "frame-support/std", "frame-system-rpc-runtime-api/std", @@ -192,3 +194,10 @@ runtime-benchmarks = [ "bifrost-vtoken-mint/runtime-benchmarks", "bifrost-minter-reward/runtime-benchmarks", ] + +try-runtime = [ + "frame-executive/try-runtime", + "frame-try-runtime", + "frame-system/try-runtime", + "pallet-vesting/try-runtime", +] diff --git a/runtime/dev/src/lib.rs b/runtime/dev/src/lib.rs index d8e7742188..e02cc60cc4 100644 --- a/runtime/dev/src/lib.rs +++ b/runtime/dev/src/lib.rs @@ -1500,6 +1500,15 @@ impl_runtime_apis! { Ok(batches) } } + + #[cfg(feature = "try-runtime")] + impl frame_try_runtime::TryRuntime for Runtime { + fn on_runtime_upgrade() -> Result<(Weight, Weight), sp_runtime::RuntimeString> { + log::info!("try-runtime::on_runtime_upgrade bifrost."); + let weight = Executive::try_runtime_upgrade()?; + Ok((weight, RuntimeBlockWeights::get().max_block)) + } + } } struct CheckInherents; diff --git a/scripts/try-runtime.sh b/scripts/try-runtime.sh new file mode 100755 index 0000000000..03e893b8b7 --- /dev/null +++ b/scripts/try-runtime.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +chain_type=$1 +chain_type="${chain_type:-bifrost}" + +chain_url=$2 +chain_url="${chain_url:-ws://localhost:9944}" + +block_hash=$3 +block_hash="${block_hash:-0xd854e0d78b2bcd9cc56b6b4897f13d937d8ee166f1cda3b6c748ce775c56a87d}" + +cargo run -p node-cli --locked --features with-$chain_type-runtime --features try-runtime -- try-runtime --chain="$chain_type-genesis" --wasm-execution=compiled --url="$chain_url" --block-at="$block_hash" on-runtime-upgrade live -s snapshot.bin \ No newline at end of file