mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 16:08:08 +00:00
60c77a2e9a
Fixes https://github.com/paritytech/polkadot-sdk/issues/1725 This PR adds the following changes: 1. An attribute `pallet::feeless_if` that can be optionally attached to a call like so: ```rust #[pallet::feeless_if(|_origin: &OriginFor<T>, something: &u32| -> bool { *something == 0 })] pub fn do_something(origin: OriginFor<T>, something: u32) -> DispatchResult { .... } ``` The closure passed accepts references to arguments as specified in the call fn. It returns a boolean that denotes the conditions required for this call to be "feeless". 2. A signed extension `SkipCheckIfFeeless<T: SignedExtension>` that wraps a transaction payment processor such as `pallet_transaction_payment::ChargeTransactionPayment`. It checks for all calls annotated with `pallet::feeless_if` to see if the conditions are met. If so, the wrapped signed extension is not called, essentially making the call feeless. In order to use this, you can simply replace your existing signed extension that manages transaction payment like so: ```diff - pallet_transaction_payment::ChargeTransactionPayment<Runtime>, + pallet_skip_feeless_payment::SkipCheckIfFeeless< + Runtime, + pallet_transaction_payment::ChargeTransactionPayment<Runtime>, + >, ``` ### Todo - [x] Tests - [x] Docs - [x] Prdoc --------- Co-authored-by: Nikhil Gupta <> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com> Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
116 lines
3.3 KiB
Rust
116 lines
3.3 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
//! Test accounts.
|
|
|
|
use codec::Encode;
|
|
use kitchensink_runtime::{CheckedExtrinsic, SessionKeys, SignedExtra, UncheckedExtrinsic};
|
|
use node_primitives::{AccountId, Balance, Nonce};
|
|
use sp_keyring::{AccountKeyring, Ed25519Keyring, Sr25519Keyring};
|
|
use sp_runtime::generic::Era;
|
|
|
|
/// Alice's account id.
|
|
pub fn alice() -> AccountId {
|
|
AccountKeyring::Alice.into()
|
|
}
|
|
|
|
/// Bob's account id.
|
|
pub fn bob() -> AccountId {
|
|
AccountKeyring::Bob.into()
|
|
}
|
|
|
|
/// Charlie's account id.
|
|
pub fn charlie() -> AccountId {
|
|
AccountKeyring::Charlie.into()
|
|
}
|
|
|
|
/// Dave's account id.
|
|
pub fn dave() -> AccountId {
|
|
AccountKeyring::Dave.into()
|
|
}
|
|
|
|
/// Eve's account id.
|
|
pub fn eve() -> AccountId {
|
|
AccountKeyring::Eve.into()
|
|
}
|
|
|
|
/// Ferdie's account id.
|
|
pub fn ferdie() -> AccountId {
|
|
AccountKeyring::Ferdie.into()
|
|
}
|
|
|
|
/// Convert keyrings into `SessionKeys`.
|
|
pub fn to_session_keys(
|
|
ed25519_keyring: &Ed25519Keyring,
|
|
sr25519_keyring: &Sr25519Keyring,
|
|
) -> SessionKeys {
|
|
SessionKeys {
|
|
grandpa: ed25519_keyring.to_owned().public().into(),
|
|
babe: sr25519_keyring.to_owned().public().into(),
|
|
im_online: sr25519_keyring.to_owned().public().into(),
|
|
authority_discovery: sr25519_keyring.to_owned().public().into(),
|
|
mixnet: sr25519_keyring.to_owned().public().into(),
|
|
}
|
|
}
|
|
|
|
/// Returns transaction extra.
|
|
pub fn signed_extra(nonce: Nonce, extra_fee: Balance) -> SignedExtra {
|
|
(
|
|
frame_system::CheckNonZeroSender::new(),
|
|
frame_system::CheckSpecVersion::new(),
|
|
frame_system::CheckTxVersion::new(),
|
|
frame_system::CheckGenesis::new(),
|
|
frame_system::CheckEra::from(Era::mortal(256, 0)),
|
|
frame_system::CheckNonce::from(nonce),
|
|
frame_system::CheckWeight::new(),
|
|
pallet_skip_feeless_payment::SkipCheckIfFeeless::from(
|
|
pallet_asset_conversion_tx_payment::ChargeAssetTxPayment::from(extra_fee, None),
|
|
),
|
|
)
|
|
}
|
|
|
|
/// Sign given `CheckedExtrinsic`.
|
|
pub fn sign(
|
|
xt: CheckedExtrinsic,
|
|
spec_version: u32,
|
|
tx_version: u32,
|
|
genesis_hash: [u8; 32],
|
|
) -> UncheckedExtrinsic {
|
|
match xt.signed {
|
|
Some((signed, extra)) => {
|
|
let payload =
|
|
(xt.function, extra.clone(), spec_version, tx_version, genesis_hash, genesis_hash);
|
|
let key = AccountKeyring::from_account_id(&signed).unwrap();
|
|
let signature = payload
|
|
.using_encoded(|b| {
|
|
if b.len() > 256 {
|
|
key.sign(&sp_io::hashing::blake2_256(b))
|
|
} else {
|
|
key.sign(b)
|
|
}
|
|
})
|
|
.into();
|
|
UncheckedExtrinsic {
|
|
signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)),
|
|
function: payload.0,
|
|
}
|
|
},
|
|
None => UncheckedExtrinsic { signature: None, function: xt.function },
|
|
}
|
|
}
|