From cbf4c85d93ab21b72df99aa5982be1d184b25da8 Mon Sep 17 00:00:00 2001 From: eNddy Date: Tue, 30 Jul 2024 09:50:14 -0700 Subject: [PATCH] feat(runtime): add metadata signed-extension (#2097) Add a new signed extension that enables the metadata hash verification feature approved under [RFC 0078](https://polkadot-fellows.github.io/RFCs/approved/0078-merkleized-metadata.html#rfc-0078-merkleized-metadata). This enhancement will support the new generic ledger hardware wallet app and future hardware wallets within the Polkadot ecosystem. [Reference implementation](https://github.com/paritytech/polkadot-sdk/pull/4580) --- Cargo.lock | 54 +++++++++++++++++++ Cargo.toml | 4 +- common/primitives/Cargo.toml | 4 +- node/cli/Cargo.toml | 1 + node/cli/src/benchmarking.rs | 2 + node/service/src/service.rs | 2 +- runtime/common/src/weights/block_weights.rs | 20 +++---- .../common/src/weights/extrinsic_weights.rs | 20 +++---- runtime/frequency/Cargo.toml | 16 +++++- runtime/frequency/build.rs | 20 ++++--- runtime/frequency/src/lib.rs | 5 +- runtime/system-runtime-api/Cargo.toml | 9 +++- 12 files changed, 119 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59a4619e26..2394da9c82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3604,6 +3604,7 @@ dependencies = [ "derive_more", "frame-benchmarking", "frame-benchmarking-cli", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frequency-runtime", @@ -3654,6 +3655,7 @@ dependencies = [ "cumulus-primitives-timestamp", "frame-benchmarking", "frame-executive", + "frame-metadata-hash-extension", "frame-support", "frame-system", "frame-system-benchmarking", @@ -5731,6 +5733,20 @@ dependencies = [ "hash-db", ] +[[package]] +name = "merkleized-metadata" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f313fcff1d2a4bcaa2deeaa00bf7530d77d5f7bd0467a117dde2e29a75a7a17a" +dependencies = [ + "array-bytes 6.2.3", + "blake3", + "frame-metadata", + "parity-scale-codec", + "scale-decode", + "scale-info", +] + [[package]] name = "merlin" version = "3.0.0" @@ -11772,6 +11788,29 @@ dependencies = [ "sp-arithmetic", ] +[[package]] +name = "scale-bits" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54" +dependencies = [ + "parity-scale-codec", + "scale-type-resolver", +] + +[[package]] +name = "scale-decode" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f3262c250d90e700bb802eb704e1f841e03331c2eb815e46516c4edbf5b27" +dependencies = [ + "derive_more", + "parity-scale-codec", + "scale-bits", + "scale-type-resolver", + "smallvec", +] + [[package]] name = "scale-info" version = "2.11.3" @@ -11798,6 +11837,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scale-type-resolver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb" + [[package]] name = "schannel" version = "0.1.23" @@ -13576,13 +13621,22 @@ name = "substrate-wasm-builder" version = "17.0.0" source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.9.0#5641e185cacd79b0c6ac1263ae28613c9625e6b3" dependencies = [ + "array-bytes 6.2.3", "build-helper", "cargo_metadata", "console", "filetime", + "frame-metadata", + "merkleized-metadata", + "parity-scale-codec", "parity-wasm", "polkavm-linker", + "sc-executor", + "sp-core", + "sp-io", "sp-maybe-compressed-blob", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.9.0)", + "sp-version", "strum 0.24.1", "tempfile", "toml 0.8.14", diff --git a/Cargo.toml b/Cargo.toml index 731b7b3910..e3eb6d92a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ frame-system = { git = "https://github.com/paritytech/polkadot-sdk", branch = "r frame-system-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } frame-try-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } +frame-metadata-hash-extension = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-api = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-io = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } @@ -44,6 +45,7 @@ scale-info = { version = "2.10.0", default-features = false, features = [ sp-keystore = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-keyring = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-version = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } +substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } chrono = { version = "0.4.24" } pretty_assertions = { version = "1.3.0" } smallvec = "1.11.0" @@ -149,13 +151,11 @@ sp-rpc = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release sp-timestamp = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } sp-transaction-pool = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0", default-features = false } sp-wasm-interface = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } -sp-metadata-ir = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } substrate-build-script-utils = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } substrate-test-utils = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } substrate-frame-rpc-system = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } substrate-prometheus-endpoint = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } -substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0"} try-runtime-cli = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.9.0" } [profile.release] diff --git a/common/primitives/Cargo.toml b/common/primitives/Cargo.toml index 8f4541a67b..d41d4d8cc7 100644 --- a/common/primitives/Cargo.toml +++ b/common/primitives/Cargo.toml @@ -37,9 +37,9 @@ std = [ 'frame-support/std', 'frame-system/std', 'sp-std/std', - 'sp-runtime/std', 'sp-api/std', 'scale-info/std', 'sp-core/std', - 'sp-runtime/std' + 'sp-runtime/std', + 'sp-io/std', ] diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 88db5ca4c2..a558457ce4 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -31,6 +31,7 @@ frame-benchmarking-cli = { workspace = true, optional = true } frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } +frame-metadata-hash-extension = { workspace = true } pallet-balances = { workspace = true } pallet-transaction-payment = { workspace = true } sc-cli = { workspace = true, optional = true } diff --git a/node/cli/src/benchmarking.rs b/node/cli/src/benchmarking.rs index 7da5492912..2259784391 100644 --- a/node/cli/src/benchmarking.rs +++ b/node/cli/src/benchmarking.rs @@ -130,6 +130,7 @@ pub fn create_benchmark_extrinsic( pallet_frequency_tx_payment::ChargeFrqTransactionPayment::::from(0), pallet_msa::CheckFreeExtrinsicUse::::new(), pallet_handles::handles_signed_extension::HandlesSignedExtension::::new(), + frame_metadata_hash_extension::CheckMetadataHash::::new(false), ); let raw_payload = sp_runtime::generic::SignedPayload::from_raw( @@ -146,6 +147,7 @@ pub fn create_benchmark_extrinsic( (), (), (), + None, ), ); let signature = raw_payload.using_encoded(|e| sender.sign(e)); diff --git a/node/service/src/service.rs b/node/service/src/service.rs index 48c1876067..72a409c127 100644 --- a/node/service/src/service.rs +++ b/node/service/src/service.rs @@ -13,6 +13,7 @@ use frequency_runtime::RuntimeApi; // RPC use common_primitives::node::{AccountId, Balance, Block, Hash, Index as Nonce}; use jsonrpsee::RpcModule; +use substrate_prometheus_endpoint::Registry; // Cumulus Imports use cumulus_client_collator::service::CollatorService; @@ -48,7 +49,6 @@ use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerH use sc_transaction_pool_api::OffchainTransactionPoolFactory; use sp_blockchain::HeaderBackend; use sp_keystore::KeystorePtr; -use substrate_prometheus_endpoint::Registry; type FullBackend = TFullBackend; diff --git a/runtime/common/src/weights/block_weights.rs b/runtime/common/src/weights/block_weights.rs index 14e5f9c0bb..36e4373520 100644 --- a/runtime/common/src/weights/block_weights.rs +++ b/runtime/common/src/weights/block_weights.rs @@ -16,8 +16,8 @@ // limitations under the License. //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-07-26 (Y/M/D) -//! HOSTNAME: `ip-10-173-10-116`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! DATE: 2024-07-30 (Y/M/D) +//! HOSTNAME: `ip-10-173-4-48`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` //! //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Frequency Development (No Relay)` //! WARMUPS: `10`, REPEAT: `100` @@ -43,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 237_698, 260_606 - /// Average: 241_909 - /// Median: 239_649 - /// Std-Dev: 5441.42 + /// Min, Max: 240_263, 260_853 + /// Average: 245_079 + /// Median: 243_534 + /// Std-Dev: 4690.52 /// /// Percentiles nanoseconds: - /// 99th: 260_507 - /// 95th: 254_401 - /// 75th: 242_002 + /// 99th: 260_552 + /// 95th: 256_706 + /// 75th: 246_329 pub const BlockExecutionWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(241_909), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(245_079), 0); } #[cfg(test)] diff --git a/runtime/common/src/weights/extrinsic_weights.rs b/runtime/common/src/weights/extrinsic_weights.rs index e4ab134e1f..5f892dc337 100644 --- a/runtime/common/src/weights/extrinsic_weights.rs +++ b/runtime/common/src/weights/extrinsic_weights.rs @@ -16,8 +16,8 @@ // limitations under the License. //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-07-26 (Y/M/D) -//! HOSTNAME: `ip-10-173-10-116`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! DATE: 2024-07-30 (Y/M/D) +//! HOSTNAME: `ip-10-173-4-48`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` //! //! SHORT-NAME: `extrinsic`, LONG-NAME: `ExtrinsicBase`, RUNTIME: `Frequency Development (No Relay)` //! WARMUPS: `10`, REPEAT: `100` @@ -43,17 +43,17 @@ parameter_types! { /// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// /// Stats nanoseconds: - /// Min, Max: 63_899, 66_104 - /// Average: 64_842 - /// Median: 64_786 - /// Std-Dev: 417.92 + /// Min, Max: 62_949, 64_130 + /// Average: 63_309 + /// Median: 63_277 + /// Std-Dev: 228.35 /// /// Percentiles nanoseconds: - /// 99th: 65_857 - /// 95th: 65_692 - /// 75th: 65_020 + /// 99th: 63_842 + /// 95th: 63_716 + /// 75th: 63_452 pub const ExtrinsicBaseWeight: Weight = - Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(64_842), 0); + Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(63_309), 0); } #[cfg(test)] diff --git a/runtime/frequency/Cargo.toml b/runtime/frequency/Cargo.toml index ec502ba390..219bb6609a 100644 --- a/runtime/frequency/Cargo.toml +++ b/runtime/frequency/Cargo.toml @@ -12,7 +12,7 @@ version = "0.0.0" targets = ["x86_64-unknown-linux-gnu"] [build-dependencies] -substrate-wasm-builder = { workspace = true } +substrate-wasm-builder = { workspace = true, optional = true } [dependencies] parity-scale-codec = { workspace = true, features = ["derive"] } @@ -30,6 +30,7 @@ frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } +frame-metadata-hash-extension = { workspace = true } pallet-aura = { workspace = true } pallet-authorship = { workspace = true } @@ -162,6 +163,8 @@ std = [ "common-runtime/std", "sp-version/std", "system-runtime-api/std", + "substrate-wasm-builder", + "frame-metadata-hash-extension/std", ] runtime-benchmarks = [ "cumulus-pallet-parachain-system/runtime-benchmarks", @@ -238,4 +241,13 @@ frequency-local = ["common-runtime/frequency-local"] frequency-no-relay = ["common-runtime/frequency-no-relay"] # Following features are used in generating lean wasms no-metadata-docs = ["frame-support/no-metadata-docs"] -on-chain-release-build = ["sp-api/disable-logging"] +on-chain-release-build = ["metadata-hash", "sp-api/disable-logging"] + +# Enable the metadata hash generation. +# +# This is hidden behind a feature because it increases the compile time. +# The wasm binary needs to be compiled twice, once to fetch the metadata, +# generate the metadata hash and then a second time with the +# `RUNTIME_METADATA_HASH` environment variable set for the `CheckMetadataHash` +# extension. +metadata-hash = ["substrate-wasm-builder/metadata-hash"] diff --git a/runtime/frequency/build.rs b/runtime/frequency/build.rs index 7e33800782..7f0c5a1035 100644 --- a/runtime/frequency/build.rs +++ b/runtime/frequency/build.rs @@ -1,12 +1,16 @@ -use substrate_wasm_builder::WasmBuilder; +#[cfg(all(feature = "std", not(feature = "metadata-hash")))] +fn main() { + substrate_wasm_builder::WasmBuilder::build_using_defaults() +} +#[cfg(all(feature = "std", feature = "metadata-hash"))] fn main() { - // VSCode Users: Uncomment the following line to disable the ANSI color codes. - // The OUTPUT pane does not understand ANSI color codes and will show garbage without this. - // std::env::set_var("WASM_BUILD_NO_COLOR", "1"); - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() + substrate_wasm_builder::WasmBuilder::init_with_defaults() + .enable_metadata_hash("FRQCY", 8) .build() } + +/// The wasm builder is deactivated when compiling +/// this crate for wasm to speed up the compilation. +#[cfg(not(feature = "std"))] +fn main() {} diff --git a/runtime/frequency/src/lib.rs b/runtime/frequency/src/lib.rs index 1fba58b799..7fee5d1c7f 100644 --- a/runtime/frequency/src/lib.rs +++ b/runtime/frequency/src/lib.rs @@ -305,6 +305,7 @@ pub type SignedExtra = ( pallet_frequency_tx_payment::ChargeFrqTransactionPayment, pallet_msa::CheckFreeExtrinsicUse, pallet_handles::handles_signed_extension::HandlesSignedExtension, + frame_metadata_hash_extension::CheckMetadataHash, ); /// A Block signed with a Justification pub type SignedBlock = generic::SignedBlock; @@ -364,7 +365,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency"), impl_name: create_runtime_str!("frequency"), authoring_version: 1, - spec_version: 100, + spec_version: 101, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -378,7 +379,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frequency-testnet"), impl_name: create_runtime_str!("frequency"), authoring_version: 1, - spec_version: 100, + spec_version: 101, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/system-runtime-api/Cargo.toml b/runtime/system-runtime-api/Cargo.toml index 1fc443752f..95e123766a 100644 --- a/runtime/system-runtime-api/Cargo.toml +++ b/runtime/system-runtime-api/Cargo.toml @@ -22,4 +22,11 @@ common-primitives = { default-features = false, path = "../../common/primitives" [features] default = ["std"] -std = ["sp-api/std", "frame-system/std", "frame-support/std", "common-primitives/std", "sp-std/std", "sp-runtime/std"] +std = [ + "sp-api/std", + "frame-system/std", + "frame-support/std", + "common-primitives/std", + "sp-std/std", + "sp-runtime/std", +]