Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Metadata V15: Enrich extrinsic type info for decoding #14123

Merged
merged 29 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
da550a7
metadata-ir: Add extrinsic type info to decode address, call, sig
lexnv May 11, 2023
a51ea7b
frame-metadata: Point to unreleased branch
lexnv May 11, 2023
888ce4a
metadata-ir: Include addrees, call, signature in V15 conversion
lexnv May 11, 2023
49995b4
metadata-ir: Include extra ty
lexnv May 11, 2023
0babb53
construct_runtime: Extract address,call,sig,extra ty from tx type
lexnv May 11, 2023
768c515
frame/tests: Check metadata populates xt types correctly
lexnv May 11, 2023
ab66814
metadata-ir/tests: Add extra fields on ExtrinsicMetadataIR
lexnv May 11, 2023
52f1480
Merge remote-tracking branch 'origin/master' into lexnv/extrinsic_dec…
lexnv May 11, 2023
6610ac2
primitives/traits: Expand the `Extrinsic::SignaturePayload`
lexnv May 15, 2023
25617e0
primitives: Adjust to new `Extrinsic` associated types
lexnv May 15, 2023
10bbe10
frame/metadata: Simplify metadata generation
lexnv May 15, 2023
b823f5c
frame/example: Adjust to new interface
lexnv May 15, 2023
a94cd09
frame/tests: Adjust `extrinsic_metadata_ir_types`
lexnv May 16, 2023
1f17361
Merge remote-tracking branch 'origin/master' into lexnv/extrinsic_dec…
lexnv May 29, 2023
86e39c1
Revert the additional Extrinsic' associated types
lexnv May 29, 2023
903ebd7
primitives: Add `SignaturePayload` marker trait
lexnv May 29, 2023
37f6a09
primitives: Implement SignaturePayload for empty tuple
lexnv May 29, 2023
16b81b6
Adjust to new SignaturePayload trait
lexnv May 29, 2023
cd5c0a3
tests: Adjust `extrinsic_metadata_ir_types` to new interface
lexnv May 29, 2023
60db7bc
frame/support: Adjust pallet test
lexnv May 29, 2023
6e4f749
frame: Add Extrinsic length prefix to the metadata
lexnv May 30, 2023
0ad90f3
primitives: Populate `ExtrinsicMetadataIR` with `len_ty`
lexnv May 30, 2023
7d55ba1
Update primitives/runtime/src/traits.rs
lexnv Jun 2, 2023
03383be
Apply cargo fmt
lexnv Jun 2, 2023
0e87313
v15: Remove len type of the extrinsic
lexnv Jun 2, 2023
2c307b8
cargo: Update frame-metadata
lexnv Jun 2, 2023
e183783
Merge remote-tracking branch 'origin/master' into lexnv/extrinsic_dec…
lexnv Jun 2, 2023
1747586
Merge remote-tracking branch 'origin/master' into lexnv/extrinsic_dec…
Jun 5, 2023
9fd69cd
Merge remote-tracking branch 'origin/master' into lexnv/extrinsic_dec…
lexnv Jun 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,14 @@ where
public: <Signature as traits::Verify>::Signer,
account: AccountId,
nonce: Index,
) -> Option<(RuntimeCall, <UncheckedExtrinsic as traits::Extrinsic>::SignaturePayload)> {
) -> Option<(
RuntimeCall,
(
<UncheckedExtrinsic as traits::Extrinsic>::SignatureAddress,
<UncheckedExtrinsic as traits::Extrinsic>::Signature,
<UncheckedExtrinsic as traits::Extrinsic>::SignatureExtra,
),
)> {
let tip = 0;
// take the biggest period possible.
let period =
Expand Down
11 changes: 9 additions & 2 deletions frame/examples/offchain-worker/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,15 @@ where
_public: <Signature as Verify>::Signer,
_account: AccountId,
nonce: u64,
) -> Option<(RuntimeCall, <Extrinsic as ExtrinsicT>::SignaturePayload)> {
Some((call, (nonce, ())))
) -> Option<(
RuntimeCall,
(
<Extrinsic as ExtrinsicT>::SignatureAddress,
<Extrinsic as ExtrinsicT>::Signature,
<Extrinsic as ExtrinsicT>::SignatureExtra,
),
)> {
Some((call, (nonce, (), ())))
}
}

Expand Down
4 changes: 2 additions & 2 deletions frame/executive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion frame/support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,29 @@ 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: #scrate::metadata_ir::ExtrinsicMetadataIR {
ty: #scrate::scale_info::meta_type::<#extrinsic>(),
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
Expand Down
24 changes: 20 additions & 4 deletions frame/support/test/tests/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,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.
Expand Down Expand Up @@ -904,7 +904,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())),
}],
);

Expand Down Expand Up @@ -975,7 +975,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 {}),
Expand Down Expand Up @@ -1703,6 +1703,23 @@ fn metadata_ir_pallet_runtime_docs() {
assert_eq!(pallet.docs, expected);
}

