Metadata V15: Enrich extrinsic type info for decoding (#14123)

* metadata-ir: Add extrinsic type info to decode address, call, sig

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame-metadata: Point to unreleased branch

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* metadata-ir: Include addrees, call, signature in V15 conversion

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* metadata-ir: Include extra ty

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* construct_runtime: Extract address,call,sig,extra ty from tx type

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/tests: Check metadata populates xt types correctly

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* metadata-ir/tests: Add extra fields on ExtrinsicMetadataIR

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives/traits: Expand the `Extrinsic::SignaturePayload`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives: Adjust to new `Extrinsic` associated types

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/metadata: Simplify metadata generation

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/example: Adjust to new interface

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/tests: Adjust `extrinsic_metadata_ir_types`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Revert the additional Extrinsic' associated types

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives: Add `SignaturePayload` marker trait

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives: Implement SignaturePayload for empty tuple

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Adjust to new SignaturePayload trait

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* tests: Adjust `extrinsic_metadata_ir_types` to new interface

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame/support: Adjust pallet test

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* frame: Add Extrinsic length prefix to the metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* primitives: Populate `ExtrinsicMetadataIR` with `len_ty`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* Update primitives/runtime/src/traits.rs

Co-authored-by: Bastian Köcher <git@kchr.de>

* Apply cargo fmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* v15: Remove len type of the extrinsic

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* cargo: Update frame-metadata

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

---------

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: parity-processbot <>
This commit is contained in:
Alexandru Vasile
2023-06-28 15:44:20 +03:00
committed by GitHub
parent b4e863c472
commit 943697fa69
9 changed files with 131 additions and 21 deletions
@@ -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> = (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<UncheckedSignaturePayload<Address, Signature, Extra>>,
/// The function that should be called.
pub function: Call,
}
impl<Address: TypeInfo, Signature: TypeInfo, Extra: TypeInfo> SignaturePayload
for UncheckedSignaturePayload<Address, Signature, Extra>
{
type SignatureAddress = Address;
type Signature = Signature;
type SignatureExtra = Extra;
}
/// Manual [`TypeInfo`] implementation because of custom encoding. The data is a valid encoded
/// `Vec<u8>`, but requires some logic to extract the signature and payload.
///
@@ -103,12 +114,12 @@ impl<Address, Call, Signature, Extra: SignedExtension>
}
}
impl<Address, Call, Signature, Extra: SignedExtension> Extrinsic
for UncheckedExtrinsic<Address, Call, Signature, Extra>
impl<Address: TypeInfo, Call: TypeInfo, Signature: TypeInfo, Extra: SignedExtension + TypeInfo>
Extrinsic for UncheckedExtrinsic<Address, Call, Signature, Extra>
{
type Call = Call;
type SignaturePayload = (Address, Signature, Extra);
type SignaturePayload = UncheckedSignaturePayload<Address, Signature, Extra>;
fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
+15 -4
View File
@@ -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<Extra> = (u64, Extra);
impl<Extra: TypeInfo> SignaturePayload for TxSingaturePayload<Extra> {
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<Call, Extra> {
/// Signature of the extrinsic.
pub signature: Option<(u64, Extra)>,
pub signature: Option<TxSingaturePayload<Extra>>,
/// Call of the extrinsic.
pub call: Call,
}
@@ -331,9 +340,11 @@ impl<Call: Codec + Sync + Send, Context, Extra> Checkable<Context> for TestXt<Ca
}
}
impl<Call: Codec + Sync + Send, Extra> traits::Extrinsic for TestXt<Call, Extra> {
impl<Call: Codec + Sync + Send + TypeInfo, Extra: TypeInfo> traits::Extrinsic
for TestXt<Call, Extra>
{
type Call = Call;
type SignaturePayload = (u64, Extra);
type SignaturePayload = TxSingaturePayload<Extra>;
fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
+27 -2
View File
@@ -1242,14 +1242,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 payload we carry for signed extrinsics.
///
/// Usually it will contain a `Signature` and
/// may include some additional data that are specific to signed
/// extrinsics.
type SignaturePayload;
type SignaturePayload: SignaturePayload;
/// Is this `Extrinsic` signed?
/// If no information are available about signed/unsigned, `None` should be returned.
@@ -1268,6 +1268,31 @@ pub trait Extrinsic: Sized {
}
}
/// Something that acts like a [`SignaturePayload`](Extrinsic::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;
}
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`.