Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple transaction extension version in UncheckedExtrinsic type. #7035

Open
wants to merge 33 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b5c95b1
WIP
gui1117 Dec 12, 2024
582cbb9
WIP
gui1117 Dec 15, 2024
32159f9
WIP
gui1117 Dec 15, 2024
2350e93
WIP
gui1117 Dec 16, 2024
143b50a
WIP
gui1117 Dec 16, 2024
17a8dc0
cleanup
gui1117 Dec 16, 2024
a38fac3
WIP
gui1117 Dec 17, 2024
3f657ac
WIP
gui1117 Dec 17, 2024
06da89b
Structure done: todo: renames and format
gui1117 Dec 18, 2024
b03b4eb
Merge remote-tracking branch 'origin/master' into gui-transaction-ext…
gui1117 Dec 23, 2024
cfddfa1
renames
gui1117 Dec 23, 2024
3aacd46
reorganize
gui1117 Dec 24, 2024
e060cac
fixes
gui1117 Dec 24, 2024
2c1e2fc
description draft
gui1117 Dec 24, 2024
d39156e
Merge remote-tracking branch 'origin/master' into gui-transaction-ext…
gui1117 Jan 6, 2025
0cc8f0c
refactor
gui1117 Jan 6, 2025
049ec5d
doc
gui1117 Jan 6, 2025
d9eb5b8
tests + fmt
gui1117 Jan 6, 2025
8e32689
multi version support 26 versions
gui1117 Jan 6, 2025
c6aa890
simplify bounds
gui1117 Jan 7, 2025
bfadf05
refactor test
gui1117 Jan 7, 2025
dc7944f
remove unneeded bounds
gui1117 Jan 7, 2025
ad9e9ba
more tests
gui1117 Jan 7, 2025
1812860
make invalid version safer
gui1117 Jan 8, 2025
9967ab0
Merge remote-tracking branch 'origin/master' into gui-transaction-ext…
gui1117 Jan 8, 2025
082ab90
fmt
gui1117 Jan 8, 2025
a4a87f5
prdoc
gui1117 Jan 8, 2025
b657487
prdoc fmt
gui1117 Jan 8, 2025
4d7e494
semver
gui1117 Jan 8, 2025
0b0d980
remove unused
gui1117 Jan 8, 2025
90b8297
explicit re-export + fix doc
gui1117 Jan 8, 2025
d1bdbd9
explicit reexport
gui1117 Jan 8, 2025
a59da7b
refactor and doc
gui1117 Jan 8, 2025
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
9 changes: 5 additions & 4 deletions docs/mermaid/extrinsics.mmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
flowchart TD
E(Extrinsic) ---> I(Inherent);
E --> T(Transaction)
T --> ST("Signed (aka. Transaction)")
T --> UT(Unsigned)
E(Extrinsic) ---> B(Bare);
E --> S(Signed Transaction)
E --> G(General Transaction)
B --> I(Inherent);
B --> U(Unsigned Transaction (deprecated))
54 changes: 54 additions & 0 deletions prdoc/pr_7035.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
title: Allow declaration and usage of multiple transaction extension version in FRAME and primitives

doc:
- audience: Runtime Dev
description: |
This PR enhance `UncheckedExtrinsic` type with a new optional generic: `ExtensionOtherVersion`.
This generic defaults to `InvalidVersion` meaning there is not other version than the regular version 0. This is the same behavior as before this PR.

# Breaking change

The types `Preamble`, `CheckedExtrinsic` and `ExtrinsicFormat` also have this new optional generic. Their type definition also have changed a bit, the `General` variant was 2 fields, the version and the extension, it is now only one field, the extension, and the version can be retrieve by calling `extension.version()`

The type inference for those types may fail because of this PR, to update the code, write some partial type: `UncheckedExtrinsic<_, _, _, _>`, `Preamble<_, _, _>`, `ExtrinsicFormat<_, _> and `CheckedExtrinsic<_, _, _>`.

# New feature

To use this new feature, you can use the new types `TxExtLineAtVers` and `MultiVersion` to define a transaction extension with multiple version:

```rust
pub type TransactionExtensionV0 = ();
pub type TransactionExtensionV4 = ();
pub type TransactionExtensionV7 = ();

pub type OtherVersions = MultiVersion<
TxExtLineAtVers<4, TransactionExtensionV4>;
TxExtLineAtVers<7, TransactionExtensionV7>;
>;

pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<
AccountId,
RuntimeCall,
UintAuthorityId,
TransactionExtensionV0, // The version 0, same as before
OtherVersions, // The other versions.
>;
```

crates:
- name: node-testing
bump: major
- name: pallet-revive
bump: major
- name: frame-support-procedural
bump: major
- name: frame-support
bump: major
- name: frame-support-test
bump: major
- name: sp-runtime
bump: major
- name: sp-metadata-ir
bump: major
- name: pallet-transaction-payment
bump: major
4 changes: 2 additions & 2 deletions substrate/bin/node/testing/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,8 @@ impl BenchKeyring {
function: xt.function,
}
.into(),
ExtrinsicFormat::General(ext_version, tx_ext) => generic::UncheckedExtrinsic {
preamble: sp_runtime::generic::Preamble::General(ext_version, tx_ext),
ExtrinsicFormat::General(tx_ext) => generic::UncheckedExtrinsic {
preamble: sp_runtime::generic::Preamble::General(tx_ext),
function: xt.function,
}
.into(),
Expand Down
4 changes: 2 additions & 2 deletions substrate/bin/node/testing/src/keyring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ pub fn sign(
function: xt.function,
}
.into(),
ExtrinsicFormat::General(ext_version, tx_ext) => generic::UncheckedExtrinsic {
preamble: sp_runtime::generic::Preamble::General(ext_version, tx_ext),
ExtrinsicFormat::General(tx_ext) => generic::UncheckedExtrinsic {
preamble: sp_runtime::generic::Preamble::General(tx_ext),
function: xt.function,
}
.into(),
Expand Down
6 changes: 6 additions & 0 deletions substrate/frame/revive/src/evm/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ impl<Address, Signature, E: EthExtra> ExtrinsicMetadata
E::Extension,
>::VERSIONS;
type TransactionExtensions = E::Extension;
type TransactionExtensionsVersions = <generic::UncheckedExtrinsic<
Address,
CallOf<E::Config>,
Signature,
E::Extension,
> as ExtrinsicMetadata>::TransactionExtensionsVersions;
}

impl<Address: TypeInfo, Signature: TypeInfo, E: EthExtra> ExtrinsicCall
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ pub fn expand_runtime_metadata(

use #scrate::__private::metadata_ir::InternalImplRuntimeApis;


let mut versioned_extensions_metadata =
#scrate::sp_runtime::traits::VersTxExtLineMetadataBuilder::new();

<
<
#extrinsic as #scrate::sp_runtime::traits::ExtrinsicMetadata
>::TransactionExtensionsVersions
as
#scrate::sp_runtime::traits::VersTxExtLine::<
<#runtime as #system_path::Config>::RuntimeCall
>
>::build_metadata(&mut versioned_extensions_metadata);

#scrate::__private::metadata_ir::MetadataIR {
pallets: #scrate::__private::vec![ #(#pallets),* ],
extrinsic: #scrate::__private::metadata_ir::ExtrinsicMetadataIR {
Expand All @@ -140,6 +154,15 @@ pub fn expand_runtime_metadata(
implicit: meta.implicit,
})
.collect(),
extensions_by_version: versioned_extensions_metadata.by_version,
extensions_in_versions: versioned_extensions_metadata.in_versions
.into_iter()
.map(|meta| #scrate::__private::metadata_ir::TransactionExtensionMetadataIR {
identifier: meta.identifier,
ty: meta.ty,
implicit: meta.implicit,
})
.collect(),
},
ty: #scrate::__private::scale_info::meta_type::<#runtime>(),
apis: (&rt).runtime_metadata(),
Expand Down
22 changes: 13 additions & 9 deletions substrate/frame/support/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,12 @@ where
}

/// Implementation for unchecked extrinsic.
impl<Address, Call: Dispatchable, Signature, Extension: TransactionExtension<Call>> GetDispatchInfo
for UncheckedExtrinsic<Address, Call, Signature, Extension>
impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> GetDispatchInfo
for UncheckedExtrinsic<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions>
where
Call: GetDispatchInfo + Dispatchable,
ExtensionV0: TransactionExtension<Call>,
ExtensionOtherVersions: sp_runtime::traits::VersTxExtLineWeight<Call>,
{
fn get_dispatch_info(&self) -> DispatchInfo {
let mut info = self.function.get_dispatch_info();
Expand All @@ -406,10 +408,12 @@ where
}

/// Implementation for checked extrinsic.
impl<AccountId, Call: Dispatchable, Extension: TransactionExtension<Call>> GetDispatchInfo
for CheckedExtrinsic<AccountId, Call, Extension>
impl<AccountId, Call, ExtensionV0, ExtensionOtherVersions> GetDispatchInfo
for CheckedExtrinsic<AccountId, Call, ExtensionV0, ExtensionOtherVersions>
where
Call: GetDispatchInfo,
Call: GetDispatchInfo + Dispatchable,
ExtensionV0: TransactionExtension<Call>,
ExtensionOtherVersions: sp_runtime::traits::VersTxExtLineWeight<Call>,
{
fn get_dispatch_info(&self) -> DispatchInfo {
let mut info = self.function.get_dispatch_info();
Expand Down Expand Up @@ -1549,7 +1553,7 @@ mod extension_weight_tests {
// First testcase
let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(2000), ActualWeightIs(0));
let xt = CheckedExtrinsic {
format: ExtrinsicFormat::Signed(0, ext.clone()),
format: ExtrinsicFormat::<_, _>::Signed(0, ext.clone()),
function: call.clone(),
};
assert_eq!(xt.extension_weight(), Weight::from_parts(600, 0));
Expand All @@ -1564,7 +1568,7 @@ mod extension_weight_tests {
// Second testcase
let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(1100), ActualWeightIs(200));
let xt = CheckedExtrinsic {
format: ExtrinsicFormat::Signed(0, ext),
format: ExtrinsicFormat::<_, _>::Signed(0, ext),
function: call.clone(),
};
let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
Expand All @@ -1574,7 +1578,7 @@ mod extension_weight_tests {
// Third testcase
let ext: TxExtension = (HalfCostIf(true), FreeIfUnder(1060), ActualWeightIs(200));
let xt = CheckedExtrinsic {
format: ExtrinsicFormat::Signed(0, ext),
format: ExtrinsicFormat::<_, _>::Signed(0, ext),
function: call.clone(),
};
let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
Expand All @@ -1584,7 +1588,7 @@ mod extension_weight_tests {
// Fourth testcase
let ext: TxExtension = (HalfCostIf(false), FreeIfUnder(100), ActualWeightIs(300));
let xt = CheckedExtrinsic {
format: ExtrinsicFormat::Signed(0, ext),
format: ExtrinsicFormat::<_, _>::Signed(0, ext),
function: call.clone(),
};
let post_info = xt.apply::<ExtRuntime>(&info, 0).unwrap().unwrap();
Expand Down
49 changes: 26 additions & 23 deletions substrate/frame/support/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,13 +926,14 @@ pub trait ExtrinsicCall: sp_runtime::traits::ExtrinsicLike {
fn call(&self) -> &Self::Call;
}

impl<Address, Call, Signature, Extra> ExtrinsicCall
for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
where
Address: TypeInfo,
Call: TypeInfo,
Signature: TypeInfo,
Extra: TypeInfo,
impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> ExtrinsicCall
for sp_runtime::generic::UncheckedExtrinsic<
Address,
Call,
Signature,
ExtensionV0,
ExtensionOtherVersions,
>
{
type Call = Call;

Expand All @@ -947,13 +948,14 @@ pub trait InherentBuilder: ExtrinsicCall {
fn new_inherent(call: Self::Call) -> Self;
}

impl<Address, Call, Signature, Extra> InherentBuilder
for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
where
Address: TypeInfo,
Call: TypeInfo,
Signature: TypeInfo,
Extra: TypeInfo,
impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> InherentBuilder
for sp_runtime::generic::UncheckedExtrinsic<
Address,
Call,
Signature,
ExtensionV0,
ExtensionOtherVersions,
>
{
fn new_inherent(call: Self::Call) -> Self {
Self::new_bare(call)
Expand All @@ -976,23 +978,24 @@ pub trait SignedTransactionBuilder: ExtrinsicCall {
) -> Self;
}

impl<Address, Call, Signature, Extension> SignedTransactionBuilder
for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extension>
where
Address: TypeInfo,
Call: TypeInfo,
Signature: TypeInfo,
Extension: TypeInfo,
impl<Address, Call, Signature, ExtensionV0, ExtensionOtherVersions> SignedTransactionBuilder
for sp_runtime::generic::UncheckedExtrinsic<
Address,
Call,
Signature,
ExtensionV0,
ExtensionOtherVersions,
>
{
type Address = Address;
type Signature = Signature;
type Extension = Extension;
type Extension = ExtensionV0;

fn new_signed_transaction(
call: Self::Call,
signed: Address,
signature: Signature,
tx_ext: Extension,
tx_ext: ExtensionV0,
) -> Self {
Self::new_signed(call, signed, signature, tx_ext)
}
Expand Down
Loading
Loading