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:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
@@ -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);
}
+243
View File
@@ -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-transactions
//! 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,
},
}
}
}
}
+147
View File
@@ -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
}
+398
View File
@@ -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))
}
}