#[test]
fn extrinsic_metadata_ir_types() {
let ir = Runtime::metadata_ir().extrinsic;

assert_eq!(meta_type::<<UncheckedExtrinsic as ExtrinsicT>::SignatureAddress>(), ir.address_ty);
assert_eq!(meta_type::<u64>(), ir.address_ty);

assert_eq!(meta_type::<<UncheckedExtrinsic as ExtrinsicT>::Call>(), ir.call_ty);
assert_eq!(meta_type::<RuntimeCall>(), ir.call_ty);

assert_eq!(meta_type::<<UncheckedExtrinsic as ExtrinsicT>::Signature>(), ir.signature_ty);
assert_eq!(meta_type::<()>(), ir.signature_ty);

assert_eq!(meta_type::<<UncheckedExtrinsic as ExtrinsicT>::SignatureExtra>(), ir.extra_ty);
assert_eq!(meta_type::<frame_system::CheckNonZeroSender<Runtime>>(), ir.extra_ty);
}

#[test]
fn test_pallet_runtime_docs() {
let docs = crate::pallet::Pallet::<Runtime>::pallet_documentation_metadata();
Expand All @@ -1716,7 +1733,6 @@ fn test_pallet_info_access() {
assert_eq!(<System as frame_support::traits::PalletInfoAccess>::name(), "System");
assert_eq!(<Example as frame_support::traits::PalletInfoAccess>::name(), "Example");
assert_eq!(<Example2 as frame_support::traits::PalletInfoAccess>::name(), "Example2");

assert_eq!(<System as frame_support::traits::PalletInfoAccess>::index(), 0);
assert_eq!(<Example as frame_support::traits::PalletInfoAccess>::index(), 1);
assert_eq!(<Example2 as frame_support::traits::PalletInfoAccess>::index(), 2);
Expand Down
15 changes: 13 additions & 2 deletions frame/system/src/offchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ where
/// Submit transaction onchain by providing the call and an optional signature
pub fn submit_transaction(
call: <T as SendTransactionTypes<LocalCall>>::OverarchingCall,
signature: Option<<T::Extrinsic as ExtrinsicT>::SignaturePayload>,
signature: Option<(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get why we have to break down SignaturePayload? can't this have TypeInfo itself?

And if it is being broken down and not used, I rather actually delete SignaturePayload if it is not being used anymore.

<T::Extrinsic as ExtrinsicT>::SignatureAddress,
<T::Extrinsic as ExtrinsicT>::Signature,
<T::Extrinsic as ExtrinsicT>::SignatureExtra,
)>,
) -> Result<(), ()> {
let xt = T::Extrinsic::new(call, signature).ok_or(())?;
sp_io::offchain::submit_transaction(xt.encode())
Expand Down Expand Up @@ -487,7 +491,14 @@ pub trait CreateSignedTransaction<LocalCall>:
public: Self::Public,
account: Self::AccountId,
nonce: Self::Index,
) -> Option<(Self::OverarchingCall, <Self::Extrinsic as ExtrinsicT>::SignaturePayload)>;
) -> Option<(
Self::OverarchingCall,
(
<Self::Extrinsic as ExtrinsicT>::SignatureAddress,
<Self::Extrinsic as ExtrinsicT>::Signature,
<Self::Extrinsic as ExtrinsicT>::SignatureExtra,
),
)>;
}

/// A message signer.
Expand Down
2 changes: 1 addition & 1 deletion frame/transaction-payment/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion primitives/metadata-ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }

Expand Down
4 changes: 4 additions & 0 deletions primitives/metadata-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<()>(),
Expand Down
12 changes: 12 additions & 0 deletions primitives/metadata-ir/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ pub struct ExtrinsicMetadataIR<T: Form = MetaForm> {
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 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<SignedExtensionMetadataIR<T>>,
}
Expand All @@ -167,6 +175,10 @@ 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),
extra_ty: registry.register_type(&self.extra_ty),
signed_extensions: registry.map_into_portable(self.signed_extensions),
}
}
Expand Down
4 changes: 4 additions & 0 deletions primitives/metadata-ir/src/v15.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ impl From<ExtrinsicMetadataIR> for ExtrinsicMetadata {
ExtrinsicMetadata {
ty: ir.ty,
version: ir.version,
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(),
}
}
Expand Down
11 changes: 9 additions & 2 deletions primitives/runtime/src/generic/unchecked_extrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,20 @@ impl<Address, Call, Signature, Extra: SignedExtension> Extrinsic
{
type Call = Call;

type SignaturePayload = (Address, Signature, Extra);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh, it is being done already 🙈

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, a type SignaturePayloadOf<E> = (<E as Extrinsic>::X, <E as Extrinsic>::Y, <E as Extrinsic>::Z) will help prevent potential error where the order of these 3 might be mistaken.

type SignatureAddress = Address;

type Signature = Signature;

type SignatureExtra = Extra;

fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
}

