feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
[package]
|
||||
name = "pezpallet-meta-tx"
|
||||
description = "FRAME pallet enabling meta transactions."
|
||||
license = "Apache-2.0"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
codec = { workspace = true, features = ["max-encoded-len"] }
|
||||
docify = { workspace = true }
|
||||
scale-info = { workspace = true, features = ["derive"] }
|
||||
serde = { features = ["derive"], optional = true, workspace = true }
|
||||
|
||||
pezframe-benchmarking = { workspace = true, optional = true }
|
||||
pezframe-support = { workspace = true }
|
||||
pezframe-system = { workspace = true }
|
||||
pezsp-core = { workspace = true }
|
||||
pezsp-io = { workspace = true }
|
||||
pezsp-runtime = { workspace = true }
|
||||
pezsp-std = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pezpallet-balances = { workspace = true, default-features = true }
|
||||
pezpallet-transaction-payment = { workspace = true, default-features = true }
|
||||
pezpallet-verify-signature = { workspace = true, default-features = true }
|
||||
pezsp-keyring = { workspace = true, default-features = true }
|
||||
pezsp-keystore = { workspace = true, default-features = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"pezframe-benchmarking?/std",
|
||||
"pezframe-support/std",
|
||||
"pezframe-system/std",
|
||||
"scale-info/std",
|
||||
"serde?/std",
|
||||
"pezsp-core/std",
|
||||
"pezsp-io/std",
|
||||
"pezsp-runtime/std",
|
||||
"pezsp-std/std",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"pezframe-benchmarking/runtime-benchmarks",
|
||||
"pezframe-support/runtime-benchmarks",
|
||||
"pezframe-system/runtime-benchmarks",
|
||||
"pezpallet-balances/runtime-benchmarks",
|
||||
"pezpallet-transaction-payment/runtime-benchmarks",
|
||||
"pezpallet-verify-signature/runtime-benchmarks",
|
||||
"pezsp-io/runtime-benchmarks",
|
||||
"pezsp-keyring/runtime-benchmarks",
|
||||
"pezsp-runtime/runtime-benchmarks",
|
||||
]
|
||||
try-runtime = [
|
||||
"pezframe-support/try-runtime",
|
||||
"pezframe-system/try-runtime",
|
||||
"pezpallet-balances/try-runtime",
|
||||
"pezpallet-transaction-payment/try-runtime",
|
||||
"pezpallet-verify-signature/try-runtime",
|
||||
"pezsp-runtime/try-runtime",
|
||||
]
|
||||
@@ -0,0 +1,130 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![cfg(feature = "runtime-benchmarks")]
|
||||
|
||||
use super::*;
|
||||
use pezframe_benchmarking::v2::*;
|
||||
use pezframe_support::traits::UnfilteredDispatchable;
|
||||
use pezsp_runtime::impl_tx_ext_default;
|
||||
|
||||
pub mod types {
|
||||
use super::*;
|
||||
use pezframe_support::traits::OriginTrait;
|
||||
use pezsp_runtime::traits::DispatchInfoOf;
|
||||
|
||||
type CallOf<T> = <T as pezframe_system::Config>::RuntimeCall;
|
||||
|
||||
/// A weightless extension to facilitate the bare dispatch benchmark.
|
||||
#[derive(TypeInfo, Eq, PartialEq, Clone, Encode, Decode, DecodeWithMemTracking)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct WeightlessExtension<T>(core::marker::PhantomData<T>);
|
||||
impl<T: Config + Send + Sync> core::fmt::Debug for WeightlessExtension<T> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||
write!(f, "WeightlessExtension")
|
||||
}
|
||||
}
|
||||
impl<T: Config + Send + Sync> Default for WeightlessExtension<T> {
|
||||
fn default() -> Self {
|
||||
WeightlessExtension(Default::default())
|
||||
}
|
||||
}
|
||||
impl<T: Config + Send + Sync> TransactionExtension<CallOf<T>> for WeightlessExtension<T> {
|
||||
const IDENTIFIER: &'static str = "WeightlessExtension";
|
||||
type Implicit = ();
|
||||
type Pre = ();
|
||||
type Val = ();
|
||||
fn weight(&self, _call: &CallOf<T>) -> Weight {
|
||||
Weight::from_all(0)
|
||||
}
|
||||
fn validate(
|
||||
&self,
|
||||
mut origin: <CallOf<T> as Dispatchable>::RuntimeOrigin,
|
||||
_: &CallOf<T>,
|
||||
_: &DispatchInfoOf<CallOf<T>>,
|
||||
_: usize,
|
||||
_: (),
|
||||
_: &impl Encode,
|
||||
_: TransactionSource,
|
||||
) -> Result<
|
||||
(ValidTransaction, Self::Val, <CallOf<T> as Dispatchable>::RuntimeOrigin),
|
||||
TransactionValidityError,
|
||||
> {
|
||||
origin.set_caller_from_signed(whitelisted_caller());
|
||||
Ok((ValidTransaction::default(), (), origin))
|
||||
}
|
||||
|
||||
impl_tx_ext_default!(CallOf<T>; prepare);
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
|
||||
pezframe_system::Pallet::<T>::assert_last_event(generic_event.into());
|
||||
}
|
||||
|
||||
#[benchmarks(
|
||||
where
|
||||
T: Config,
|
||||
<T as Config>::Extension: Default,
|
||||
)]
|
||||
mod benchmarks {
|
||||
use super::*;
|
||||
|
||||
#[benchmark]
|
||||
fn bare_dispatch() {
|
||||
let meta_call = pezframe_system::Call::<T>::remark { remark: vec![] }.into();
|
||||
let meta_ext = T::Extension::default();
|
||||
let meta_ext_weight = meta_ext.weight(&meta_call);
|
||||
|
||||
#[cfg(not(test))]
|
||||
assert!(
|
||||
meta_ext_weight.is_zero(),
|
||||
"meta tx extension weight for the benchmarks must be zero. \
|
||||
use `pezpallet_meta_tx::WeightlessExtension` as `pezpallet_meta_tx::Config::Extension` \
|
||||
with the `runtime-benchmarks` feature enabled.",
|
||||
);
|
||||
|
||||
let meta_tx = MetaTxFor::<T>::new(meta_call.clone(), 0u8, meta_ext.clone());
|
||||
|
||||
let caller = whitelisted_caller();
|
||||
let origin: <T as pezframe_system::Config>::RuntimeOrigin =
|
||||
pezframe_system::RawOrigin::Signed(caller).into();
|
||||
let call = Call::<T>::dispatch { meta_tx: Box::new(meta_tx) };
|
||||
|
||||
#[block]
|
||||
{
|
||||
let _ = call.dispatch_bypass_filter(origin);
|
||||
}
|
||||
|
||||
let info = meta_call.get_dispatch_info();
|
||||
assert_last_event::<T>(
|
||||
Event::Dispatched {
|
||||
result: Ok(PostDispatchInfo {
|
||||
actual_weight: Some(info.call_weight + meta_ext_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
}),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite! {
|
||||
Pallet,
|
||||
crate::mock::new_test_ext(),
|
||||
crate::mock::Runtime,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::*;
|
||||
use pezsp_runtime::impl_tx_ext_default;
|
||||
|
||||
/// This type serves as a marker extension to differentiate meta-transactions from regular
|
||||
/// transactions. It implements the `TransactionExtension` trait and carries constant implicit data
|
||||
/// ("_meta_tx").
|
||||
#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo, DebugNoBound, DecodeWithMemTracking)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct MetaTxMarker<T> {
|
||||
_phantom: core::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> MetaTxMarker<T> {
|
||||
/// Creates new `TransactionExtension` with implicit meta tx marked.
|
||||
pub fn new() -> Self {
|
||||
Self { _phantom: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for MetaTxMarker<T> {
|
||||
const IDENTIFIER: &'static str = "MetaTxMarker";
|
||||
type Implicit = [u8; 8];
|
||||
type Val = ();
|
||||
type Pre = ();
|
||||
fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
|
||||
Ok(*b"_meta_tx")
|
||||
}
|
||||
fn weight(&self, _: &T::RuntimeCall) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
impl_tx_ext_default!(T::RuntimeCall; validate prepare);
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! # Meta Tx (Meta Transaction) Pallet
|
||||
//!
|
||||
//! This pallet enables the dispatch of transactions that are authorized by one party (the signer)
|
||||
//! and executed by an untrusted third party (the relayer), who covers the transaction fees.
|
||||
//!
|
||||
//! ## Pallet API
|
||||
//!
|
||||
//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
|
||||
//! including its configuration trait, dispatchables, storage items, events and errors.
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! The pallet provides a client-level API, typically not meant for direct use by end users.
|
||||
//! A meta transaction, constructed with the help of a wallet, contains a target call, necessary
|
||||
//! extensions, and the signer's signature. This transaction is then broadcast, and any interested
|
||||
//! relayer can pick it up and execute it. The relayer submits a regular transaction via the
|
||||
//! [`dispatch`](`Pallet::dispatch`) function, passing the meta transaction as an argument to
|
||||
//! execute the target call on behalf of the signer while covering the fees.
|
||||
//!
|
||||
//! ### Example
|
||||
#![doc = docify::embed!("src/tests.rs", sign_and_execute_meta_tx)]
|
||||
//!
|
||||
//! ## Low-Level / Implementation Details
|
||||
//!
|
||||
//! The structure of a meta transaction is identical to the
|
||||
//! [`General`](pezsp_runtime::generic::Preamble::General) transaction.
|
||||
//! It contains the target call along with a configurable set of extensions and its associated
|
||||
//! version. Typically, these extensions include type like
|
||||
//! `pezpallet_verify_signature::VerifySignature`, which provides the signer address
|
||||
//! and the signature of the payload, encompassing the call and the meta-transaction’s
|
||||
//! configurations, such as its mortality. The extensions follow the same [`TransactionExtension`]
|
||||
//! contract, and common types such as [`pezframe_system::CheckGenesis`],
|
||||
//! [`pezframe_system::CheckMortality`], [`pezframe_system::CheckNonce`], etc., are applicable in the
|
||||
//! context of meta transactions. Check the `mock` setup for the example.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
mod benchmarking;
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
#[cfg(all(test, not(feature = "runtime-benchmarks")))]
|
||||
mod tests;
|
||||
pub mod weights;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub use benchmarking::types::WeightlessExtension;
|
||||
pub use pallet::*;
|
||||
pub use weights::WeightInfo;
|
||||
mod extension;
|
||||
pub use extension::MetaTxMarker;
|
||||
|
||||
use core::ops::Add;
|
||||
use pezframe_support::{
|
||||
dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo},
|
||||
pezpallet_prelude::*,
|
||||
};
|
||||
use pezframe_system::{pezpallet_prelude::*, RawOrigin as SystemOrigin};
|
||||
use pezsp_runtime::{
|
||||
generic::ExtensionVersion,
|
||||
traits::{
|
||||
AsTransactionAuthorizedOrigin, DispatchTransaction, Dispatchable, TransactionExtension,
|
||||
},
|
||||
};
|
||||
use pezsp_std::prelude::*;
|
||||
|
||||
/// Meta Transaction type.
|
||||
///
|
||||
/// The data that is provided and signed by the signer and shared with the relayer.
|
||||
#[derive(Encode, Decode, PartialEq, Eq, TypeInfo, Clone, RuntimeDebug, DecodeWithMemTracking)]
|
||||
pub struct MetaTx<Call, Extension> {
|
||||
/// The target call to be executed on behalf of the signer.
|
||||
call: Call,
|
||||
/// The extension version.
|
||||
extension_version: ExtensionVersion,
|
||||
/// The extension/s for the meta transaction.
|
||||
extension: Extension,
|
||||
}
|
||||
|
||||
impl<Call, Extension> MetaTx<Call, Extension> {
|
||||
/// Create a new meta transaction.
|
||||
pub fn new(call: Call, extension_version: ExtensionVersion, extension: Extension) -> Self {
|
||||
Self { call, extension_version, extension }
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`MetaTx`] for the given config.
|
||||
pub type MetaTxFor<T> = MetaTx<<T as pezframe_system::Config>::RuntimeCall, <T as Config>::Extension>;
|
||||
|
||||
#[pezframe_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config:
|
||||
pezframe_system::Config<
|
||||
RuntimeCall: Dispatchable<
|
||||
Info = DispatchInfo,
|
||||
PostInfo = PostDispatchInfo,
|
||||
RuntimeOrigin = <Self as pezframe_system::Config>::RuntimeOrigin,
|
||||
>,
|
||||
RuntimeOrigin: AsTransactionAuthorizedOrigin + From<SystemOrigin<Self::AccountId>>,
|
||||
>
|
||||
{
|
||||
/// Weight information for calls in this pallet.
|
||||
type WeightInfo: WeightInfo;
|
||||
/// The overarching event type.
|
||||
#[allow(deprecated)]
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
|
||||
/// Transaction extension/s for meta transactions.
|
||||
///
|
||||
/// The extensions that must be present in every meta transaction. This generally includes
|
||||
/// extensions like `pezpallet_verify_signature::VerifySignature`,
|
||||
/// [pezframe_system::CheckSpecVersion], [pezframe_system::CheckTxVersion],
|
||||
/// [pezframe_system::CheckGenesis], [pezframe_system::CheckMortality],
|
||||
/// [pezframe_system::CheckNonce], etc. Check the `mock` setup for the example.
|
||||
///
|
||||
/// The types implementing the [`TransactionExtension`] trait can be composed into a tuple
|
||||
/// type that will implement the same trait by piping invocations through each type.
|
||||
///
|
||||
/// In the `runtime-benchmarks` environment the type must implement [`Default`] trait.
|
||||
/// The extension must provide an origin and the extension's weight must be zero. Use
|
||||
/// `pezpallet_meta_tx::WeightlessExtension` type when the `runtime-benchmarks` feature
|
||||
/// enabled.
|
||||
type Extension: TransactionExtension<<Self as pezframe_system::Config>::RuntimeCall>;
|
||||
}
|
||||
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// Invalid proof (e.g. signature).
|
||||
BadProof,
|
||||
/// The meta transaction is not yet valid (e.g. nonce too high).
|
||||
Future,
|
||||
/// The meta transaction is outdated (e.g. nonce too low).
|
||||
Stale,
|
||||
/// The meta transactions's birth block is ancient.
|
||||
AncientBirthBlock,
|
||||
/// The transaction extension did not authorize any origin.
|
||||
UnknownOrigin,
|
||||
/// The meta transaction is invalid.
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(crate) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
/// A meta transaction has been dispatched.
|
||||
///
|
||||
/// Contains the dispatch result of the meta transaction along with post-dispatch
|
||||
/// information.
|
||||
Dispatched { result: DispatchResultWithPostInfo },
|
||||
}
|
||||
|
||||
#[pallet::pallet]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Dispatch a given meta transaction.
|
||||
///
|
||||
/// - `_origin`: Can be any kind of origin.
|
||||
/// - `meta_tx`: Meta Transaction with a target call to be dispatched.
|
||||
#[pallet::call_index(0)]
|
||||
#[pallet::weight({
|
||||
let dispatch_info = meta_tx.call.get_dispatch_info();
|
||||
let extension_weight = meta_tx.extension.weight(&meta_tx.call);
|
||||
let bare_call_weight = T::WeightInfo::bare_dispatch();
|
||||
(
|
||||
dispatch_info.call_weight.add(extension_weight).add(bare_call_weight),
|
||||
dispatch_info.class,
|
||||
)
|
||||
})]
|
||||
pub fn dispatch(
|
||||
_origin: OriginFor<T>,
|
||||
meta_tx: Box<MetaTxFor<T>>,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
let origin = SystemOrigin::None;
|
||||
let meta_tx_size = meta_tx.encoded_size();
|
||||
// `info` with worst-case call weight and extension weight.
|
||||
let info = {
|
||||
let mut info = meta_tx.call.get_dispatch_info();
|
||||
info.extension_weight = meta_tx.extension.weight(&meta_tx.call);
|
||||
info
|
||||
};
|
||||
|
||||
// dispatch the meta transaction.
|
||||
let meta_dispatch_res = meta_tx
|
||||
.extension
|
||||
.dispatch_transaction(
|
||||
origin.into(),
|
||||
meta_tx.call,
|
||||
&info,
|
||||
meta_tx_size,
|
||||
meta_tx.extension_version,
|
||||
)
|
||||
.map_err(Error::<T>::from)?;
|
||||
|
||||
Self::deposit_event(Event::Dispatched { result: meta_dispatch_res });
|
||||
|
||||
// meta weight after possible refunds.
|
||||
let meta_weight = meta_dispatch_res
|
||||
.map_or_else(|err| err.post_info.actual_weight, |info| info.actual_weight)
|
||||
.unwrap_or(info.total_weight());
|
||||
|
||||
Ok((Some(T::WeightInfo::bare_dispatch().saturating_add(meta_weight)), true.into())
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Implements [`From<TransactionValidityError>`] for [`Error`] by mapping the relevant error
|
||||
/// variants.
|
||||
impl<T> From<TransactionValidityError> for Error<T> {
|
||||
fn from(err: TransactionValidityError) -> Self {
|
||||
use TransactionValidityError::*;
|
||||
match err {
|
||||
Unknown(_) => Error::<T>::Invalid,
|
||||
Invalid(err) => match err {
|
||||
InvalidTransaction::BadProof => Error::<T>::BadProof,
|
||||
InvalidTransaction::Future => Error::<T>::Future,
|
||||
InvalidTransaction::Stale => Error::<T>::Stale,
|
||||
InvalidTransaction::AncientBirthBlock => Error::<T>::AncientBirthBlock,
|
||||
InvalidTransaction::UnknownOrigin => Error::<T>::UnknownOrigin,
|
||||
_ => Error::<T>::Invalid,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Mock setup for tests.
|
||||
|
||||
#![cfg(any(test, feature = "runtime-benchmarks"))]
|
||||
|
||||
use crate as pezpallet_meta_tx;
|
||||
use crate::*;
|
||||
use pezframe_support::{
|
||||
construct_runtime, derive_impl,
|
||||
weights::{FixedFee, NoFee},
|
||||
};
|
||||
use pezsp_core::ConstU8;
|
||||
use pezsp_keystore::{testing::MemoryKeystore, KeystoreExt};
|
||||
use pezsp_runtime::{
|
||||
traits::{IdentifyAccount, IdentityLookup, Verify},
|
||||
MultiSignature,
|
||||
};
|
||||
|
||||
pub type Balance = u64;
|
||||
|
||||
pub type Signature = MultiSignature;
|
||||
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub type MetaTxExtension = crate::benchmarking::types::WeightlessExtension<Runtime>;
|
||||
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
pub use tx_ext::*;
|
||||
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
mod tx_ext {
|
||||
use super::*;
|
||||
|
||||
pub type UncheckedExtrinsic =
|
||||
pezsp_runtime::generic::UncheckedExtrinsic<AccountId, RuntimeCall, Signature, TxExtension>;
|
||||
|
||||
/// Transaction extension.
|
||||
pub type TxExtension = (pezpallet_verify_signature::VerifySignature<Runtime>, TxBareExtension);
|
||||
|
||||
/// Transaction extension without signature information.
|
||||
///
|
||||
/// Helper type used to decode the part of the extension which should be signed.
|
||||
pub type TxBareExtension = (
|
||||
pezframe_system::CheckNonZeroSender<Runtime>,
|
||||
pezframe_system::CheckSpecVersion<Runtime>,
|
||||
pezframe_system::CheckTxVersion<Runtime>,
|
||||
pezframe_system::CheckGenesis<Runtime>,
|
||||
pezframe_system::CheckMortality<Runtime>,
|
||||
pezframe_system::CheckNonce<Runtime>,
|
||||
pezframe_system::CheckWeight<Runtime>,
|
||||
pezpallet_transaction_payment::ChargeTransactionPayment<Runtime>,
|
||||
);
|
||||
|
||||
pub const META_EXTENSION_VERSION: ExtensionVersion = 0;
|
||||
|
||||
/// Meta transaction extension.
|
||||
pub type MetaTxExtension =
|
||||
(pezpallet_verify_signature::VerifySignature<Runtime>, MetaTxBareExtension);
|
||||
|
||||
/// Meta transaction extension without signature information.
|
||||
///
|
||||
/// Helper type used to decode the part of the extension which should be signed.
|
||||
pub type MetaTxBareExtension = (
|
||||
MetaTxMarker<Runtime>,
|
||||
pezframe_system::CheckNonZeroSender<Runtime>,
|
||||
pezframe_system::CheckSpecVersion<Runtime>,
|
||||
pezframe_system::CheckTxVersion<Runtime>,
|
||||
pezframe_system::CheckGenesis<Runtime>,
|
||||
pezframe_system::CheckMortality<Runtime>,
|
||||
pezframe_system::CheckNonce<Runtime>,
|
||||
);
|
||||
}
|
||||
|
||||
impl Config for Runtime {
|
||||
type WeightInfo = ();
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Extension = MetaTxExtension;
|
||||
}
|
||||
|
||||
impl pezpallet_verify_signature::Config for Runtime {
|
||||
type Signature = MultiSignature;
|
||||
type AccountIdentifier = <Signature as Verify>::Signer;
|
||||
type WeightInfo = ();
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BenchmarkHelper = ();
|
||||
}
|
||||
|
||||
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
|
||||
impl pezframe_system::Config for Runtime {
|
||||
type AccountId = AccountId;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = pezframe_system::mocking::MockBlock<Runtime>;
|
||||
type AccountData = pezpallet_balances::AccountData<<Self as pezpallet_balances::Config>::Balance>;
|
||||
}
|
||||
|
||||
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
|
||||
impl pezpallet_balances::Config for Runtime {
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
type AccountStore = System;
|
||||
}
|
||||
|
||||
pub const TX_FEE: u32 = 10;
|
||||
|
||||
impl pezpallet_transaction_payment::Config for Runtime {
|
||||
type WeightInfo = ();
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type OnChargeTransaction = pezpallet_transaction_payment::FungibleAdapter<Balances, ()>;
|
||||
type OperationalFeeMultiplier = ConstU8<1>;
|
||||
type WeightToFee = FixedFee<TX_FEE, Balance>;
|
||||
type LengthToFee = NoFee<Balance>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Runtime {
|
||||
System: pezframe_system,
|
||||
Balances: pezpallet_balances,
|
||||
MetaTx: pezpallet_meta_tx,
|
||||
TxPayment: pezpallet_transaction_payment,
|
||||
VerifySignature: pezpallet_verify_signature,
|
||||
}
|
||||
);
|
||||
|
||||
pub(crate) fn new_test_ext() -> pezsp_io::TestExternalities {
|
||||
let mut ext = pezsp_io::TestExternalities::new(Default::default());
|
||||
ext.execute_with(|| {
|
||||
pezframe_system::GenesisConfig::<Runtime>::default().build();
|
||||
System::set_block_number(1);
|
||||
});
|
||||
ext.register_extension(KeystoreExt::new(MemoryKeystore::new()));
|
||||
ext
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use pezframe_support::traits::tokens::fungible::Inspect;
|
||||
use mock::*;
|
||||
use pezsp_io::hashing::blake2_256;
|
||||
use pezsp_keyring::Sr25519Keyring;
|
||||
use pezsp_runtime::{
|
||||
generic::Era,
|
||||
traits::{Applyable, Checkable, Hash, IdentityLookup},
|
||||
DispatchErrorWithPostInfo, MultiSignature,
|
||||
};
|
||||
|
||||
type VerifySignatureExt = pezpallet_verify_signature::VerifySignature<Runtime>;
|
||||
|
||||
fn create_tx_bare_ext(account: AccountId) -> TxBareExtension {
|
||||
(
|
||||
pezframe_system::CheckNonZeroSender::<Runtime>::new(),
|
||||
pezframe_system::CheckSpecVersion::<Runtime>::new(),
|
||||
pezframe_system::CheckTxVersion::<Runtime>::new(),
|
||||
pezframe_system::CheckGenesis::<Runtime>::new(),
|
||||
pezframe_system::CheckMortality::<Runtime>::from(Era::immortal()),
|
||||
pezframe_system::CheckNonce::<Runtime>::from(
|
||||
pezframe_system::Pallet::<Runtime>::account(&account).nonce,
|
||||
),
|
||||
pezframe_system::CheckWeight::<Runtime>::new(),
|
||||
pezpallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn create_meta_tx_bare_ext(account: AccountId) -> MetaTxBareExtension {
|
||||
(
|
||||
MetaTxMarker::new(),
|
||||
pezframe_system::CheckNonZeroSender::<Runtime>::new(),
|
||||
pezframe_system::CheckSpecVersion::<Runtime>::new(),
|
||||
pezframe_system::CheckTxVersion::<Runtime>::new(),
|
||||
pezframe_system::CheckGenesis::<Runtime>::new(),
|
||||
pezframe_system::CheckMortality::<Runtime>::from(Era::immortal()),
|
||||
pezframe_system::CheckNonce::<Runtime>::from(
|
||||
pezframe_system::Pallet::<Runtime>::account(&account).nonce,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn create_signature<Call: Encode, Ext: Encode + TransactionExtension<RuntimeCall>>(
|
||||
call: Call,
|
||||
ext: Ext,
|
||||
signer: Sr25519Keyring,
|
||||
) -> MultiSignature {
|
||||
MultiSignature::Sr25519(
|
||||
(META_EXTENSION_VERSION, call, ext.clone(), ext.implicit().unwrap())
|
||||
.using_encoded(|e| signer.sign(&blake2_256(e))),
|
||||
)
|
||||
}
|
||||
|
||||
fn force_set_balance(account: AccountId) -> Balance {
|
||||
let balance = Balances::minimum_balance() * 100;
|
||||
Balances::force_set_balance(RuntimeOrigin::root(), account.into(), balance).unwrap();
|
||||
balance
|
||||
}
|
||||
|
||||
fn apply_extrinsic(uxt: UncheckedExtrinsic) -> DispatchResultWithPostInfo {
|
||||
let uxt_info = uxt.get_dispatch_info();
|
||||
let uxt_len = uxt.using_encoded(|e| e.len());
|
||||
let xt = <UncheckedExtrinsic as Checkable<IdentityLookup<AccountId>>>::check(
|
||||
uxt,
|
||||
&Default::default(),
|
||||
)
|
||||
.unwrap();
|
||||
xt.apply::<Runtime>(&uxt_info, uxt_len).unwrap()
|
||||
}
|
||||
|
||||
#[docify::export]
|
||||
#[test]
|
||||
fn sign_and_execute_meta_tx() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// meta tx signer
|
||||
let alice_keyring = Sr25519Keyring::Alice;
|
||||
// meta tx relayer
|
||||
let bob_keyring = Sr25519Keyring::Bob;
|
||||
|
||||
let alice_account: AccountId = alice_keyring.public().into();
|
||||
let bob_account: AccountId = bob_keyring.public().into();
|
||||
|
||||
let tx_fee: Balance = (2 * TX_FEE).into(); // base tx fee + weight fee
|
||||
let alice_balance = force_set_balance(alice_account.clone());
|
||||
let bob_balance = force_set_balance(bob_account.clone());
|
||||
|
||||
// Alice builds a meta transaction.
|
||||
|
||||
let remark_call =
|
||||
RuntimeCall::System(pezframe_system::Call::remark_with_event { remark: vec![1] });
|
||||
let meta_tx_bare_ext = create_meta_tx_bare_ext(alice_account.clone());
|
||||
let meta_tx_sig =
|
||||
create_signature(remark_call.clone(), meta_tx_bare_ext.clone(), alice_keyring);
|
||||
let meta_tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(meta_tx_sig, alice_account.clone()),
|
||||
// append signed part.
|
||||
meta_tx_bare_ext,
|
||||
);
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::new(
|
||||
remark_call.clone(),
|
||||
META_EXTENSION_VERSION,
|
||||
meta_tx_ext.clone(),
|
||||
);
|
||||
|
||||
// Encode and share with the world.
|
||||
let meta_tx_encoded = meta_tx.encode();
|
||||
|
||||
// Bob acts as meta transaction relayer.
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::decode(&mut &meta_tx_encoded[..]).unwrap();
|
||||
let call = RuntimeCall::MetaTx(Call::dispatch { meta_tx: Box::new(meta_tx.clone()) });
|
||||
let tx_bare_ext = create_tx_bare_ext(bob_account.clone());
|
||||
let tx_sig = create_signature(call.clone(), tx_bare_ext.clone(), bob_keyring);
|
||||
let tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(tx_sig, bob_account.clone()),
|
||||
// append signed part
|
||||
tx_bare_ext,
|
||||
);
|
||||
|
||||
let uxt = UncheckedExtrinsic::new_transaction(call.clone(), tx_ext.clone());
|
||||
|
||||
// Check Extrinsic validity and apply it.
|
||||
let result = apply_extrinsic(uxt);
|
||||
|
||||
// Asserting the results and make sure the weight is correct.
|
||||
|
||||
let tx_weight = tx_ext.weight(&call) + <Runtime as Config>::WeightInfo::bare_dispatch();
|
||||
let meta_tx_weight = remark_call
|
||||
.get_dispatch_info()
|
||||
.call_weight
|
||||
.add(meta_tx_ext.weight(&remark_call));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(PostDispatchInfo {
|
||||
actual_weight: Some(meta_tx_weight + tx_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
})
|
||||
);
|
||||
|
||||
System::assert_has_event(RuntimeEvent::MetaTx(crate::Event::Dispatched {
|
||||
result: Ok(PostDispatchInfo {
|
||||
actual_weight: Some(meta_tx_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
}),
|
||||
}));
|
||||
|
||||
System::assert_has_event(RuntimeEvent::System(pezframe_system::Event::Remarked {
|
||||
sender: alice_account.clone(),
|
||||
hash: <Runtime as pezframe_system::Config>::Hashing::hash(&[1]),
|
||||
}));
|
||||
|
||||
// Alice balance is unchanged, Bob paid the transaction fee.
|
||||
assert_eq!(alice_balance, Balances::free_balance(alice_account));
|
||||
assert_eq!(bob_balance - tx_fee, Balances::free_balance(bob_account));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_signature() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// meta tx signer
|
||||
let alice_keyring = Sr25519Keyring::Alice;
|
||||
// meta tx relayer
|
||||
let bob_keyring = Sr25519Keyring::Bob;
|
||||
|
||||
let alice_account: AccountId = alice_keyring.public().into();
|
||||
let bob_account: AccountId = bob_keyring.public().into();
|
||||
|
||||
let tx_fee: Balance = (2 * TX_FEE).into(); // base tx fee + weight fee
|
||||
let alice_balance = force_set_balance(alice_account.clone());
|
||||
let bob_balance = force_set_balance(bob_account.clone());
|
||||
|
||||
// Alice builds a meta transaction.
|
||||
|
||||
let remark_call =
|
||||
RuntimeCall::System(pezframe_system::Call::remark_with_event { remark: vec![1] });
|
||||
let meta_tx_bare_ext = create_meta_tx_bare_ext(alice_account.clone());
|
||||
// signature is invalid since it's signed by charlie instead of alice.
|
||||
let invalid_meta_tx_sig = create_signature(
|
||||
remark_call.clone(),
|
||||
meta_tx_bare_ext.clone(),
|
||||
Sr25519Keyring::Charlie,
|
||||
);
|
||||
let meta_tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(invalid_meta_tx_sig, alice_account.clone()),
|
||||
// append signed part.
|
||||
meta_tx_bare_ext,
|
||||
);
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::new(
|
||||
remark_call.clone(),
|
||||
META_EXTENSION_VERSION,
|
||||
meta_tx_ext.clone(),
|
||||
);
|
||||
|
||||
// Encode and share with the world.
|
||||
let meta_tx_encoded = meta_tx.encode();
|
||||
|
||||
// Bob acts as meta transaction relayer.
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::decode(&mut &meta_tx_encoded[..]).unwrap();
|
||||
let call = RuntimeCall::MetaTx(Call::dispatch { meta_tx: Box::new(meta_tx.clone()) });
|
||||
let tx_bare_ext = create_tx_bare_ext(bob_account.clone());
|
||||
let tx_sig = create_signature(call.clone(), tx_bare_ext.clone(), bob_keyring);
|
||||
let tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(tx_sig, bob_account.clone()),
|
||||
// append signed part
|
||||
tx_bare_ext,
|
||||
);
|
||||
|
||||
let uxt = UncheckedExtrinsic::new_transaction(call, tx_ext);
|
||||
|
||||
// Check Extrinsic validity and apply it.
|
||||
let result = apply_extrinsic(uxt);
|
||||
|
||||
// Asserting the results.
|
||||
|
||||
assert_eq!(result.unwrap_err().error, Error::<Runtime>::BadProof.into());
|
||||
|
||||
// Alice balance is unchanged, Bob paid the transaction fee.
|
||||
assert_eq!(alice_balance, Balances::free_balance(alice_account));
|
||||
assert_eq!(bob_balance - tx_fee, Balances::free_balance(bob_account));
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
#[test]
|
||||
fn meta_tx_extension_work() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// meta tx signer
|
||||
let alice_keyring = Sr25519Keyring::Alice;
|
||||
// meta tx relayer
|
||||
let bob_keyring = Sr25519Keyring::Bob;
|
||||
|
||||
let alice_account: AccountId = alice_keyring.public().into();
|
||||
let bob_account: AccountId = bob_keyring.public().into();
|
||||
|
||||
let tx_fee: Balance = (2 * TX_FEE).into(); // base tx fee + weight fee
|
||||
let alice_balance = force_set_balance(alice_account.clone());
|
||||
let bob_balance = force_set_balance(bob_account.clone());
|
||||
|
||||
// Alice builds a meta transaction.
|
||||
|
||||
let remark_call =
|
||||
RuntimeCall::System(pezframe_system::Call::remark_with_event { remark: vec![1] });
|
||||
|
||||
let meta_tx_bare_ext = create_meta_tx_bare_ext(alice_account.clone());
|
||||
let meta_tx_sig =
|
||||
create_signature(remark_call.clone(), meta_tx_bare_ext.clone(), alice_keyring);
|
||||
let meta_tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(meta_tx_sig, alice_account.clone()),
|
||||
// append signed part.
|
||||
meta_tx_bare_ext,
|
||||
);
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::new(remark_call, META_EXTENSION_VERSION, meta_tx_ext);
|
||||
|
||||
// Encode and share with the world.
|
||||
let meta_tx_encoded = meta_tx.encode();
|
||||
|
||||
// Bob acts as meta transaction relayer.
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::decode(&mut &meta_tx_encoded[..]).unwrap();
|
||||
let call = RuntimeCall::MetaTx(Call::dispatch { meta_tx: Box::new(meta_tx.clone()) });
|
||||
let tx_bare_ext = create_tx_bare_ext(bob_account.clone());
|
||||
let tx_sig = create_signature(call.clone(), tx_bare_ext.clone(), bob_keyring);
|
||||
let tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(tx_sig, bob_account.clone()),
|
||||
// append signed part
|
||||
tx_bare_ext,
|
||||
);
|
||||
|
||||
let uxt = UncheckedExtrinsic::new_transaction(call, tx_ext);
|
||||
|
||||
// increment alice's nonce to invalidate the meta tx and verify that the
|
||||
// meta tx extension works.
|
||||
pezframe_system::Pallet::<Runtime>::inc_account_nonce(alice_account.clone());
|
||||
|
||||
// Check Extrinsic validity and apply it.
|
||||
let result = apply_extrinsic(uxt);
|
||||
|
||||
// Asserting the results.
|
||||
assert_eq!(result.unwrap_err().error, Error::<Runtime>::Stale.into());
|
||||
|
||||
// Alice balance is unchanged, Bob paid the transaction fee.
|
||||
assert_eq!(alice_balance, Balances::free_balance(alice_account));
|
||||
assert_eq!(bob_balance - tx_fee, Balances::free_balance(bob_account));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn meta_tx_call_fails() {
|
||||
new_test_ext().execute_with(|| {
|
||||
// meta tx signer
|
||||
let alice_keyring = Sr25519Keyring::Alice;
|
||||
// meta tx relayer
|
||||
let bob_keyring = Sr25519Keyring::Bob;
|
||||
|
||||
let alice_account: AccountId = alice_keyring.public().into();
|
||||
let bob_account: AccountId = bob_keyring.public().into();
|
||||
|
||||
let tx_fee: Balance = (2 * TX_FEE).into(); // base tx fee + weight fee
|
||||
let alice_balance = force_set_balance(alice_account.clone());
|
||||
let bob_balance = force_set_balance(bob_account.clone());
|
||||
|
||||
// Alice builds a meta transaction.
|
||||
|
||||
// transfer more than alice has
|
||||
let transfer_call = RuntimeCall::Balances(pezpallet_balances::Call::transfer_allow_death {
|
||||
dest: bob_account.clone(),
|
||||
value: alice_balance * 2,
|
||||
});
|
||||
|
||||
let meta_tx_bare_ext = create_meta_tx_bare_ext(alice_account.clone());
|
||||
let meta_tx_sig =
|
||||
create_signature(transfer_call.clone(), meta_tx_bare_ext.clone(), alice_keyring);
|
||||
let meta_tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(meta_tx_sig, alice_account.clone()),
|
||||
// append signed part.
|
||||
meta_tx_bare_ext,
|
||||
);
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::new(
|
||||
transfer_call.clone(),
|
||||
META_EXTENSION_VERSION,
|
||||
meta_tx_ext.clone(),
|
||||
);
|
||||
|
||||
// Encode and share with the world.
|
||||
let meta_tx_encoded = meta_tx.encode();
|
||||
|
||||
// Bob acts as meta transaction relayer.
|
||||
|
||||
let meta_tx = MetaTxFor::<Runtime>::decode(&mut &meta_tx_encoded[..]).unwrap();
|
||||
let call = RuntimeCall::MetaTx(Call::dispatch { meta_tx: Box::new(meta_tx.clone()) });
|
||||
let tx_bare_ext = create_tx_bare_ext(bob_account.clone());
|
||||
let tx_sig = create_signature(call.clone(), tx_bare_ext.clone(), bob_keyring);
|
||||
let tx_ext = (
|
||||
VerifySignatureExt::new_with_signature(tx_sig, bob_account.clone()),
|
||||
// append signed part
|
||||
tx_bare_ext,
|
||||
);
|
||||
|
||||
let uxt = UncheckedExtrinsic::new_transaction(call.clone(), tx_ext.clone());
|
||||
|
||||
// Check Extrinsic validity and apply it.
|
||||
let result = apply_extrinsic(uxt);
|
||||
|
||||
// Asserting the results and make sure the weight is correct.
|
||||
|
||||
let tx_weight = tx_ext.weight(&call) + <Runtime as Config>::WeightInfo::bare_dispatch();
|
||||
let meta_tx_weight = transfer_call
|
||||
.get_dispatch_info()
|
||||
.call_weight
|
||||
.add(meta_tx_ext.weight(&transfer_call));
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(PostDispatchInfo {
|
||||
actual_weight: Some(meta_tx_weight + tx_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
})
|
||||
);
|
||||
|
||||
System::assert_has_event(RuntimeEvent::MetaTx(crate::Event::Dispatched {
|
||||
result: Err(DispatchErrorWithPostInfo {
|
||||
post_info: PostDispatchInfo {
|
||||
actual_weight: Some(meta_tx_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
},
|
||||
error: pezsp_runtime::DispatchError::Token(pezsp_runtime::TokenError::FundsUnavailable),
|
||||
}),
|
||||
}));
|
||||
|
||||
// Alice balance is unchanged, Bob paid the transaction fee.
|
||||
assert_eq!(alice_balance, Balances::free_balance(alice_account));
|
||||
assert_eq!(bob_balance - tx_fee, Balances::free_balance(bob_account));
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Autogenerated weights for `pezpallet_meta_tx`
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
|
||||
//! DATE: 2025-01-15, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! WORST CASE MAP SIZE: `1000000`
|
||||
//! HOSTNAME: `runner-ys-ssygq-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
|
||||
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
|
||||
|
||||
// Executed Command:
|
||||
// target/production/bizinikiwi-node
|
||||
// benchmark
|
||||
// pallet
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --extrinsic=*
|
||||
// --wasm-execution=compiled
|
||||
// --heap-pages=4096
|
||||
// --json-file=/builds/parity/mirrors/pezkuwi-sdk/.git/.artifacts/bench.json
|
||||
// --pallet=pezpallet_meta_tx
|
||||
// --chain=dev
|
||||
// --header=./bizinikiwi/HEADER-APACHE2
|
||||
// --output=./bizinikiwi/pezframe/meta-tx/src/weights.rs
|
||||
// --template=./bizinikiwi/.maintain/frame-weight-template.hbs
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for `pezpallet_meta_tx`.
|
||||
pub trait WeightInfo {
|
||||
fn bare_dispatch() -> Weight;
|
||||
}
|
||||
|
||||
/// Weights for `pezpallet_meta_tx` using the Bizinikiwi node and recommended hardware.
|
||||
pub struct BizinikiwiWeight<T>(PhantomData<T>);
|
||||
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
|
||||
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
|
||||
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
|
||||
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
|
||||
fn bare_dispatch() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3997`
|
||||
// Minimum execution time: 13_110_000 picoseconds.
|
||||
Weight::from_parts(13_605_000, 3997)
|
||||
.saturating_add(T::DbWeight::get().reads(2_u64))
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests.
|
||||
impl WeightInfo for () {
|
||||
/// Storage: `SafeMode::EnteredUntil` (r:1 w:0)
|
||||
/// Proof: `SafeMode::EnteredUntil` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
|
||||
/// Storage: `TxPause::PausedCalls` (r:1 w:0)
|
||||
/// Proof: `TxPause::PausedCalls` (`max_values`: None, `max_size`: Some(532), added: 3007, mode: `MaxEncodedLen`)
|
||||
fn bare_dispatch() -> Weight {
|
||||
// Proof Size summary in bytes:
|
||||
// Measured: `145`
|
||||
// Estimated: `3997`
|
||||
// Minimum execution time: 13_110_000 picoseconds.
|
||||
Weight::from_parts(13_605_000, 3997)
|
||||
.saturating_add(RocksDbWeight::get().reads(2_u64))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user