From da550a71b291067556548926c632b1e91ee160ef Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 11:41:58 +0300 Subject: [PATCH 01/24] metadata-ir: Add extrinsic type info to decode address, call, sig Signed-off-by: Alexandru Vasile --- primitives/metadata-ir/src/types.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/primitives/metadata-ir/src/types.rs b/primitives/metadata-ir/src/types.rs index 93ee54891d89f..23fd50ef136bf 100644 --- a/primitives/metadata-ir/src/types.rs +++ b/primitives/metadata-ir/src/types.rs @@ -156,6 +156,12 @@ pub struct ExtrinsicMetadataIR { pub ty: T::Type, /// Extrinsic version. pub version: u8, + /// The type of the address that signes the extrinsic + pub address_ty: T::Type, + /// The type of the call. + pub call_ty: T::Type, + /// The type of the extrinsic's signature. + pub signature_ty: T::Type, /// The signed extensions in the order they appear in the extrinsic. pub signed_extensions: Vec>, } @@ -167,6 +173,9 @@ impl IntoPortable for ExtrinsicMetadataIR { ExtrinsicMetadataIR { ty: registry.register_type(&self.ty), version: self.version, + address_ty: registry.register_type(&self.address_ty), + call_ty: registry.register_type(&self.call_ty), + signature_ty: registry.register_type(&self.signature_ty), signed_extensions: registry.map_into_portable(self.signed_extensions), } } From a51ea7b51a549935ef8b9cb12201db46a4aa45b0 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 11:44:20 +0300 Subject: [PATCH 02/24] frame-metadata: Point to unreleased branch Signed-off-by: Alexandru Vasile --- Cargo.lock | 3 +-- frame/support/Cargo.toml | 2 +- primitives/metadata-ir/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e6e8e847a01b..b6e70fb25466e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2650,8 +2650,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#847fc3d213acc4ca1312ce96064fe8d9abeef2c5" dependencies = [ "cfg-if", "parity-scale-codec", diff --git a/frame/support/Cargo.toml b/frame/support/Cargo.toml index d8b1b9c248720..be887472cca17 100644 --- a/frame/support/Cargo.toml +++ b/frame/support/Cargo.toml @@ -16,7 +16,7 @@ targets = ["x86_64-unknown-linux-gnu"] serde = { version = "1.0.136", optional = true, features = ["derive"] } codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive", "max-encoded-len"] } scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } -frame-metadata = { version = "15.1.0", default-features = false, features = ["v14", "v15-unstable"] } +frame-metadata = { git = "https://github.com/paritytech/frame-metadata.git", branch = "lexnv/extrinsic_decode_info", default-features = false, features = ["v14", "v15-unstable"] } sp-api = { version = "4.0.0-dev", default-features = false, path = "../../primitives/api" } sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" } sp-io = { version = "7.0.0", default-features = false, path = "../../primitives/io" } diff --git a/primitives/metadata-ir/Cargo.toml b/primitives/metadata-ir/Cargo.toml index 27fada9c6f34e..1d99e4c389e49 100644 --- a/primitives/metadata-ir/Cargo.toml +++ b/primitives/metadata-ir/Cargo.toml @@ -14,7 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false } -frame-metadata = { version = "15.1.0", default-features = false, features = ["v14", "v15-unstable"] } +frame-metadata = { git = "https://github.com/paritytech/frame-metadata.git", branch = "lexnv/extrinsic_decode_info", default-features = false, features = ["v14", "v15-unstable"] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } sp-std = { version = "5.0.0", default-features = false, path = "../std" } From 888ce4a96174d66d83939f17a08d13a773044034 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 11:46:16 +0300 Subject: [PATCH 03/24] metadata-ir: Include addrees, call, signature in V15 conversion Signed-off-by: Alexandru Vasile --- primitives/metadata-ir/src/v15.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/primitives/metadata-ir/src/v15.rs b/primitives/metadata-ir/src/v15.rs index 86441228d008e..a668ccf87268d 100644 --- a/primitives/metadata-ir/src/v15.rs +++ b/primitives/metadata-ir/src/v15.rs @@ -182,6 +182,9 @@ impl From for ExtrinsicMetadata { ExtrinsicMetadata { ty: ir.ty, version: ir.version, + address_ty: ir.address_ty, + call_ty: ir.call_ty, + signature_ty: ir.signature_ty, signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), } } From 49995b4f6ccc9365dd4e3bfe28afc1a3f7f17edd Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 12:56:42 +0300 Subject: [PATCH 04/24] metadata-ir: Include extra ty Signed-off-by: Alexandru Vasile --- primitives/metadata-ir/src/types.rs | 5 ++++- primitives/metadata-ir/src/v15.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/primitives/metadata-ir/src/types.rs b/primitives/metadata-ir/src/types.rs index 23fd50ef136bf..4cf2c165e3798 100644 --- a/primitives/metadata-ir/src/types.rs +++ b/primitives/metadata-ir/src/types.rs @@ -158,10 +158,12 @@ pub struct ExtrinsicMetadataIR { pub version: u8, /// The type of the address that signes the extrinsic pub address_ty: T::Type, - /// The type of the call. + /// The type of the outermost Call enum. pub call_ty: T::Type, /// The type of the extrinsic's signature. pub signature_ty: T::Type, + /// The type of the outermost Extra enum. + pub extra_ty: T::Type, /// The signed extensions in the order they appear in the extrinsic. pub signed_extensions: Vec>, } @@ -176,6 +178,7 @@ impl IntoPortable for ExtrinsicMetadataIR { address_ty: registry.register_type(&self.address_ty), call_ty: registry.register_type(&self.call_ty), signature_ty: registry.register_type(&self.signature_ty), + extra_ty: registry.register_type(&self.extra_ty), signed_extensions: registry.map_into_portable(self.signed_extensions), } } diff --git a/primitives/metadata-ir/src/v15.rs b/primitives/metadata-ir/src/v15.rs index a668ccf87268d..098e627ba608d 100644 --- a/primitives/metadata-ir/src/v15.rs +++ b/primitives/metadata-ir/src/v15.rs @@ -185,6 +185,7 @@ impl From for ExtrinsicMetadata { address_ty: ir.address_ty, call_ty: ir.call_ty, signature_ty: ir.signature_ty, + extra_ty: ir.extra_ty, signed_extensions: ir.signed_extensions.into_iter().map(Into::into).collect(), } } From 0babb5336360aa88f895d73abaf9490ff9beb4a5 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 12:58:16 +0300 Subject: [PATCH 05/24] construct_runtime: Extract address,call,sig,extra ty from tx type Signed-off-by: Alexandru Vasile --- Cargo.lock | 2 +- .../src/construct_runtime/expand/metadata.rs | 76 +++++++++++++++---- 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6e70fb25466e..abe8d7061c37b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2650,7 +2650,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "15.1.0" -source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#847fc3d213acc4ca1312ce96064fe8d9abeef2c5" +source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#5a14aacd2fcf01b2ec1689acd3575088fab2d62a" dependencies = [ "cfg-if", "parity-scale-codec", diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 81fc93ba3c9ef..14e5f2b30201b 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -76,6 +76,65 @@ pub fn expand_runtime_metadata( quote! { impl #runtime { + fn extrinsic_metadata_ir() -> #scrate::metadata_ir::ExtrinsicMetadataIR { + let ty = #scrate::scale_info::meta_type::<#extrinsic>(); + + // Inspect the extrinsic type parameters for the following types needed to + // decode extrinsics. + const ADDRESS: &str = "Address"; + const CALL: &str = "Call"; + const SIGNATURE: &str = "Signature"; + const EXTRA: &str = "Extra"; + + let mut address_ty = None; + let mut call_ty = None; + let mut signature_ty = None; + let mut extra_ty = None; + + for ty_param in &ty.type_info().type_params { + let name = ty_param.name; + + if name == ADDRESS { + address_ty = ty_param.ty; + } + if name == CALL { + call_ty = ty_param.ty; + } + if name == SIGNATURE { + signature_ty = ty_param.ty; + } + if name == EXTRA { + extra_ty = ty_param.ty; + } + } + + let address_ty = address_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); + let call_ty = call_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); + let signature_ty = signature_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); + let extra_ty = extra_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); + + #scrate::metadata_ir::ExtrinsicMetadataIR { + ty, + version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, + address_ty, + call_ty, + signature_ty, + extra_ty, + signed_extensions: < + < + #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata + >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension + >::metadata() + .into_iter() + .map(|meta| #scrate::metadata_ir::SignedExtensionMetadataIR { + identifier: meta.identifier, + ty: meta.ty, + additional_signed: meta.additional_signed, + }) + .collect(), + } + } + fn metadata_ir() -> #scrate::metadata_ir::MetadataIR { // Each runtime must expose the `runtime_metadata()` to fetch the runtime API metadata. // The function is implemented by calling `impl_runtime_apis!`. @@ -97,22 +156,7 @@ pub fn expand_runtime_metadata( #scrate::metadata_ir::MetadataIR { pallets: #scrate::sp_std::vec![ #(#pallets),* ], - extrinsic: #scrate::metadata_ir::ExtrinsicMetadataIR { - ty: #scrate::scale_info::meta_type::<#extrinsic>(), - version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, - signed_extensions: < - < - #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata - >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension - >::metadata() - .into_iter() - .map(|meta| #scrate::metadata_ir::SignedExtensionMetadataIR { - identifier: meta.identifier, - ty: meta.ty, - additional_signed: meta.additional_signed, - }) - .collect(), - }, + extrinsic: #runtime::extrinsic_metadata_ir(), ty: #scrate::scale_info::meta_type::<#runtime>(), apis: (&rt).runtime_metadata(), } From 768c515c84f1fa8b54969728661cb4ad14c36a1f Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 14:17:07 +0300 Subject: [PATCH 06/24] frame/tests: Check metadata populates xt types correctly Signed-off-by: Alexandru Vasile --- frame/support/test/tests/pallet.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 7f15ad1f9298a..ecf76ce769d4c 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::collections::HashMap; + use frame_support::{ assert_ok, dispatch::{ @@ -1703,6 +1705,32 @@ fn metadata_ir_pallet_runtime_docs() { assert_eq!(pallet.docs, expected); } +#[test] +fn extrinsic_metadata_ir_types() { + let ir = Runtime::extrinsic_metadata_ir(); + + // `TestXt` used to construct the runtime exposes only the `Call` and `Extra` types. + // In contrast, substrate chains expose: `Address`, `Call`, `Signature` and `Extra` types. + // Any missing type is populated with the tuple type. + let params: HashMap<_, _> = ir + .ty + .type_info() + .type_params + .iter() + .map(|ty_param| (ty_param.name, ty_param.ty.expect("Type params are populated"))) + .collect(); + + assert!(params.get("Address").is_none()); + let call_ty = params.get("Call").expect("Type `Call` must be present in the extrinsic"); + assert!(params.get("Signature").is_none()); + let extra_ty = params.get("Extra").expect("Type `Extra` must be present in the extrinsic"); + + assert_eq!(meta_type::<()>(), ir.address_ty); + assert_eq!(call_ty, &ir.call_ty); + assert_eq!(meta_type::<()>(), ir.signature_ty); + assert_eq!(extra_ty, &ir.extra_ty); +} + #[test] fn test_pallet_runtime_docs() { let docs = crate::pallet::Pallet::::pallet_documentation_metadata(); @@ -1716,7 +1744,6 @@ fn test_pallet_info_access() { assert_eq!(::name(), "System"); assert_eq!(::name(), "Example"); assert_eq!(::name(), "Example2"); - assert_eq!(::index(), 0); assert_eq!(::index(), 1); assert_eq!(::index(), 2); From ab66814fcc5b4ed375904c19b5296b7b4974d13d Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Thu, 11 May 2023 14:40:31 +0300 Subject: [PATCH 07/24] metadata-ir/tests: Add extra fields on ExtrinsicMetadataIR Signed-off-by: Alexandru Vasile --- primitives/metadata-ir/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/primitives/metadata-ir/src/lib.rs b/primitives/metadata-ir/src/lib.rs index 3ddc2911d4c93..0e9b0d6c397d3 100644 --- a/primitives/metadata-ir/src/lib.rs +++ b/primitives/metadata-ir/src/lib.rs @@ -81,6 +81,10 @@ mod test { extrinsic: ExtrinsicMetadataIR { ty: meta_type::<()>(), version: 0, + address_ty: meta_type::<()>(), + call_ty: meta_type::<()>(), + signature_ty: meta_type::<()>(), + extra_ty: meta_type::<()>(), signed_extensions: vec![], }, ty: meta_type::<()>(), From 6610ac2836f2015133e60fe7b208de8e640b809d Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 15 May 2023 23:06:13 +0300 Subject: [PATCH 08/24] primitives/traits: Expand the `Extrinsic::SignaturePayload` Signed-off-by: Alexandru Vasile --- primitives/runtime/src/traits.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 95f977077e704..dbee81757a23f 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -961,12 +961,20 @@ pub trait Extrinsic: Sized { /// The function call. type Call; - /// The payload we carry for signed extrinsics. + /// The type of the address that signed the extrinsic. /// - /// Usually it will contain a `Signature` and - /// may include some additional data that are specific to signed - /// extrinsics. - type SignaturePayload; + /// Particular to a signed extrinsic. + type SignatureAddress; + + /// The signature type of the extrinsic. + /// + /// Particular to a signed extrinsic. + type Signature; + + /// The additional data that is specific to the signed extrinsic. + /// + /// Particular to a signed extrinsic. + type SignatureExtra; /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. @@ -980,7 +988,10 @@ pub trait Extrinsic: Sized { /// 1. Inherents (no signature; created by validators during block production) /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of /// calls) 3. Signed Transactions (with signature; a regular transactions with known origin) - fn new(_call: Self::Call, _signed_data: Option) -> Option { + fn new( + _call: Self::Call, + _signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, + ) -> Option { None } } From 25617e0f67b65dd9acb0eb1ba9b9d26b3fc00a07 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 15 May 2023 23:08:12 +0300 Subject: [PATCH 09/24] primitives: Adjust to new `Extrinsic` associated types Signed-off-by: Alexandru Vasile --- bin/node/runtime/src/lib.rs | 9 +++++++- frame/system/src/offchain.rs | 15 +++++++++++-- .../src/generic/unchecked_extrinsic.rs | 11 ++++++++-- primitives/runtime/src/lib.rs | 6 ++++-- primitives/runtime/src/testing.rs | 21 ++++++++++++------- primitives/test-primitives/src/lib.rs | 9 ++++++-- 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 02a126cc4c8ca..ba1755244773a 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1272,7 +1272,14 @@ where public: ::Signer, account: AccountId, nonce: Index, - ) -> Option<(RuntimeCall, ::SignaturePayload)> { + ) -> Option<( + RuntimeCall, + ( + ::SignatureAddress, + ::Signature, + ::SignatureExtra, + ), + )> { let tip = 0; // take the biggest period possible. let period = diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 742146d1642c8..927cd1fe51028 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -86,7 +86,11 @@ where /// Submit transaction onchain by providing the call and an optional signature pub fn submit_transaction( call: >::OverarchingCall, - signature: Option<::SignaturePayload>, + signature: Option<( + ::SignatureAddress, + ::Signature, + ::SignatureExtra, + )>, ) -> Result<(), ()> { let xt = T::Extrinsic::new(call, signature).ok_or(())?; sp_io::offchain::submit_transaction(xt.encode()) @@ -487,7 +491,14 @@ pub trait CreateSignedTransaction: public: Self::Public, account: Self::AccountId, nonce: Self::Index, - ) -> Option<(Self::OverarchingCall, ::SignaturePayload)>; + ) -> Option<( + Self::OverarchingCall, + ( + ::SignatureAddress, + ::Signature, + ::SignatureExtra, + ), + )>; } /// A message signer. diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index d147e7b6c1505..e4467b7c69c59 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -106,13 +106,20 @@ impl Extrinsic { type Call = Call; - type SignaturePayload = (Address, Signature, Extra); + type SignatureAddress = Address; + + type Signature = Signature; + + type SignatureExtra = Extra; fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new(function: Call, signed_data: Option) -> Option { + fn new( + function: Call, + signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, + ) -> Option { Some(if let Some((address, signature, extra)) = signed_data { Self::new_signed(function, address, signature, extra) } else { diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 13ef157dff19e..88d2135ef2236 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -897,13 +897,15 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { { let r = ::sp_core::bytes::deserialize(de)?; Decode::decode(&mut &r[..]) - .map_err(|e| ::serde::de::Error::custom(format!("Decode error: {}", e))) + .map_err(|e: codec::Error| ::serde::de::Error::custom(format!("Decode error: {}", e))) } } impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); - type SignaturePayload = (); + type SignatureAddress = (); + type Signature = (); + type SignatureExtra = (); } /// Print something that implements `Printable` from the runtime. diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 6d02e23094f90..b07753cbc1ba8 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -204,7 +204,9 @@ pub struct ExtrinsicWrapper(Xt); impl traits::Extrinsic for ExtrinsicWrapper { type Call = (); - type SignaturePayload = (); + type SignatureAddress = (); + type Signature = (); + type SignatureExtra = (); fn is_signed(&self) -> Option { None @@ -286,14 +288,14 @@ where #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] pub struct TestXt { /// Signature of the extrinsic. - pub signature: Option<(u64, Extra)>, + pub signature: Option<(u64, (), Extra)>, /// Call of the extrinsic. pub call: Call, } impl TestXt { /// Create a new `TextXt`. - pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self { + pub fn new(call: Call, signature: Option<(u64, (), Extra)>) -> Self { Self { call, signature } } } @@ -333,13 +335,18 @@ impl Checkable for TestXt traits::Extrinsic for TestXt { type Call = Call; - type SignaturePayload = (u64, Extra); + type SignatureAddress = u64; + type Signature = (); + type SignatureExtra = Extra; fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new(c: Call, sig: Option) -> Option { + fn new( + c: Call, + sig: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, + ) -> Option { Some(TestXt { signature: sig, call: c }) } } @@ -376,7 +383,7 @@ where info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { - if let Some((ref id, ref extra)) = self.signature { + if let Some((ref id, _, ref extra)) = self.signature { Extra::validate(extra, id, &self.call, info, len) } else { let valid = Extra::validate_unsigned(&self.call, info, len)?; @@ -392,7 +399,7 @@ where info: &DispatchInfoOf, len: usize, ) -> ApplyExtrinsicResultWithInfo> { - let maybe_who = if let Some((who, extra)) = self.signature { + let maybe_who = if let Some((who, _, extra)) = self.signature { Extra::pre_dispatch(extra, &who, &self.call, info, len)?; Some(who) } else { diff --git a/primitives/test-primitives/src/lib.rs b/primitives/test-primitives/src/lib.rs index 035acc7a35ef6..c5c4040e58cd7 100644 --- a/primitives/test-primitives/src/lib.rs +++ b/primitives/test-primitives/src/lib.rs @@ -46,7 +46,9 @@ impl serde::Serialize for Extrinsic { impl ExtrinsicT for Extrinsic { type Call = Extrinsic; - type SignaturePayload = (); + type SignatureAddress = (); + type Signature = (); + type SignatureExtra = (); fn is_signed(&self) -> Option { if let Extrinsic::IncludeData(_) = *self { @@ -56,7 +58,10 @@ impl ExtrinsicT for Extrinsic { } } - fn new(call: Self::Call, _signature_payload: Option) -> Option { + fn new( + call: Self::Call, + _signature_payload: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, + ) -> Option { Some(call) } } From 10bbe1040042bf0ec0a8399a1f59b92357222e7d Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 15 May 2023 23:09:30 +0300 Subject: [PATCH 10/24] frame/metadata: Simplify metadata generation Signed-off-by: Alexandru Vasile --- .../src/construct_runtime/expand/metadata.rs | 94 +++++++------------ 1 file changed, 34 insertions(+), 60 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 14e5f2b30201b..87c5fa24568b7 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -76,65 +76,6 @@ pub fn expand_runtime_metadata( quote! { impl #runtime { - fn extrinsic_metadata_ir() -> #scrate::metadata_ir::ExtrinsicMetadataIR { - let ty = #scrate::scale_info::meta_type::<#extrinsic>(); - - // Inspect the extrinsic type parameters for the following types needed to - // decode extrinsics. - const ADDRESS: &str = "Address"; - const CALL: &str = "Call"; - const SIGNATURE: &str = "Signature"; - const EXTRA: &str = "Extra"; - - let mut address_ty = None; - let mut call_ty = None; - let mut signature_ty = None; - let mut extra_ty = None; - - for ty_param in &ty.type_info().type_params { - let name = ty_param.name; - - if name == ADDRESS { - address_ty = ty_param.ty; - } - if name == CALL { - call_ty = ty_param.ty; - } - if name == SIGNATURE { - signature_ty = ty_param.ty; - } - if name == EXTRA { - extra_ty = ty_param.ty; - } - } - - let address_ty = address_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); - let call_ty = call_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); - let signature_ty = signature_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); - let extra_ty = extra_ty.unwrap_or_else(|| #scrate::scale_info::meta_type::<()>()); - - #scrate::metadata_ir::ExtrinsicMetadataIR { - ty, - version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, - address_ty, - call_ty, - signature_ty, - extra_ty, - signed_extensions: < - < - #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata - >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension - >::metadata() - .into_iter() - .map(|meta| #scrate::metadata_ir::SignedExtensionMetadataIR { - identifier: meta.identifier, - ty: meta.ty, - additional_signed: meta.additional_signed, - }) - .collect(), - } - } - fn metadata_ir() -> #scrate::metadata_ir::MetadataIR { // Each runtime must expose the `runtime_metadata()` to fetch the runtime API metadata. // The function is implemented by calling `impl_runtime_apis!`. @@ -154,9 +95,42 @@ pub fn expand_runtime_metadata( // `Deref` needs a reference for resolving the function call. let rt = #runtime; + let ty = #scrate::scale_info::meta_type::<#extrinsic>(); + let address_ty = #scrate::scale_info::meta_type::< + <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignatureAddress + >(); + let call_ty = #scrate::scale_info::meta_type::< + <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Call + >(); + let signature_ty = #scrate::scale_info::meta_type::< + <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Signature + >(); + let extra_ty = #scrate::scale_info::meta_type::< + <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignatureExtra + >(); + #scrate::metadata_ir::MetadataIR { pallets: #scrate::sp_std::vec![ #(#pallets),* ], - extrinsic: #runtime::extrinsic_metadata_ir(), + extrinsic: #scrate::metadata_ir::ExtrinsicMetadataIR { + ty, + version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, + address_ty, + call_ty, + signature_ty, + extra_ty, + signed_extensions: < + < + #extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata + >::SignedExtensions as #scrate::sp_runtime::traits::SignedExtension + >::metadata() + .into_iter() + .map(|meta| #scrate::metadata_ir::SignedExtensionMetadataIR { + identifier: meta.identifier, + ty: meta.ty, + additional_signed: meta.additional_signed, + }) + .collect(), + }, ty: #scrate::scale_info::meta_type::<#runtime>(), apis: (&rt).runtime_metadata(), } From b823f5c4fbaa2f92bad7fe8e4c86bcdafdf5ea3a Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 15 May 2023 23:32:42 +0300 Subject: [PATCH 11/24] frame/example: Adjust to new interface Signed-off-by: Alexandru Vasile --- frame/examples/offchain-worker/src/tests.rs | 11 +++++++++-- frame/executive/src/lib.rs | 4 ++-- frame/support/test/tests/pallet.rs | 6 +++--- frame/transaction-payment/src/tests.rs | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index 3df7f4a8d5439..dcce41c21351a 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -102,8 +102,15 @@ where _public: ::Signer, _account: AccountId, nonce: u64, - ) -> Option<(RuntimeCall, ::SignaturePayload)> { - Some((call, (nonce, ()))) + ) -> Option<( + RuntimeCall, + ( + ::SignatureAddress, + ::Signature, + ::SignatureExtra, + ), + )> { + Some((call, (nonce, (), ()))) } } diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index fd76fefadff4b..7dc61e20cd741 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -953,8 +953,8 @@ mod tests { ) } - fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { - Some((who, extra(nonce, fee))) + fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, (), SignedExtra)> { + Some((who, (), extra(nonce, fee))) } fn call_transfer(dest: u64, value: u64) -> RuntimeCall { diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index ecf76ce769d4c..adab9131919b9 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -906,7 +906,7 @@ fn inherent_expand() { ), vec![UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: Some((1, Default::default())), + signature: Some((1, (), Default::default())), }], ); @@ -977,7 +977,7 @@ fn inherent_expand() { }, UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), - signature: Some((1, Default::default())), + signature: Some((1, (), Default::default())), }, UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), @@ -1707,7 +1707,7 @@ fn metadata_ir_pallet_runtime_docs() { #[test] fn extrinsic_metadata_ir_types() { - let ir = Runtime::extrinsic_metadata_ir(); + let ir = Runtime::metadata_ir().extrinsic; // `TestXt` used to construct the runtime exposes only the `Call` and `Extra` types. // In contrast, substrate chains expose: `Address`, `Call`, `Signature` and `Extra` types. diff --git a/frame/transaction-payment/src/tests.rs b/frame/transaction-payment/src/tests.rs index d5109609e2975..b3fc94cbba8c6 100644 --- a/frame/transaction-payment/src/tests.rs +++ b/frame/transaction-payment/src/tests.rs @@ -288,7 +288,7 @@ fn query_info_and_fee_details_works() { let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); let origin = 111111; let extra = (); - let xt = TestXt::new(call.clone(), Some((origin, extra))); + let xt = TestXt::new(call.clone(), Some((origin, (), extra))); let info = xt.get_dispatch_info(); let ext = xt.encode(); let len = ext.len() as u32; From a94cd09bec8c1c16d8a0f1d009c30a98c0c81b37 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 16 May 2023 10:49:50 +0300 Subject: [PATCH 12/24] frame/tests: Adjust `extrinsic_metadata_ir_types` Signed-off-by: Alexandru Vasile --- frame/support/test/tests/pallet.rs | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index adab9131919b9..a0b05c891e51d 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -15,8 +15,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::HashMap; - use frame_support::{ assert_ok, dispatch::{ @@ -38,7 +36,7 @@ use sp_io::{ hashing::{blake2_128, twox_128, twox_64}, TestExternalities, }; -use sp_runtime::{DispatchError, ModuleError}; +use sp_runtime::{traits::Extrinsic as ExtrinsicT, DispatchError, ModuleError}; parameter_types! { /// Used to control if the storage version should be updated. @@ -1709,26 +1707,17 @@ fn metadata_ir_pallet_runtime_docs() { fn extrinsic_metadata_ir_types() { let ir = Runtime::metadata_ir().extrinsic; - // `TestXt` used to construct the runtime exposes only the `Call` and `Extra` types. - // In contrast, substrate chains expose: `Address`, `Call`, `Signature` and `Extra` types. - // Any missing type is populated with the tuple type. - let params: HashMap<_, _> = ir - .ty - .type_info() - .type_params - .iter() - .map(|ty_param| (ty_param.name, ty_param.ty.expect("Type params are populated"))) - .collect(); + assert_eq!(meta_type::<::SignatureAddress>(), ir.address_ty); + assert_eq!(meta_type::(), ir.address_ty); - assert!(params.get("Address").is_none()); - let call_ty = params.get("Call").expect("Type `Call` must be present in the extrinsic"); - assert!(params.get("Signature").is_none()); - let extra_ty = params.get("Extra").expect("Type `Extra` must be present in the extrinsic"); + assert_eq!(meta_type::<::Call>(), ir.call_ty); + assert_eq!(meta_type::(), ir.call_ty); - assert_eq!(meta_type::<()>(), ir.address_ty); - assert_eq!(call_ty, &ir.call_ty); + assert_eq!(meta_type::<::Signature>(), ir.signature_ty); assert_eq!(meta_type::<()>(), ir.signature_ty); - assert_eq!(extra_ty, &ir.extra_ty); + + assert_eq!(meta_type::<::SignatureExtra>(), ir.extra_ty); + assert_eq!(meta_type::>(), ir.extra_ty); } #[test] From 86e39c175bd40cb0515abe8e92a3b9d89b3ded6e Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 15:44:09 +0300 Subject: [PATCH 13/24] Revert the additional Extrinsic' associated types Signed-off-by: Alexandru Vasile --- bin/node/runtime/src/lib.rs | 9 +-------- frame/examples/offchain-worker/src/tests.rs | 11 ++--------- frame/executive/src/lib.rs | 4 ++-- frame/system/src/offchain.rs | 15 ++------------- frame/transaction-payment/src/tests.rs | 2 +- primitives/runtime/src/lib.rs | 6 ++---- primitives/runtime/src/testing.rs | 21 +++++++-------------- 7 files changed, 17 insertions(+), 51 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 650caf2e3ccd6..6dc9841f6b44f 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1267,14 +1267,7 @@ where public: ::Signer, account: AccountId, nonce: Index, - ) -> Option<( - RuntimeCall, - ( - ::SignatureAddress, - ::Signature, - ::SignatureExtra, - ), - )> { + ) -> Option<(RuntimeCall, ::SignaturePayload)> { let tip = 0; // take the biggest period possible. let period = diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index dcce41c21351a..3df7f4a8d5439 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -102,15 +102,8 @@ where _public: ::Signer, _account: AccountId, nonce: u64, - ) -> Option<( - RuntimeCall, - ( - ::SignatureAddress, - ::Signature, - ::SignatureExtra, - ), - )> { - Some((call, (nonce, (), ()))) + ) -> Option<(RuntimeCall, ::SignaturePayload)> { + Some((call, (nonce, ()))) } } diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 7dee5493afa9d..31cbb0ee7ba0d 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -956,8 +956,8 @@ mod tests { ) } - fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, (), SignedExtra)> { - Some((who, (), extra(nonce, fee))) + fn sign_extra(who: u64, nonce: u64, fee: Balance) -> Option<(u64, SignedExtra)> { + Some((who, extra(nonce, fee))) } fn call_transfer(dest: u64, value: u64) -> RuntimeCall { diff --git a/frame/system/src/offchain.rs b/frame/system/src/offchain.rs index 927cd1fe51028..742146d1642c8 100644 --- a/frame/system/src/offchain.rs +++ b/frame/system/src/offchain.rs @@ -86,11 +86,7 @@ where /// Submit transaction onchain by providing the call and an optional signature pub fn submit_transaction( call: >::OverarchingCall, - signature: Option<( - ::SignatureAddress, - ::Signature, - ::SignatureExtra, - )>, + signature: Option<::SignaturePayload>, ) -> Result<(), ()> { let xt = T::Extrinsic::new(call, signature).ok_or(())?; sp_io::offchain::submit_transaction(xt.encode()) @@ -491,14 +487,7 @@ pub trait CreateSignedTransaction: public: Self::Public, account: Self::AccountId, nonce: Self::Index, - ) -> Option<( - Self::OverarchingCall, - ( - ::SignatureAddress, - ::Signature, - ::SignatureExtra, - ), - )>; + ) -> Option<(Self::OverarchingCall, ::SignaturePayload)>; } /// A message signer. diff --git a/frame/transaction-payment/src/tests.rs b/frame/transaction-payment/src/tests.rs index b3fc94cbba8c6..d5109609e2975 100644 --- a/frame/transaction-payment/src/tests.rs +++ b/frame/transaction-payment/src/tests.rs @@ -288,7 +288,7 @@ fn query_info_and_fee_details_works() { let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest: 2, value: 69 }); let origin = 111111; let extra = (); - let xt = TestXt::new(call.clone(), Some((origin, (), extra))); + let xt = TestXt::new(call.clone(), Some((origin, extra))); let info = xt.get_dispatch_info(); let ext = xt.encode(); let len = ext.len() as u32; diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 42b0886a2c158..363881e431e0e 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -902,15 +902,13 @@ impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic { { let r = ::sp_core::bytes::deserialize(de)?; Decode::decode(&mut &r[..]) - .map_err(|e: codec::Error| ::serde::de::Error::custom(format!("Decode error: {}", e))) + .map_err(|e| ::serde::de::Error::custom(format!("Decode error: {}", e))) } } impl traits::Extrinsic for OpaqueExtrinsic { type Call = (); - type SignatureAddress = (); - type Signature = (); - type SignatureExtra = (); + type SignaturePayload = (); } /// Print something that implements `Printable` from the runtime. diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index b07753cbc1ba8..6d02e23094f90 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -204,9 +204,7 @@ pub struct ExtrinsicWrapper(Xt); impl traits::Extrinsic for ExtrinsicWrapper { type Call = (); - type SignatureAddress = (); - type Signature = (); - type SignatureExtra = (); + type SignaturePayload = (); fn is_signed(&self) -> Option { None @@ -288,14 +286,14 @@ where #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] pub struct TestXt { /// Signature of the extrinsic. - pub signature: Option<(u64, (), Extra)>, + pub signature: Option<(u64, Extra)>, /// Call of the extrinsic. pub call: Call, } impl TestXt { /// Create a new `TextXt`. - pub fn new(call: Call, signature: Option<(u64, (), Extra)>) -> Self { + pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self { Self { call, signature } } } @@ -335,18 +333,13 @@ impl Checkable for TestXt traits::Extrinsic for TestXt { type Call = Call; - type SignatureAddress = u64; - type Signature = (); - type SignatureExtra = Extra; + type SignaturePayload = (u64, Extra); fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new( - c: Call, - sig: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, - ) -> Option { + fn new(c: Call, sig: Option) -> Option { Some(TestXt { signature: sig, call: c }) } } @@ -383,7 +376,7 @@ where info: &DispatchInfoOf, len: usize, ) -> TransactionValidity { - if let Some((ref id, _, ref extra)) = self.signature { + if let Some((ref id, ref extra)) = self.signature { Extra::validate(extra, id, &self.call, info, len) } else { let valid = Extra::validate_unsigned(&self.call, info, len)?; @@ -399,7 +392,7 @@ where info: &DispatchInfoOf, len: usize, ) -> ApplyExtrinsicResultWithInfo> { - let maybe_who = if let Some((who, _, extra)) = self.signature { + let maybe_who = if let Some((who, extra)) = self.signature { Extra::pre_dispatch(extra, &who, &self.call, info, len)?; Some(who) } else { From 903ebd765342478366e16badc466dc904a6150b1 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 15:47:42 +0300 Subject: [PATCH 14/24] primitives: Add `SignaturePayload` marker trait Signed-off-by: Alexandru Vasile --- primitives/runtime/src/traits.rs | 43 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 21c160325eb63..d284ef1f173b6 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -962,22 +962,14 @@ pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug + 'st /// Something that acts like an `Extrinsic`. pub trait Extrinsic: Sized { /// The function call. - type Call; + type Call: TypeInfo; - /// The type of the address that signed the extrinsic. + /// The payload we carry for signed extrinsics. /// - /// Particular to a signed extrinsic. - type SignatureAddress; - - /// The signature type of the extrinsic. - /// - /// Particular to a signed extrinsic. - type Signature; - - /// The additional data that is specific to the signed extrinsic. - /// - /// Particular to a signed extrinsic. - type SignatureExtra; + /// Usually it will contain a `Signature` and + /// may include some additional data that are specific to signed + /// extrinsics. + type SignaturePayload: SignaturePayload; /// Is this `Extrinsic` signed? /// If no information are available about signed/unsigned, `None` should be returned. @@ -991,14 +983,29 @@ pub trait Extrinsic: Sized { /// 1. Inherents (no signature; created by validators during block production) /// 2. Unsigned Transactions (no signature; represent "system calls" or other special kinds of /// calls) 3. Signed Transactions (with signature; a regular transactions with known origin) - fn new( - _call: Self::Call, - _signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, - ) -> Option { + fn new(_call: Self::Call, _signed_data: Option) -> Option { None } } +/// Something that acts like a `SignaturePayload` of an `Extrinsic. +pub trait SignaturePayload { + /// The type of the address that signed the extrinsic. + /// + /// Particular to a signed extrinsic. + type SignatureAddress: TypeInfo; + + /// The signature type of the extrinsic. + /// + /// Particular to a signed extrinsic. + type Signature: TypeInfo; + + /// The additional data that is specific to the signed extrinsic. + /// + /// Particular to a signed extrinsic. + type SignatureExtra: TypeInfo; +} + /// Implementor is an [`Extrinsic`] and provides metadata about this extrinsic. pub trait ExtrinsicMetadata { /// The format version of the `Extrinsic`. From 37f6a09acd6ba54e6e8c57ce648016420c347874 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 15:49:03 +0300 Subject: [PATCH 15/24] primitives: Implement SignaturePayload for empty tuple Signed-off-by: Alexandru Vasile --- primitives/runtime/src/traits.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index d284ef1f173b6..474f009f24c4d 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -1006,6 +1006,12 @@ pub trait SignaturePayload { type SignatureExtra: TypeInfo; } +impl SignaturePayload for () { + type SignatureAddress = (); + type Signature = (); + type SignatureExtra = (); +} + /// Implementor is an [`Extrinsic`] and provides metadata about this extrinsic. pub trait ExtrinsicMetadata { /// The format version of the `Extrinsic`. From 16b81b63e9229283746eb688f4a5c858f15b0a3c Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 16:04:55 +0300 Subject: [PATCH 16/24] Adjust to new SignaturePayload trait Signed-off-by: Alexandru Vasile --- .../src/construct_runtime/expand/metadata.rs | 6 ++-- frame/support/src/traits/misc.rs | 8 +++-- .../src/generic/unchecked_extrinsic.rs | 30 +++++++++++-------- primitives/runtime/src/testing.rs | 19 +++++++++--- primitives/test-primitives/src/lib.rs | 9 ++---- 5 files changed, 43 insertions(+), 29 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 87c5fa24568b7..2e7fe3e45c2be 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -97,16 +97,16 @@ pub fn expand_runtime_metadata( let ty = #scrate::scale_info::meta_type::<#extrinsic>(); let address_ty = #scrate::scale_info::meta_type::< - <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignatureAddress + <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureAddress >(); let call_ty = #scrate::scale_info::meta_type::< <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Call >(); let signature_ty = #scrate::scale_info::meta_type::< - <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::Signature + <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::Signature >(); let extra_ty = #scrate::scale_info::meta_type::< - <#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignatureExtra + <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureExtra >(); #scrate::metadata_ir::MetadataIR { diff --git a/frame/support/src/traits/misc.rs b/frame/support/src/traits/misc.rs index a6f8c46d63951..85eb7b47e26da 100644 --- a/frame/support/src/traits/misc.rs +++ b/frame/support/src/traits/misc.rs @@ -893,7 +893,8 @@ pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic { #[cfg(feature = "std")] impl ExtrinsicCall for sp_runtime::testing::TestXt where - Call: codec::Codec + Sync + Send, + Call: codec::Codec + Sync + Send + TypeInfo, + Extra: TypeInfo, { fn call(&self) -> &Self::Call { &self.call @@ -903,7 +904,10 @@ where impl ExtrinsicCall for sp_runtime::generic::UncheckedExtrinsic where - Extra: sp_runtime::traits::SignedExtension, + Address: TypeInfo, + Call: TypeInfo, + Signature: TypeInfo, + Extra: sp_runtime::traits::SignedExtension + TypeInfo, { fn call(&self) -> &Self::Call { &self.function diff --git a/primitives/runtime/src/generic/unchecked_extrinsic.rs b/primitives/runtime/src/generic/unchecked_extrinsic.rs index 408d57fb28a1e..0b1cd2b54290e 100644 --- a/primitives/runtime/src/generic/unchecked_extrinsic.rs +++ b/primitives/runtime/src/generic/unchecked_extrinsic.rs @@ -21,7 +21,7 @@ use crate::{ generic::CheckedExtrinsic, traits::{ self, Checkable, Extrinsic, ExtrinsicMetadata, IdentifyAccount, MaybeDisplay, Member, - SignedExtension, + SignaturePayload, SignedExtension, }, transaction_validity::{InvalidTransaction, TransactionValidityError}, OpaqueExtrinsic, @@ -40,6 +40,9 @@ use sp_std::{fmt, prelude::*}; /// the decoding fails. const EXTRINSIC_FORMAT_VERSION: u8 = 4; +/// The `SingaturePayload` of `UncheckedExtrinsic`. +type UncheckedSignaturePayload = (Address, Signature, Extra); + /// A extrinsic right from the external world. This is unchecked and so /// can contain a signature. #[derive(PartialEq, Eq, Clone)] @@ -50,11 +53,19 @@ where /// The signature, address, number of extrinsics have come before from /// the same signer and an era describing the longevity of this transaction, /// if this is a signed extrinsic. - pub signature: Option<(Address, Signature, Extra)>, + pub signature: Option>, /// The function that should be called. pub function: Call, } +impl SignaturePayload + for UncheckedSignaturePayload +{ + type SignatureAddress = Address; + type Signature = Signature; + type SignatureExtra = Extra; +} + /// Manual [`TypeInfo`] implementation because of custom encoding. The data is a valid encoded /// `Vec`, but requires some logic to extract the signature and payload. /// @@ -103,25 +114,18 @@ impl } } -impl Extrinsic - for UncheckedExtrinsic +impl + Extrinsic for UncheckedExtrinsic { type Call = Call; - type SignatureAddress = Address; - - type Signature = Signature; - - type SignatureExtra = Extra; + type SignaturePayload = UncheckedSignaturePayload; fn is_signed(&self) -> Option { Some(self.signature.is_some()) } - fn new( - function: Call, - signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, - ) -> Option { + fn new(function: Call, signed_data: Option) -> Option { Some(if let Some((address, signature, extra)) = signed_data { Self::new_signed(function, address, signature, extra) } else { diff --git a/primitives/runtime/src/testing.rs b/primitives/runtime/src/testing.rs index 6d02e23094f90..abf4d81634691 100644 --- a/primitives/runtime/src/testing.rs +++ b/primitives/runtime/src/testing.rs @@ -23,7 +23,7 @@ use crate::{ scale_info::TypeInfo, traits::{ self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys, - PostDispatchInfoOf, SignedExtension, ValidateUnsigned, + PostDispatchInfoOf, SignaturePayload, SignedExtension, ValidateUnsigned, }, transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError}, ApplyExtrinsicResultWithInfo, KeyTypeId, @@ -279,6 +279,15 @@ where } } +/// The signature payload of a `TestXt`. +type TxSingaturePayload = (u64, Extra); + +impl SignaturePayload for TxSingaturePayload { + type SignatureAddress = u64; + type Signature = (); + type SignatureExtra = Extra; +} + /// Test transaction, tuple of (sender, call, signed_extra) /// with index only used if sender is some. /// @@ -286,7 +295,7 @@ where #[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] pub struct TestXt { /// Signature of the extrinsic. - pub signature: Option<(u64, Extra)>, + pub signature: Option>, /// Call of the extrinsic. pub call: Call, } @@ -331,9 +340,11 @@ impl Checkable for TestXt traits::Extrinsic for TestXt { +impl traits::Extrinsic + for TestXt +{ type Call = Call; - type SignaturePayload = (u64, Extra); + type SignaturePayload = TxSingaturePayload; fn is_signed(&self) -> Option { Some(self.signature.is_some()) diff --git a/primitives/test-primitives/src/lib.rs b/primitives/test-primitives/src/lib.rs index abf9732dcf4b8..913cb762d92a5 100644 --- a/primitives/test-primitives/src/lib.rs +++ b/primitives/test-primitives/src/lib.rs @@ -47,9 +47,7 @@ impl serde::Serialize for Extrinsic { impl ExtrinsicT for Extrinsic { type Call = Extrinsic; - type SignatureAddress = (); - type Signature = (); - type SignatureExtra = (); + type SignaturePayload = (); fn is_signed(&self) -> Option { if let Extrinsic::IncludeData(_) = *self { @@ -59,10 +57,7 @@ impl ExtrinsicT for Extrinsic { } } - fn new( - call: Self::Call, - _signature_payload: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>, - ) -> Option { + fn new(call: Self::Call, _signature_payload: Option) -> Option { Some(call) } } From cd5c0a3faa9429896b115917e50b75fa78d3e819 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 16:39:55 +0300 Subject: [PATCH 17/24] tests: Adjust `extrinsic_metadata_ir_types` to new interface Signed-off-by: Alexandru Vasile --- frame/support/test/tests/pallet.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 259736ccaf9ed..4109d81f4948c 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -36,7 +36,10 @@ use sp_io::{ hashing::{blake2_128, twox_128, twox_64}, TestExternalities, }; -use sp_runtime::{traits::Extrinsic as ExtrinsicT, DispatchError, ModuleError}; +use sp_runtime::{ + traits::{Extrinsic as ExtrinsicT, SignaturePayload as SignaturePayloadT}, + DispatchError, ModuleError, +}; parameter_types! { /// Used to control if the storage version should be updated. @@ -1707,16 +1710,21 @@ fn metadata_ir_pallet_runtime_docs() { fn extrinsic_metadata_ir_types() { let ir = Runtime::metadata_ir().extrinsic; - assert_eq!(meta_type::<::SignatureAddress>(), ir.address_ty); + assert_eq!(meta_type::<<::SignaturePayload as SignaturePayloadT>::SignatureAddress>(), ir.address_ty); assert_eq!(meta_type::(), ir.address_ty); assert_eq!(meta_type::<::Call>(), ir.call_ty); assert_eq!(meta_type::(), ir.call_ty); - assert_eq!(meta_type::<::Signature>(), ir.signature_ty); + assert_eq!( + meta_type::< + <::SignaturePayload as SignaturePayloadT>::Signature, + >(), + ir.signature_ty + ); assert_eq!(meta_type::<()>(), ir.signature_ty); - assert_eq!(meta_type::<::SignatureExtra>(), ir.extra_ty); + assert_eq!(meta_type::<<::SignaturePayload as SignaturePayloadT>::SignatureExtra>(), ir.extra_ty); assert_eq!(meta_type::>(), ir.extra_ty); } From 60db7bc80b030bd27870db15a6b404663e0e4ad0 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Mon, 29 May 2023 17:06:26 +0300 Subject: [PATCH 18/24] frame/support: Adjust pallet test Signed-off-by: Alexandru Vasile --- frame/support/test/tests/pallet.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 4109d81f4948c..f13f06cf0795e 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -907,7 +907,7 @@ fn inherent_expand() { ), vec![UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), - signature: Some((1, (), Default::default())), + signature: Some((1, Default::default())), }], ); @@ -978,7 +978,7 @@ fn inherent_expand() { }, UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo { foo: 1, bar: 0 }), - signature: Some((1, (), Default::default())), + signature: Some((1, Default::default())), }, UncheckedExtrinsic { call: RuntimeCall::Example(pallet::Call::foo_no_post_info {}), From 6e4f7491302bcea9a4806fa9702bdbac53c4b017 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 30 May 2023 14:39:41 +0300 Subject: [PATCH 19/24] frame: Add Extrinsic length prefix to the metadata Signed-off-by: Alexandru Vasile --- Cargo.lock | 2 +- .../procedural/src/construct_runtime/expand/metadata.rs | 2 ++ primitives/metadata-ir/src/types.rs | 7 +++++++ primitives/metadata-ir/src/v15.rs | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee9a3ba5f577f..6545028197a2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2634,7 +2634,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "15.1.0" -source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#5a14aacd2fcf01b2ec1689acd3575088fab2d62a" +source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#b3de61b949a9fa57e599a642b4d70aab8c91fa28" dependencies = [ "cfg-if", "parity-scale-codec", diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 2e7fe3e45c2be..377d38006fe11 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -108,12 +108,14 @@ pub fn expand_runtime_metadata( let extra_ty = #scrate::scale_info::meta_type::< <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureExtra >(); + let len_ty = #scrate::scale_info::meta_type::<#scrate::codec::Compact>(); #scrate::metadata_ir::MetadataIR { pallets: #scrate::sp_std::vec![ #(#pallets),* ], extrinsic: #scrate::metadata_ir::ExtrinsicMetadataIR { ty, version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, + len_ty, address_ty, call_ty, signature_ty, diff --git a/primitives/metadata-ir/src/types.rs b/primitives/metadata-ir/src/types.rs index 4cf2c165e3798..196d6ba969222 100644 --- a/primitives/metadata-ir/src/types.rs +++ b/primitives/metadata-ir/src/types.rs @@ -153,9 +153,15 @@ impl IntoPortable for PalletMetadataIR { #[derive(Clone, PartialEq, Eq, Encode, Debug)] pub struct ExtrinsicMetadataIR { /// The type of the extrinsic. + /// + /// Note: Field used for metadata V14 only. pub ty: T::Type, /// Extrinsic version. pub version: u8, + /// The prefix of the extrinsic. + /// + /// This is the type of the encoded length of this extrinsic. + pub len_ty: T::Type, /// The type of the address that signes the extrinsic pub address_ty: T::Type, /// The type of the outermost Call enum. @@ -175,6 +181,7 @@ impl IntoPortable for ExtrinsicMetadataIR { ExtrinsicMetadataIR { ty: registry.register_type(&self.ty), version: self.version, + len_ty: registry.register_type(&self.len_ty), address_ty: registry.register_type(&self.address_ty), call_ty: registry.register_type(&self.call_ty), signature_ty: registry.register_type(&self.signature_ty), diff --git a/primitives/metadata-ir/src/v15.rs b/primitives/metadata-ir/src/v15.rs index 098e627ba608d..55eb474372958 100644 --- a/primitives/metadata-ir/src/v15.rs +++ b/primitives/metadata-ir/src/v15.rs @@ -180,8 +180,8 @@ impl From for SignedExtensionMetadata { impl From for ExtrinsicMetadata { fn from(ir: ExtrinsicMetadataIR) -> Self { ExtrinsicMetadata { - ty: ir.ty, version: ir.version, + len_ty: ir.len_ty, address_ty: ir.address_ty, call_ty: ir.call_ty, signature_ty: ir.signature_ty, From 0ad90f3267f642cff90ca85bb879d1acadf5efd8 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Tue, 30 May 2023 15:01:41 +0300 Subject: [PATCH 20/24] primitives: Populate `ExtrinsicMetadataIR` with `len_ty` Signed-off-by: Alexandru Vasile --- primitives/metadata-ir/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/primitives/metadata-ir/src/lib.rs b/primitives/metadata-ir/src/lib.rs index 0e9b0d6c397d3..2762144d889c2 100644 --- a/primitives/metadata-ir/src/lib.rs +++ b/primitives/metadata-ir/src/lib.rs @@ -81,6 +81,7 @@ mod test { extrinsic: ExtrinsicMetadataIR { ty: meta_type::<()>(), version: 0, + len_ty: meta_type::<()>(), address_ty: meta_type::<()>(), call_ty: meta_type::<()>(), signature_ty: meta_type::<()>(), From 7d55ba19d99102624378af4312347c75f0df59c3 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com> Date: Fri, 2 Jun 2023 14:46:01 +0300 Subject: [PATCH 21/24] Update primitives/runtime/src/traits.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bastian Köcher --- primitives/runtime/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 474f009f24c4d..650e7b8d48eb8 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -988,7 +988,7 @@ pub trait Extrinsic: Sized { } } -/// Something that acts like a `SignaturePayload` of an `Extrinsic. +/// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an [`Extrinsic`]. pub trait SignaturePayload { /// The type of the address that signed the extrinsic. /// From 03383be22b2851b9dcfc67590034efb73018b1bf Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Fri, 2 Jun 2023 18:46:20 +0300 Subject: [PATCH 22/24] Apply cargo fmt Signed-off-by: Alexandru Vasile --- primitives/runtime/src/traits.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 650e7b8d48eb8..2804773214f91 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -988,7 +988,8 @@ pub trait Extrinsic: Sized { } } -/// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an [`Extrinsic`]. +/// Something that acts like a [`SignaturePayload`](Extrinsic::SignaturePayload) of an +/// [`Extrinsic`]. pub trait SignaturePayload { /// The type of the address that signed the extrinsic. /// From 0e8731350c9dcaf4693502f26d5d66cca89957c5 Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Fri, 2 Jun 2023 18:47:16 +0300 Subject: [PATCH 23/24] v15: Remove len type of the extrinsic Signed-off-by: Alexandru Vasile --- .../procedural/src/construct_runtime/expand/metadata.rs | 2 -- primitives/metadata-ir/src/lib.rs | 1 - primitives/metadata-ir/src/types.rs | 5 ----- primitives/metadata-ir/src/v15.rs | 1 - 4 files changed, 9 deletions(-) diff --git a/frame/support/procedural/src/construct_runtime/expand/metadata.rs b/frame/support/procedural/src/construct_runtime/expand/metadata.rs index 377d38006fe11..2e7fe3e45c2be 100644 --- a/frame/support/procedural/src/construct_runtime/expand/metadata.rs +++ b/frame/support/procedural/src/construct_runtime/expand/metadata.rs @@ -108,14 +108,12 @@ pub fn expand_runtime_metadata( let extra_ty = #scrate::scale_info::meta_type::< <<#extrinsic as #scrate::sp_runtime::traits::Extrinsic>::SignaturePayload as #scrate::sp_runtime::traits::SignaturePayload>::SignatureExtra >(); - let len_ty = #scrate::scale_info::meta_type::<#scrate::codec::Compact>(); #scrate::metadata_ir::MetadataIR { pallets: #scrate::sp_std::vec![ #(#pallets),* ], extrinsic: #scrate::metadata_ir::ExtrinsicMetadataIR { ty, version: <#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata>::VERSION, - len_ty, address_ty, call_ty, signature_ty, diff --git a/primitives/metadata-ir/src/lib.rs b/primitives/metadata-ir/src/lib.rs index 2762144d889c2..0e9b0d6c397d3 100644 --- a/primitives/metadata-ir/src/lib.rs +++ b/primitives/metadata-ir/src/lib.rs @@ -81,7 +81,6 @@ mod test { extrinsic: ExtrinsicMetadataIR { ty: meta_type::<()>(), version: 0, - len_ty: meta_type::<()>(), address_ty: meta_type::<()>(), call_ty: meta_type::<()>(), signature_ty: meta_type::<()>(), diff --git a/primitives/metadata-ir/src/types.rs b/primitives/metadata-ir/src/types.rs index 196d6ba969222..d308b5ef4c55f 100644 --- a/primitives/metadata-ir/src/types.rs +++ b/primitives/metadata-ir/src/types.rs @@ -158,10 +158,6 @@ pub struct ExtrinsicMetadataIR { pub ty: T::Type, /// Extrinsic version. pub version: u8, - /// The prefix of the extrinsic. - /// - /// This is the type of the encoded length of this extrinsic. - pub len_ty: T::Type, /// The type of the address that signes the extrinsic pub address_ty: T::Type, /// The type of the outermost Call enum. @@ -181,7 +177,6 @@ impl IntoPortable for ExtrinsicMetadataIR { ExtrinsicMetadataIR { ty: registry.register_type(&self.ty), version: self.version, - len_ty: registry.register_type(&self.len_ty), address_ty: registry.register_type(&self.address_ty), call_ty: registry.register_type(&self.call_ty), signature_ty: registry.register_type(&self.signature_ty), diff --git a/primitives/metadata-ir/src/v15.rs b/primitives/metadata-ir/src/v15.rs index 55eb474372958..3c671673df777 100644 --- a/primitives/metadata-ir/src/v15.rs +++ b/primitives/metadata-ir/src/v15.rs @@ -181,7 +181,6 @@ impl From for ExtrinsicMetadata { fn from(ir: ExtrinsicMetadataIR) -> Self { ExtrinsicMetadata { version: ir.version, - len_ty: ir.len_ty, address_ty: ir.address_ty, call_ty: ir.call_ty, signature_ty: ir.signature_ty, From 2c307b8e41396775bd4df471384c7ac7d077a5fb Mon Sep 17 00:00:00 2001 From: Alexandru Vasile Date: Fri, 2 Jun 2023 18:47:58 +0300 Subject: [PATCH 24/24] cargo: Update frame-metadata Signed-off-by: Alexandru Vasile --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 6545028197a2c..8f9656cff445c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2634,7 +2634,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "15.1.0" -source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#b3de61b949a9fa57e599a642b4d70aab8c91fa28" +source = "git+https://github.com/paritytech/frame-metadata.git?branch=lexnv/extrinsic_decode_info#04213d23e314ab6e42e5840f94787aaede60b627" dependencies = [ "cfg-if", "parity-scale-codec",