fn new(function: Call, signed_data: Option<Self::SignaturePayload>) -> Option<Self> {
fn new(
function: Call,
signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>,
) -> Option<Self> {
Some(if let Some((address, signature, extra)) = signed_data {
Self::new_signed(function, address, signature, extra)
} else {
Expand Down
6 changes: 4 additions & 2 deletions primitives/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
21 changes: 14 additions & 7 deletions primitives/runtime/src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ pub struct ExtrinsicWrapper<Xt>(Xt);

impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> {
type Call = ();
type SignaturePayload = ();
type SignatureAddress = ();
type Signature = ();
type SignatureExtra = ();

fn is_signed(&self) -> Option<bool> {
None
Expand Down Expand Up @@ -286,14 +288,14 @@ 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<(u64, (), Extra)>,
/// Call of the extrinsic.
pub call: Call,
}

impl<Call, Extra> TestXt<Call, Extra> {
/// 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 }
}
}
Expand Down Expand Up @@ -333,13 +335,18 @@ impl<Call: Codec + Sync + Send, Context, Extra> Checkable<Context> for TestXt<Ca

impl<Call: Codec + Sync + Send, Extra> traits::Extrinsic for TestXt<Call, Extra> {
type Call = Call;
type SignaturePayload = (u64, Extra);
type SignatureAddress = u64;
type Signature = ();
type SignatureExtra = Extra;

fn is_signed(&self) -> Option<bool> {
Some(self.signature.is_some())
}

fn new(c: Call, sig: Option<Self::SignaturePayload>) -> Option<Self> {
fn new(
c: Call,
sig: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>,
) -> Option<Self> {
Some(TestXt { signature: sig, call: c })
}
}
Expand Down Expand Up @@ -376,7 +383,7 @@ where
info: &DispatchInfoOf<Self::Call>,
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)?;
Expand All @@ -392,7 +399,7 @@ where
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
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 {
Expand Down
23 changes: 17 additions & 6 deletions primitives/runtime/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of breaking most of the code we could just do

type SignaturePayload: SignaturePayload;
trait SignaturePayload {
      type Address: TypeInfo;
      type Signature: TypeInfo;
      type Extra: TypeInfo;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I like this approach more! Thanks for the feedback!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bkchr What's your opinion on having the extrinsic.ty in the metadata after this change (the message James mentioned above)?

We should have enough type info by relying on:

  • address_ty
  • call_ty
  • signature_ty
  • extra_ty

The extrinsic.ty has a manual implementation of TypeInfo that adds the above ty as generic types, but since we explicitly expose that info with this PR, I believe we should remove the extrinsic.ty.

That is unless we'll break other things

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea if someone is using this. However, frankly speaking by only having the types you listed you don't know the encoding of the Extrinsic type. While currently it may also already not being correct as it probably doesn't include the Compact<u32> length in from of the extrinsinc encoding?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I'll add the TypeDefCompact<u32> type to the extrinsic metadata to provide even better decoding abilities to end users. Considering this, I'll remove the extrinsic_ty from the metadata, unless encountering some edge-cases from UX teams.

The type only contained the address, call, signature and extra on its type info definition, and users should be able to obtain those details (and more) directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iirc the extrinsic type was quite useless anyway before; it mostly just said "hey we want to encode the extrinsic to some vec of bytes". It doesn't provide any useful information on how those bytes need to be formed etc.

There are already a bunch of things we must just assume already about encoding extrinsics, ie the order of the signature stuff, how the not-really-scale Option for the signature is encoded (ie it has a version number &&'d to it) etc. I've always assumed this format information to be encoded in the tx version (4 atm); if a transaction has this version, it must be encoded in this way.

The metadata, in my mind, only needs to provide the information that might vary from chain to chain (eg the actual additional params etc). This tx version can encode the actual format that this stuff is turned into an extrinsic.

All of this to say, what would adding a TypeDefCompact<u32> to the metadata help with? I'd assume it to be part of the V4 extrinsic format I guess, but perhaps I'm wrong on this :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are already a bunch of things we must just assume already about encoding extrinsics, ie the order of the signature stuff, how the not-really-scale Option for the signature is encoded (ie it has a version number &&'d to it) etc. I've always assumed this format information to be encoded in the tx version (4 atm); if a transaction has this version, it must be encoded in this way.

Good point.

The metadata, in my mind, only needs to provide the information that might vary from chain to chain (eg the actual additional params etc). This tx version can encode the actual format that this stuff is turned into an extrinsic.

Just because every body is currently using our UncheckedExtrinsic doesn't mean that this will always be the case. However, it makes sense that this is a type that we can not depict in as type metadata.

/// 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.
Expand All @@ -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<Self::SignaturePayload>) -> Option<Self> {
fn new(
_call: Self::Call,
_signed_data: Option<(Self::SignatureAddress, Self::Signature, Self::SignatureExtra)>,
) -> Option<Self> {
None
}
}
Expand Down
Loading