From 0e27b881a46ca9a367ddafeca9185c3e0d10bdc7 Mon Sep 17 00:00:00 2001 From: gupnik Date: Tue, 9 Apr 2024 14:05:46 +0530 Subject: [PATCH] Fixes validation for `SkipCheckIfFeeless` extension (#3993) During validation, `SkipCheckIfFeeless` should check if the call is `feeless` and delegate to the wrapped extension if not. --- .../skip-feeless-payment/src/lib.rs | 16 +++++++++++++- .../skip-feeless-payment/src/mock.rs | 13 ++++++++++++ .../skip-feeless-payment/src/tests.rs | 21 ++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs index 6c34c26ce9..00391d7947 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/lib.rs @@ -43,7 +43,7 @@ use frame_support::{ use scale_info::{StaticTypeInfo, TypeInfo}; use sp_runtime::{ traits::{DispatchInfoOf, PostDispatchInfoOf, SignedExtension}, - transaction_validity::TransactionValidityError, + transaction_validity::{TransactionValidity, TransactionValidityError, ValidTransaction}, }; #[cfg(test)] @@ -122,6 +122,20 @@ where self.0.additional_signed() } + fn validate( + &self, + who: &Self::AccountId, + call: &Self::Call, + info: &DispatchInfoOf, + len: usize, + ) -> TransactionValidity { + if call.is_feeless(&::RuntimeOrigin::signed(who.clone())) { + Ok(ValidTransaction::default()) + } else { + self.0.validate(who, call, info, len) + } + } + fn pre_dispatch( self, who: &Self::AccountId, diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs index 5f26680af3..4ddeae11fc 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/mock.rs @@ -33,6 +33,7 @@ impl Config for Runtime { parameter_types! { pub static PreDispatchCount: u32 = 0; + pub static ValidateCount: u32 = 0; } #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)] @@ -47,6 +48,18 @@ impl SignedExtension for DummyExtension { fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) } + + fn validate( + &self, + _who: &Self::AccountId, + _call: &Self::Call, + _info: &DispatchInfoOf, + _len: usize, + ) -> TransactionValidity { + ValidateCount::mutate(|c| *c += 1); + Ok(Default::default()) + } + fn pre_dispatch( self, _who: &Self::AccountId, diff --git a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs index 4b4dd69974..adee52d6b3 100644 --- a/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/skip-feeless-payment/src/tests.rs @@ -14,7 +14,9 @@ // limitations under the License. use super::*; -use crate::mock::{pallet_dummy::Call, DummyExtension, PreDispatchCount, Runtime, RuntimeCall}; +use crate::mock::{ + pallet_dummy::Call, DummyExtension, PreDispatchCount, Runtime, RuntimeCall, ValidateCount, +}; use frame_support::dispatch::DispatchInfo; #[test] @@ -31,3 +33,20 @@ fn skip_feeless_payment_works() { .unwrap(); assert_eq!(PreDispatchCount::get(), 1); } + +#[test] +fn validate_works() { + assert_eq!(ValidateCount::get(), 0); + + let call = RuntimeCall::DummyPallet(Call::::aux { data: 1 }); + SkipCheckIfFeeless::::from(DummyExtension) + .validate(&0, &call, &DispatchInfo::default(), 0) + .unwrap(); + assert_eq!(ValidateCount::get(), 1); + + let call = RuntimeCall::DummyPallet(Call::::aux { data: 0 }); + SkipCheckIfFeeless::::from(DummyExtension) + .validate(&0, &call, &DispatchInfo::default(), 0) + .unwrap(); + assert_eq!(ValidateCount::get(), 1); +}