diff --git a/Cargo.lock b/Cargo.lock index 9c063ee..efaab62 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4378,6 +4378,7 @@ dependencies = [ "blake2", "frame-metadata 16.0.0 (git+https://github.com/paritytech/frame-metadata?branch=main)", "hex", + "log", "parity-scale-codec", "sp-core", "sp-io", diff --git a/README.md b/README.md index 33c2088..4f55900 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,9 @@ MacOS Homebrew users can use: By default, the ID for the Parachain pallet is expected to be `0x01` and the call ID for `authorize_upgrade` is expected to be `0x03`. This default behavior can be overriden by setting the `PARACHAIN_PALLET_ID` to the ID of your parachain pallet and the `AUTHORIZE_UPGRADE_PREFIX` to the ID of your choice. +Also, because of a recent [breaking change to the `parachainSystem::authorizeUpgrade` extrinsic](https://github.com/paritytech/cumulus/commit/3249186fe643f62ca95769e2217f858dde803ab6), a new `checkVersion` boolean flag is required on chains running on Cumulus v0.9.41 and above. +This new behavior is supported by the `AUTHORIZE_UPGRADE_CHECK_VERSION` env variable, which, if set, is evaluated to `true` if its value is the string `"true"`, or false otherwise. +If not set, the behavior remains the same as pre-0.9.41. ### Command: version diff --git a/doc/index.adoc b/doc/index.adoc index 2d42ad3..3554d8e 100644 --- a/doc/index.adoc +++ b/doc/index.adoc @@ -15,6 +15,7 @@ include::usage_info.adoc[] NOTE: By default, the ID for the Parachain pallet is expected to be `0x01` and the call ID for `authorize_upgrade` is expected to be `0x03`. This default behavior can be overriden by setting the `PARACHAIN_PALLET_ID` to the ID of your parachain pallet and the `AUTHORIZE_UPGRADE_PREFIX` to the ID of your choice. +The new `check_spec_version` parameter can be provided with the `AUTHORIZE_UPGRADE_CHECK_VERSION=true` or `AUTHORIZE_UPGRADE_CHECK_VERSION=false` variable, if needed. === Command: version ---- diff --git a/libs/substrate-runtime-proposal-hash/Cargo.toml b/libs/substrate-runtime-proposal-hash/Cargo.toml index d186baa..b6a8850 100644 --- a/libs/substrate-runtime-proposal-hash/Cargo.toml +++ b/libs/substrate-runtime-proposal-hash/Cargo.toml @@ -18,6 +18,7 @@ readme = "README.md" repository = "https://github.com/chevdor/subwasm" [dependencies] +log = "0.4" hex = "0.4" blake2 = "0.10" thiserror = "1.0" diff --git a/libs/substrate-runtime-proposal-hash/src/lib.rs b/libs/substrate-runtime-proposal-hash/src/lib.rs index 6fd839d..3b54405 100644 --- a/libs/substrate-runtime-proposal-hash/src/lib.rs +++ b/libs/substrate-runtime-proposal-hash/src/lib.rs @@ -24,6 +24,8 @@ pub const DEFAULT_PARACHAIN_PALLET_ID: &str = "0x01"; pub const AUTHORIZE_UPGRADE_PREFIX_ENV: &str = "AUTHORIZE_UPGRADE_PREFIX"; pub const DEFAULT_AUTHORIZE_UPGRADE_PREFIX: &str = "0x02"; +pub const AUTHORIZE_UPGRADE_CHECK_VERSION_ENV: &str = "AUTHORIZE_UPGRADE_CHECK_VERSION"; + /// This struct is a container for whatever we calculated. #[derive(Debug)] pub struct SrhResult { @@ -63,9 +65,19 @@ pub fn get_system_setcode(wasm_blob: &[u8]) -> Result { get_call_hash(PREFIX_SYSTEM_SETCODE, wasm_blob) } -pub fn get_parachainsystem_authorize_upgrade(prefix: Prefix, wasm_blob: &[u8]) -> Result { +pub fn get_parachainsystem_authorize_upgrade( + prefix: Prefix, + wasm_blob: &[u8], + check_spec_version: Option, +) -> Result { let code_hash = BlakeTwo256::hash(wasm_blob); - let call_hash = get_call_hash(prefix, code_hash.as_bytes())?; + let call_hash_preimage = if let Some(check_version) = check_spec_version { + let encoded_check_version = [check_version as u8; 1]; + [code_hash.as_bytes(), encoded_check_version.as_slice()].concat() + } else { + code_hash.as_bytes().to_owned() + }; + let call_hash = get_call_hash(prefix, call_hash_preimage.as_slice())?; Ok(call_hash) } @@ -109,7 +121,8 @@ mod prop_hash_tests { assert_eq!( get_parachainsystem_authorize_upgrade( (0x01, 0x02), - &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f] + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + None ) .expect("Failed getting a hash"), [ @@ -119,12 +132,41 @@ mod prop_hash_tests { ); } + #[test] + fn test_parachain_upgrade_with_check_version_flag() { + assert_eq!( + get_parachainsystem_authorize_upgrade( + (0x01, 0x02), + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + Some(true) + ) + .expect("Failed getting a hash"), + [ + 3, 115, 197, 16, 201, 214, 199, 165, 224, 209, 253, 187, 187, 123, 235, 163, 30, 53, 236, 117, 235, + 174, 36, 14, 244, 4, 117, 95, 184, 249, 174, 176 + ] + ); + assert_eq!( + get_parachainsystem_authorize_upgrade( + (0x01, 0x02), + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + Some(false) + ) + .expect("Failed getting a hash"), + [ + 119, 119, 214, 62, 223, 113, 109, 231, 134, 250, 52, 135, 213, 23, 52, 143, 125, 34, 235, 123, 167, + 177, 14, 206, 14, 88, 22, 165, 110, 233, 139, 157 + ] + ); + } + #[test] fn test_custom_parachain_upgrade() { assert_eq!( get_parachainsystem_authorize_upgrade( (0x32, 0x02), - &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f] + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + None ) .expect("Failed getting a hash"), [ @@ -134,6 +176,34 @@ mod prop_hash_tests { ); } + #[test] + fn test_custom_parachain_upgrade_with_check_version_flag() { + assert_eq!( + get_parachainsystem_authorize_upgrade( + (0x32, 0x02), + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + Some(true) + ) + .expect("Failed getting a hash"), + [ + 70, 248, 60, 132, 125, 149, 3, 80, 167, 12, 27, 56, 89, 181, 128, 158, 6, 205, 11, 42, 25, 255, 123, + 216, 86, 86, 127, 53, 193, 119, 224, 44 + ] + ); + assert_eq!( + get_parachainsystem_authorize_upgrade( + (0x32, 0x02), + &[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x97, 0x03, 0x39, 0x60, 0x03, 0x7f, 0x7f], + Some(false) + ) + .expect("Failed getting a hash"), + [ + 209, 146, 155, 255, 19, 158, 45, 191, 35, 129, 211, 182, 29, 74, 42, 196, 13, 139, 203, 105, 183, 102, + 35, 186, 218, 119, 33, 152, 116, 152, 199, 203 + ] + ); + } + #[test] fn test_hash_length() { assert_eq!(32, get_call_hash((0, 0), &[0]).expect("Failed getting a hash").len()); diff --git a/libs/wasm-testbed/src/lib.rs b/libs/wasm-testbed/src/lib.rs index 1c4eb17..0d4843f 100644 --- a/libs/wasm-testbed/src/lib.rs +++ b/libs/wasm-testbed/src/lib.rs @@ -197,6 +197,12 @@ impl WasmTestBed { let s2 = env::var(AUTHORIZE_UPGRADE_PREFIX_ENV) .unwrap_or_else(|_| DEFAULT_AUTHORIZE_UPGRADE_PREFIX.into()) .replacen("0x", "", 1); + let check_version = env::var(AUTHORIZE_UPGRADE_CHECK_VERSION_ENV) + .map(|var| if var == "true" { Some(true) } else { Some(false) }) + .unwrap_or_else(|_| None); + if check_version.is_none() { + log::warn!("Env variable `{AUTHORIZE_UPGRADE_CHECK_VERSION_ENV}` not specified. If your chain is running on Substrate >= 0.9.41, this will most likely yield wrong values for the `parachainSystem::authorizeUpgrade` call hash."); + } let decoded1 = <[u8; 1]>::from_hex(&s1).map_err(|_| RuntimePropHashError::HexDecoding(s1))?; let decoded2 = <[u8; 1]>::from_hex(&s2).map_err(|_| RuntimePropHashError::HexDecoding(s2))?; @@ -205,7 +211,11 @@ impl WasmTestBed { let authorize_upgrade_prefix = *decoded2.first().expect("Failure while fecthing the Auhtorize upgrade ID"); let parachainsystem_authorize_upgrade_prefix = (parachain_pallet_id, authorize_upgrade_prefix); - let result = get_parachainsystem_authorize_upgrade(parachainsystem_authorize_upgrade_prefix, &self.bytes)?; + let result = get_parachainsystem_authorize_upgrade( + parachainsystem_authorize_upgrade_prefix, + &self.bytes, + check_version, + )?; Ok(format!("0x{}", hex::encode(result))) }