diff --git a/demo/runtime/src/lib.rs b/demo/runtime/src/lib.rs index de70ad0997..53c6f9a9b5 100644 --- a/demo/runtime/src/lib.rs +++ b/demo/runtime/src/lib.rs @@ -47,10 +47,10 @@ use sp_core::{OpaqueMetadata, crypto::KeyTypeId}; use sp_governed_map::MainChainScriptsV1; use sp_inherents::InherentIdentifier; use sp_runtime::{ - ApplyExtrinsicResult, MultiSignature, Perbill, generic, impl_opaque_keys, + ApplyExtrinsicResult, MultiSignature, Perbill, SaturatedConversion, generic, impl_opaque_keys, traits::{ AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, One, OpaqueKeys, - Verify, + StaticLookup, Verify, }, transaction_validity::{TransactionSource, TransactionValidity}, }; @@ -712,8 +712,9 @@ pub type Address = sp_runtime::MultiAddress; pub type Header = generic::Header; /// Block type as expected by this runtime. pub type Block = generic::Block; -/// The SignedExtension to the basic transaction logic. -pub type SignedExtra = ( +/// The TransactionExtension to the basic transaction logic. +pub type TxExtension = ( + frame_system::AuthorizeCall, frame_system::CheckNonZeroSender, frame_system::CheckSpecVersion, frame_system::CheckTxVersion, @@ -722,13 +723,18 @@ pub type SignedExtra = ( frame_system::CheckNonce, frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, + frame_system::WeightReclaim, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = - generic::UncheckedExtrinsic; + generic::UncheckedExtrinsic; +pub type UncheckedSignaturePayload = + generic::UncheckedSignaturePayload; /// The payload being signed in transactions. -pub type SignedPayload = generic::SignedPayload; +pub type SignedPayload = generic::SignedPayload; +/// Extrinsic type that has already been checked. +pub type CheckedExtrinsic = generic::CheckedExtrinsic; pub type Migrations = ( pallet_session_validator_management::migrations::v1::LegacyToV1Migration, // More migrations can be added here @@ -743,6 +749,108 @@ pub type Executive = frame_executive::Executive< Migrations, >; +impl frame_system::offchain::CreateTransaction for Runtime +where + RuntimeCall: From, +{ + type Extension = TxExtension; + + fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic { + generic::UncheckedExtrinsic::new_transaction(call, extension).into() + } +} + +impl frame_system::offchain::CreateBare for Runtime +where + RuntimeCall: From, +{ + fn create_bare(call: RuntimeCall) -> UncheckedExtrinsic { + generic::UncheckedExtrinsic::new_bare(call).into() + } +} + +impl frame_system::offchain::SigningTypes for Runtime { + type Public = ::Signer; + type Signature = Signature; +} + +impl frame_system::offchain::CreateTransactionBase for Runtime +where + RuntimeCall: From, +{ + type Extrinsic = UncheckedExtrinsic; + type RuntimeCall = RuntimeCall; +} + +impl frame_system::offchain::CreateAuthorizedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_extension() -> Self::Extension { + ( + frame_system::AuthorizeCall::::new(), + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(generic::Era::Immortal), + frame_system::CheckNonce::::from(0), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + frame_system::WeightReclaim::::new(), + ) + } +} + +impl frame_system::offchain::CreateSignedTransaction for Runtime +where + RuntimeCall: From, +{ + fn create_signed_transaction< + C: frame_system::offchain::AppCrypto, + >( + call: RuntimeCall, + public: ::Signer, + account: AccountId, + nonce: Nonce, + ) -> Option { + // take the biggest period possible. + let period = + BlockHashCount::get().checked_next_power_of_two().map(|c| c / 2).unwrap_or(2) as u64; + let current_block = System::block_number() + .saturated_into::() + // The `System::block_number` is initialized with `n+1`, + // so the actual block number is `n`. + .saturating_sub(1); + let era = generic::Era::mortal(period, current_block); + let tip = 0; + let tx_ext: TxExtension = ( + frame_system::AuthorizeCall::::new(), + frame_system::CheckNonZeroSender::::new(), + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(era), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(tip), + frame_system::WeightReclaim::::new(), + ); + + let raw_payload = SignedPayload::new(call, tx_ext) + .map_err(|e| { + log::warn!("Unable to create signed payload: {:?}", e); + }) + .ok()?; + let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?; + let address = ::Lookup::unlookup(account); + let (call, tx_ext, _) = raw_payload.deconstruct(); + let transaction = + generic::UncheckedExtrinsic::new_signed(call, address, signature, tx_ext).into(); + Some(transaction) + } +} + #[cfg(feature = "runtime-benchmarks")] mod benches { define_benchmarks!(