Skip to content

Commit 00667e8

Browse files
committed
feat: Migrated to TransactionExtension
1 parent 6306d00 commit 00667e8

File tree

5 files changed

+122
-6
lines changed

5 files changed

+122
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ once_cell = { version = "1.21.3", default-features = false }
189189
# substrate dependencies
190190
frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }
191191
frame-executive = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }
192+
frame-metadata-hash-extension = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }
192193
frame-support = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }
193194
frame-system = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }
194195
frame-system-benchmarking = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2506" }

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ match this change.
2929
need to transform the data in their own runtime code
3030
* Updates Rust dependency to v1.88, changes WASM target to 'wasm32v1-none'
3131
* Backward compatible Encode and Decode for legacy chains that operate with AURA and Grandpa keys as session keys.
32+
* Migrated SignedExtension to TransactionExtension
3233

3334
## Added
3435

demo/runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pallet-partner-chains-session = { workspace = true, features = [
3434
] }
3535
pallet-session = { workspace = true }
3636
pallet-sudo = { workspace = true }
37+
frame-metadata-hash-extension = { workspace = true }
3738
frame-system = { workspace = true }
3839
frame-try-runtime = { workspace = true, optional = true }
3940
hex = { workspace = true }
@@ -120,6 +121,7 @@ std = [
120121
"parity-scale-codec/std",
121122
"scale-info/std",
122123
"frame-executive/std",
124+
"frame-metadata-hash-extension/std",
123125
"frame-support/std",
124126
"frame-system-rpc-runtime-api/std",
125127
"frame-system/std",

demo/runtime/src/lib.rs

Lines changed: 117 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ use sp_core::{OpaqueMetadata, crypto::KeyTypeId};
4747
use sp_governed_map::MainChainScriptsV1;
4848
use sp_inherents::InherentIdentifier;
4949
use sp_runtime::{
50-
ApplyExtrinsicResult, MultiSignature, Perbill, generic, impl_opaque_keys,
50+
ApplyExtrinsicResult, MultiSignature, Perbill, SaturatedConversion, generic, impl_opaque_keys,
5151
traits::{
5252
AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, One, OpaqueKeys,
53-
Verify,
53+
StaticLookup, Verify,
5454
},
5555
transaction_validity::{TransactionSource, TransactionValidity},
5656
};
@@ -712,8 +712,9 @@ pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
712712
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
713713
/// Block type as expected by this runtime.
714714
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
715-
/// The SignedExtension to the basic transaction logic.
716-
pub type SignedExtra = (
715+
/// The TransactionExtension to the basic transaction logic.
716+
pub type TxExtension = (
717+
frame_system::AuthorizeCall<Runtime>,
717718
frame_system::CheckNonZeroSender<Runtime>,
718719
frame_system::CheckSpecVersion<Runtime>,
719720
frame_system::CheckTxVersion<Runtime>,
@@ -722,13 +723,19 @@ pub type SignedExtra = (
722723
frame_system::CheckNonce<Runtime>,
723724
frame_system::CheckWeight<Runtime>,
724725
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
726+
frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
727+
frame_system::WeightReclaim<Runtime>,
725728
);
726729

727730
/// Unchecked extrinsic type as expected by this runtime.
728731
pub type UncheckedExtrinsic =
729-
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
732+
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
733+
pub type UncheckedSignaturePayload =
734+
generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
730735
/// The payload being signed in transactions.
731-
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
736+
pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
737+
/// Extrinsic type that has already been checked.
738+
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension>;
732739
pub type Migrations = (
733740
pallet_session_validator_management::migrations::v1::LegacyToV1Migration<Runtime>,
734741
// More migrations can be added here
@@ -743,6 +750,110 @@ pub type Executive = frame_executive::Executive<
743750
Migrations,
744751
>;
745752

753+
impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
754+
where
755+
RuntimeCall: From<LocalCall>,
756+
{
757+
type Extension = TxExtension;
758+
759+
fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
760+
generic::UncheckedExtrinsic::new_transaction(call, extension).into()
761+
}
762+
}
763+
764+
impl<LocalCall> frame_system::offchain::CreateBare<LocalCall> for Runtime
765+
where
766+
RuntimeCall: From<LocalCall>,
767+
{
768+
fn create_bare(call: RuntimeCall) -> UncheckedExtrinsic {
769+
generic::UncheckedExtrinsic::new_bare(call).into()
770+
}
771+
}
772+
773+
impl frame_system::offchain::SigningTypes for Runtime {
774+
type Public = <Signature as sp_runtime::traits::Verify>::Signer;
775+
type Signature = Signature;
776+
}
777+
778+
impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
779+
where
780+
RuntimeCall: From<C>,
781+
{
782+
type Extrinsic = UncheckedExtrinsic;
783+
type RuntimeCall = RuntimeCall;
784+
}
785+
786+
impl<C> frame_system::offchain::CreateAuthorizedTransaction<C> for Runtime
787+
where
788+
RuntimeCall: From<C>,
789+
{
790+
fn create_extension() -> Self::Extension {
791+
(
792+
frame_system::AuthorizeCall::<Runtime>::new(),
793+
frame_system::CheckNonZeroSender::<Runtime>::new(),
794+
frame_system::CheckSpecVersion::<Runtime>::new(),
795+
frame_system::CheckTxVersion::<Runtime>::new(),
796+
frame_system::CheckGenesis::<Runtime>::new(),
797+
frame_system::CheckEra::<Runtime>::from(generic::Era::Immortal),
798+
frame_system::CheckNonce::<Runtime>::from(0),
799+
frame_system::CheckWeight::<Runtime>::new(),
800+
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
801+
frame_metadata_hash_extension::CheckMetadataHash::new(false),
802+
frame_system::WeightReclaim::<Runtime>::new(),
803+
)
804+
}
805+
}
806+
807+
impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
808+
where
809+
RuntimeCall: From<LocalCall>,
810+
{
811+
fn create_signed_transaction<
812+
C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
813+
>(
814+
call: RuntimeCall,
815+
public: <Signature as sp_runtime::traits::Verify>::Signer,
816+
account: AccountId,
817+
nonce: Nonce,
818+
) -> Option<UncheckedExtrinsic> {
819+
// take the biggest period possible.
820+
let period =
821+
BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64;
822+
let current_block = System::block_number()
823+
.saturated_into::<u64>()
824+
// The `System::block_number` is initialized with `n+1`,
825+
// so the actual block number is `n`.
826+
.saturating_sub(1);
827+
let era = generic::Era::mortal(period, current_block);
828+
let tip = 0;
829+
let tx_ext: TxExtension = (
830+
frame_system::AuthorizeCall::<Runtime>::new(),
831+
frame_system::CheckNonZeroSender::<Runtime>::new(),
832+
frame_system::CheckSpecVersion::<Runtime>::new(),
833+
frame_system::CheckTxVersion::<Runtime>::new(),
834+
frame_system::CheckGenesis::<Runtime>::new(),
835+
frame_system::CheckEra::<Runtime>::from(era),
836+
frame_system::CheckNonce::<Runtime>::from(nonce),
837+
frame_system::CheckWeight::<Runtime>::new(),
838+
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
839+
frame_metadata_hash_extension::CheckMetadataHash::new(false),
840+
frame_system::WeightReclaim::<Runtime>::new(),
841+
);
842+
843+
let raw_payload = SignedPayload::new(call, tx_ext)
844+
.map_err(|e| {
845+
log::warn!("Unable to create signed payload: {:?}", e);
846+
})
847+
.ok()?;
848+
let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;
849+
let address = <Runtime as frame_system::Config>::Lookup::unlookup(account);
850+
let (call, tx_ext, _) = raw_payload.deconstruct();
851+
let transaction =
852+
generic::UncheckedExtrinsic::new_signed(call, address, signature, tx_ext).into();
853+
Some(transaction)
854+
}
855+
}
856+
746857
#[cfg(feature = "runtime-benchmarks")]
747858
mod benches {
748859
define_benchmarks!(

0 commit comments

Comments
 (0)