diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 33ad43a4ec..0e7fce2b8d 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -7101,6 +7101,7 @@ dependencies = [ "sp-core", "sp-io", "sp-runtime", + "sp-version", "tokio 0.2.25", ] diff --git a/substrate/utils/frame/remote-externalities/Cargo.toml b/substrate/utils/frame/remote-externalities/Cargo.toml index c799e30d6a..f849c89d70 100644 --- a/substrate/utils/frame/remote-externalities/Cargo.toml +++ b/substrate/utils/frame/remote-externalities/Cargo.toml @@ -27,6 +27,7 @@ serde = "1.0.126" sp-io = { version = "4.0.0-dev", path = "../../../primitives/io" } sp-core = { version = "4.0.0-dev", path = "../../../primitives/core" } sp-runtime = { version = "4.0.0-dev", path = "../../../primitives/runtime" } +sp-version = { version = "4.0.0-dev", path = "../../../primitives/version" } [dev-dependencies] tokio = { version = "0.2", features = ["macros", "rt-threaded"] } diff --git a/substrate/utils/frame/remote-externalities/src/rpc_api.rs b/substrate/utils/frame/remote-externalities/src/rpc_api.rs index be77cd9499..24050856a9 100644 --- a/substrate/utils/frame/remote-externalities/src/rpc_api.rs +++ b/substrate/utils/frame/remote-externalities/src/rpc_api.rs @@ -88,3 +88,24 @@ async fn build_client>(from: S) -> Result { .await .map_err(|e| format!("`WsClientBuilder` failed to build: {:?}", e)) } + +/// Get the runtime version of a given chain. +pub async fn get_runtime_version( + from: S, + at: Option, +) -> Result +where + S: AsRef, + Block: BlockT + serde::de::DeserializeOwned, + Block::Header: HeaderT, +{ + let params = if let Some(at) = at { vec![hash_to_json::(at)?] } else { vec![] }; + let client = build_client(from).await?; + client + .request::( + "state_getRuntimeVersion", + JsonRpcParams::Array(params), + ) + .await + .map_err(|e| format!("state_getRuntimeVersion request failed: {:?}", e)) +} diff --git a/substrate/utils/frame/try-runtime/cli/src/lib.rs b/substrate/utils/frame/try-runtime/cli/src/lib.rs index 047829d94d..c92c395953 100644 --- a/substrate/utils/frame/try-runtime/cli/src/lib.rs +++ b/substrate/utils/frame/try-runtime/cli/src/lib.rs @@ -179,7 +179,7 @@ async fn on_runtime_upgrade( config: Configuration, ) -> sc_cli::Result<()> where - Block: BlockT, + Block: BlockT + serde::de::DeserializeOwned, Block::Hash: FromStr, ::Err: Debug, NumberFor: FromStr, @@ -198,6 +198,8 @@ where max_runtime_instances, ); + check_spec_name::(shared.url.clone(), config.chain_spec.name().to_string()).await; + let ext = { let builder = match command.state { State::Snap { snapshot_path } => @@ -254,7 +256,7 @@ async fn offchain_worker( config: Configuration, ) -> sc_cli::Result<()> where - Block: BlockT, + Block: BlockT + serde::de::DeserializeOwned, Block::Hash: FromStr, Block::Header: serde::de::DeserializeOwned, ::Err: Debug, @@ -274,6 +276,8 @@ where max_runtime_instances, ); + check_spec_name::(shared.url.clone(), config.chain_spec.name().to_string()).await; + let mode = match command.state { State::Live { snapshot_path, modules } => { let at = shared.block_at::()?; @@ -361,6 +365,8 @@ where let block_hash = shared.block_at::()?; let block: Block = rpc_api::get_block::(shared.url.clone(), block_hash).await?; + check_spec_name::(shared.url.clone(), config.chain_spec.name().to_string()).await; + let mode = match command.state { State::Snap { snapshot_path } => { let mode = @@ -484,3 +490,32 @@ fn extract_code(spec: Box) -> sc_cli::Result<(StorageKey, Storage Ok((code_key, code)) } + +/// Check the spec_name of an `ext` +/// +/// If the version does not exist, or if it does not match with the given, it emits a warning. +async fn check_spec_name( + uri: String, + expected_spec_name: String, +) { + let expected_spec_name = expected_spec_name.to_lowercase(); + match remote_externalities::rpc_api::get_runtime_version::(uri.clone(), None) + .await + .map(|version| String::from(version.spec_name.clone())) + .map(|spec_name| spec_name.to_lowercase()) + { + Ok(spec) if spec == expected_spec_name => { + log::debug!("found matching spec name: {:?}", spec); + }, + Ok(spec) => { + log::warn!( + "version mismatch: remote spec name: '{}', expected (local chain spec, aka. `--chain`): '{}'", + spec, + expected_spec_name, + ); + }, + Err(why) => { + log::error!("failed to fetch runtime version from {}: {:?}", uri, why); + }, + } +}