Skip to content
Open
Changes from all commits
Commits
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
120 changes: 114 additions & 6 deletions demo/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down Expand Up @@ -712,8 +712,9 @@ pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
/// The TransactionExtension to the basic transaction logic.
pub type TxExtension = (
frame_system::AuthorizeCall<Runtime>,
frame_system::CheckNonZeroSender<Runtime>,
frame_system::CheckSpecVersion<Runtime>,
frame_system::CheckTxVersion<Runtime>,
Expand All @@ -722,13 +723,18 @@ pub type SignedExtra = (
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
frame_system::WeightReclaim<Runtime>,
);

/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
pub type UncheckedSignaturePayload =
generic::UncheckedSignaturePayload<Address, Signature, TxExtension>;
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
/// Extrinsic type that has already been checked.
pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, RuntimeCall, TxExtension>;
pub type Migrations = (
pallet_session_validator_management::migrations::v1::LegacyToV1Migration<Runtime>,
// More migrations can be added here
Expand All @@ -743,6 +749,108 @@ pub type Executive = frame_executive::Executive<
Migrations,
>;

impl<LocalCall> frame_system::offchain::CreateTransaction<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
{
type Extension = TxExtension;

fn create_transaction(call: RuntimeCall, extension: TxExtension) -> UncheckedExtrinsic {
generic::UncheckedExtrinsic::new_transaction(call, extension).into()
}
}

impl<LocalCall> frame_system::offchain::CreateBare<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
{
fn create_bare(call: RuntimeCall) -> UncheckedExtrinsic {
generic::UncheckedExtrinsic::new_bare(call).into()
}
}

impl frame_system::offchain::SigningTypes for Runtime {
type Public = <Signature as sp_runtime::traits::Verify>::Signer;
type Signature = Signature;
}

impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
where
RuntimeCall: From<C>,
{
type Extrinsic = UncheckedExtrinsic;
type RuntimeCall = RuntimeCall;
}

impl<C> frame_system::offchain::CreateAuthorizedTransaction<C> for Runtime
where
RuntimeCall: From<C>,
{
fn create_extension() -> Self::Extension {
(
frame_system::AuthorizeCall::<Runtime>::new(),
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(generic::Era::Immortal),
frame_system::CheckNonce::<Runtime>::from(0),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
frame_system::WeightReclaim::<Runtime>::new(),
)
}
}

impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
{
fn create_signed_transaction<
C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>,
>(
call: RuntimeCall,
public: <Signature as sp_runtime::traits::Verify>::Signer,
account: AccountId,
nonce: Nonce,
) -> Option<UncheckedExtrinsic> {
// 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::<u64>()
// 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::<Runtime>::new(),
frame_system::CheckNonZeroSender::<Runtime>::new(),
frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckEra::<Runtime>::from(era),
frame_system::CheckNonce::<Runtime>::from(nonce),
frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
frame_system::WeightReclaim::<Runtime>::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 = <Runtime as frame_system::Config>::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!(
Expand Down