From 507909c3be71f91e060713c5d00aea6750e4140a Mon Sep 17 00:00:00 2001 From: Xiliang Chen <xlchen1291@gmail.com> Date: Mon, 13 Jan 2020 20:48:34 +1300 Subject: [PATCH] Improve PaysFee trait and dispatch info logic in utility module (#4606) * pass target to PaysFee trait and allow batch call to be free if all its calls are free * bump version * fix error --- substrate/bin/node/runtime/src/lib.rs | 4 +-- substrate/frame/evm/src/lib.rs | 4 +-- substrate/frame/example/src/lib.rs | 4 +-- substrate/frame/support/src/dispatch.rs | 10 ++++--- substrate/frame/support/src/weights.rs | 8 +++--- substrate/frame/utility/src/lib.rs | 38 +++++++++++++++---------- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index b3ff8b16283..4266ad7459e 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // and set impl_version to equal spec_version. If only runtime // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. - spec_version: 202, - impl_version: 202, + spec_version: 203, + impl_version: 203, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/frame/evm/src/lib.rs b/substrate/frame/evm/src/lib.rs index 48b54a8c867..8d504127245 100644 --- a/substrate/frame/evm/src/lib.rs +++ b/substrate/frame/evm/src/lib.rs @@ -141,8 +141,8 @@ impl<T> ClassifyDispatch<T> for WeightForCallCreate { } } -impl PaysFee for WeightForCallCreate { - fn pays_fee(&self) -> bool { +impl<T> PaysFee<T> for WeightForCallCreate { + fn pays_fee(&self, _: T) -> bool { true } } diff --git a/substrate/frame/example/src/lib.rs b/substrate/frame/example/src/lib.rs index 853674f6fd0..80569a1b573 100644 --- a/substrate/frame/example/src/lib.rs +++ b/substrate/frame/example/src/lib.rs @@ -301,8 +301,8 @@ impl<T: pallet_balances::Trait> ClassifyDispatch<(&BalanceOf<T>,)> for WeightFor } } -impl<T: pallet_balances::Trait> PaysFee for WeightForSetDummy<T> { - fn pays_fee(&self) -> bool { +impl<T: pallet_balances::Trait> PaysFee<(&BalanceOf<T>,)> for WeightForSetDummy<T> { + fn pays_fee(&self, _target: (&BalanceOf<T>,)) -> bool { true } } diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs index 7d3750d9d4e..b2d7e6e1d40 100644 --- a/substrate/frame/support/src/dispatch.rs +++ b/substrate/frame/support/src/dispatch.rs @@ -1312,8 +1312,9 @@ macro_rules! decl_module { &$weight, ($( $param_name, )*) ); - let pays_fee = <dyn $crate::dispatch::PaysFee>::pays_fee( - &$weight + let pays_fee = <dyn $crate::dispatch::PaysFee<( $( & $param, )* )>>::pays_fee( + &$weight, + ($( $param_name, )*) ); return $crate::dispatch::DispatchInfo { weight, class, pays_fee }; } @@ -1331,8 +1332,9 @@ macro_rules! decl_module { &$crate::dispatch::SimpleDispatchInfo::default(), () ); - let pays_fee = <dyn $crate::dispatch::PaysFee>::pays_fee( - &$crate::dispatch::SimpleDispatchInfo::default() + let pays_fee = <dyn $crate::dispatch::PaysFee<_>>::pays_fee( + &$crate::dispatch::SimpleDispatchInfo::default(), + () ); $crate::dispatch::DispatchInfo { weight, class, pays_fee } diff --git a/substrate/frame/support/src/weights.rs b/substrate/frame/support/src/weights.rs index b4b70def1d3..f1092b50023 100644 --- a/substrate/frame/support/src/weights.rs +++ b/substrate/frame/support/src/weights.rs @@ -78,8 +78,8 @@ pub trait WeighBlock<BlockNumber> { /// Indicates if dispatch function should pay fees or not. /// If set to false, the block resource limits are applied, yet no fee is deducted. -pub trait PaysFee { - fn pays_fee(&self) -> bool { +pub trait PaysFee<T> { + fn pays_fee(&self, _target: T) -> bool { true } } @@ -208,8 +208,8 @@ impl<T> ClassifyDispatch<T> for SimpleDispatchInfo { } } -impl PaysFee for SimpleDispatchInfo { - fn pays_fee(&self) -> bool { +impl<T> PaysFee<T> for SimpleDispatchInfo { + fn pays_fee(&self, _: T) -> bool { match self { SimpleDispatchInfo::FixedNormal(_) => true, SimpleDispatchInfo::MaxNormal => true, diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs index 1f7e861373c..9ab2975e295 100644 --- a/substrate/frame/utility/src/lib.rs +++ b/substrate/frame/utility/src/lib.rs @@ -204,9 +204,9 @@ impl<Call: GetDispatchInfo> ClassifyDispatch<(&u16, &Box<Call>)> for Passthrough call.get_dispatch_info().class } } -impl<Call: GetDispatchInfo> PaysFee for Passthrough<Call> { - fn pays_fee(&self) -> bool { - true +impl<Call: GetDispatchInfo> PaysFee<(&u16, &Box<Call>)> for Passthrough<Call> { + fn pays_fee(&self, (_, call): (&u16, &Box<Call>)) -> bool { + call.get_dispatch_info().pays_fee } } @@ -226,13 +226,21 @@ impl<Call: GetDispatchInfo> WeighData<(&Vec<Call>,)> for BatchPassthrough<Call> } } impl<Call: GetDispatchInfo> ClassifyDispatch<(&Vec<Call>,)> for BatchPassthrough<Call> { - fn classify_dispatch(&self, (_,): (&Vec<Call>,)) -> DispatchClass { - DispatchClass::Normal + fn classify_dispatch(&self, (calls,): (&Vec<Call>,)) -> DispatchClass { + let all_operational = calls.iter() + .map(|call| call.get_dispatch_info().class) + .all(|class| class == DispatchClass::Operational); + if all_operational { + DispatchClass::Operational + } else { + DispatchClass::Normal + } } } -impl<Call: GetDispatchInfo> PaysFee for BatchPassthrough<Call> { - fn pays_fee(&self) -> bool { - true +impl<Call: GetDispatchInfo> PaysFee<(&Vec<Call>,)> for BatchPassthrough<Call> { + fn pays_fee(&self, (calls,): (&Vec<Call>,)) -> bool { + calls.iter() + .any(|call| call.get_dispatch_info().pays_fee) } } @@ -254,16 +262,16 @@ for MultiPassthrough<Call, AccountId, Timepoint> impl<Call: GetDispatchInfo, AccountId, Timepoint> ClassifyDispatch<(&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)> for MultiPassthrough<Call, AccountId, Timepoint> { - fn classify_dispatch(&self, (_, _, _, _): (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)) + fn classify_dispatch(&self, (_, _, _, call): (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)) -> DispatchClass { - DispatchClass::Normal + call.get_dispatch_info().class } } -impl<Call: GetDispatchInfo, AccountId, Timepoint> PaysFee +impl<Call: GetDispatchInfo, AccountId, Timepoint> PaysFee<(&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)> for MultiPassthrough<Call, AccountId, Timepoint> { - fn pays_fee(&self) -> bool { + fn pays_fee(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &Box<Call>)) -> bool { true } } @@ -286,16 +294,16 @@ for SigsLen<AccountId, Timepoint> impl<AccountId, Timepoint> ClassifyDispatch<(&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])> for SigsLen<AccountId, Timepoint> { - fn classify_dispatch(&self, (_, _, _, _): (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])) + fn classify_dispatch(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])) -> DispatchClass { DispatchClass::Normal } } -impl<AccountId, Timepoint> PaysFee +impl<AccountId, Timepoint> PaysFee<(&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])> for SigsLen<AccountId, Timepoint> { - fn pays_fee(&self) -> bool { + fn pays_fee(&self, _: (&u16, &Vec<AccountId>, &Timepoint, &[u8; 32])) -> bool { true } } -- GitLab