From 04c438678c684595eac0fd20793092eda6fd2131 Mon Sep 17 00:00:00 2001 From: Bryan Chen Date: Fri, 22 Nov 2019 23:14:22 +1300 Subject: [PATCH] Add PaysFee trait --- palette/contracts/src/tests.rs | 2 +- palette/example/src/lib.rs | 8 ++++- palette/support/src/dispatch.rs | 18 +++++++---- palette/system/src/lib.rs | 10 +++--- palette/transaction-payment/src/lib.rs | 43 +++++++++++++------------ primitives/sr-primitives/src/weights.rs | 34 ++++++++++++------- 6 files changed, 71 insertions(+), 44 deletions(-) diff --git a/palette/contracts/src/tests.rs b/palette/contracts/src/tests.rs index 28ba77f0bbfc7..a808cc0807d33 100644 --- a/palette/contracts/src/tests.rs +++ b/palette/contracts/src/tests.rs @@ -2329,7 +2329,7 @@ fn cannot_self_destruct_in_constructor() { #[test] fn check_block_gas_limit_works() { ExtBuilder::default().block_gas_limit(50).build().execute_with(|| { - let info = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: false }; let check = CheckBlockGasLimit::(Default::default()); let call: Call = crate::Call::put_code(1000, vec![]).into(); diff --git a/palette/example/src/lib.rs b/palette/example/src/lib.rs index 87693fcfa8bc6..752a05873f324 100644 --- a/palette/example/src/lib.rs +++ b/palette/example/src/lib.rs @@ -259,7 +259,7 @@ use system::{ensure_signed, ensure_root}; use codec::{Encode, Decode}; use sr_primitives::{ traits::{SignedExtension, Bounded, SaturatedConversion}, - weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight}, + weights::{SimpleDispatchInfo, DispatchInfo, DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee}, transaction_validity::{ ValidTransaction, TransactionValidityError, InvalidTransaction, TransactionValidity, }, @@ -299,6 +299,12 @@ impl ClassifyDispatch<(&BalanceOf,)> for WeightForSetDumm } } +impl PaysFee for WeightForSetDummy { + fn pays_fee(&self) -> bool { + true + } +} + /// A type alias for the balance type from this module's point of view. type BalanceOf = ::Balance; diff --git a/palette/support/src/dispatch.rs b/palette/support/src/dispatch.rs index d8d2391734cf2..dda22d6b0ed58 100644 --- a/palette/support/src/dispatch.rs +++ b/palette/support/src/dispatch.rs @@ -26,7 +26,7 @@ pub use palette_metadata::{ pub use sr_primitives::{ weights::{ SimpleDispatchInfo, GetDispatchInfo, DispatchInfo, WeighData, ClassifyDispatch, - TransactionPriority, Weight, WeighBlock, + TransactionPriority, Weight, WeighBlock, PaysFee, }, traits::{Dispatchable, DispatchResult, ModuleDispatchError}, DispatchError, @@ -1276,7 +1276,10 @@ macro_rules! decl_module { &$weight, ($( $param_name, )*) ); - return $crate::dispatch::DispatchInfo { weight, class }; + let pays_fee = ::pays_fee( + &$weight + ); + return $crate::dispatch::DispatchInfo { weight, class, pays_fee }; } if let $call_type::__PhantomItem(_, _) = self { unreachable!("__PhantomItem should never be used.") } )* @@ -1292,7 +1295,10 @@ macro_rules! decl_module { &$crate::dispatch::SimpleDispatchInfo::default(), () ); - $crate::dispatch::DispatchInfo { weight, class } + let pays_fee = ::pays_fee( + &$crate::dispatch::SimpleDispatchInfo::default() + ); + $crate::dispatch::DispatchInfo { weight, class, pays_fee } } } @@ -2021,17 +2027,17 @@ mod tests { // operational. assert_eq!( Call::::operational().get_dispatch_info(), - DispatchInfo { weight: 5, class: DispatchClass::Operational }, + DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: true }, ); // default weight. assert_eq!( Call::::aux_0().get_dispatch_info(), - DispatchInfo { weight: 10_000, class: DispatchClass::Normal }, + DispatchInfo { weight: 10_000, class: DispatchClass::Normal, pays_fee: true }, ); // custom basic assert_eq!( Call::::aux_3().get_dispatch_info(), - DispatchInfo { weight: 3, class: DispatchClass::Normal }, + DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: true }, ); } diff --git a/palette/system/src/lib.rs b/palette/system/src/lib.rs index 51b7820a43f88..bce4df8602d66 100644 --- a/palette/system/src/lib.rs +++ b/palette/system/src/lib.rs @@ -1405,7 +1405,7 @@ mod tests { fn signed_ext_check_weight_works_operational_tx() { new_test_ext().execute_with(|| { let normal = DispatchInfo { weight: 100, ..Default::default() }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; let len = 0_usize; let normal_limit = normal_weight_limit(); @@ -1427,8 +1427,8 @@ mod tests { #[test] fn signed_ext_check_weight_priority_works() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; - let op = DispatchInfo { weight: 100, class: DispatchClass::Operational }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; + let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true }; let len = 0_usize; let priority = CheckWeight::(PhantomData) @@ -1461,7 +1461,7 @@ mod tests { reset_check_weight(normal, normal_limit + 1, true); // Operational ones don't have this limit. - let op = DispatchInfo { weight: 0, class: DispatchClass::Operational }; + let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true }; reset_check_weight(op, normal_limit, false); reset_check_weight(op, normal_limit + 100, false); reset_check_weight(op, 1024, false); @@ -1488,7 +1488,7 @@ mod tests { #[test] fn signed_ext_check_era_should_change_longevity() { new_test_ext().execute_with(|| { - let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal }; + let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true }; let len = 0_usize; let ext = ( CheckWeight::(PhantomData), diff --git a/palette/transaction-payment/src/lib.rs b/palette/transaction-payment/src/lib.rs index 2314edf053958..a4e131904cca1 100644 --- a/palette/transaction-payment/src/lib.rs +++ b/palette/transaction-payment/src/lib.rs @@ -118,7 +118,7 @@ impl Module { let dispatch_info = ::get_dispatch_info(&unchecked_extrinsic); let partial_fee = >::compute_fee(len, dispatch_info, 0u32.into()); - let DispatchInfo { weight, class } = dispatch_info; + let DispatchInfo { weight, class, .. } = dispatch_info; RuntimeDispatchInfo { weight, class, partial_fee } } @@ -145,28 +145,28 @@ impl ChargeTransactionPayment { /// - (optional) _tip_: if included in the transaction, it will be added on top. Only signed /// transactions can have a tip. fn compute_fee(len: u32, info: DispatchInfo, tip: BalanceOf) -> BalanceOf { - let len_fee = if info.pay_length_fee() { + if info.pays_fee { let len = >::from(len); let base = T::TransactionBaseFee::get(); let per_byte = T::TransactionByteFee::get(); - base.saturating_add(per_byte.saturating_mul(len)) - } else { - Zero::zero() - }; + let len_fee = base.saturating_add(per_byte.saturating_mul(len)); - let weight_fee = { - // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` - // maximum of its data type, which is not desired. - let capped_weight = info.weight.min(::MaximumBlockWeight::get()); - T::WeightToFee::convert(capped_weight) - }; + let weight_fee = { + // cap the weight to the maximum defined in runtime, otherwise it will be the `Bounded` + // maximum of its data type, which is not desired. + let capped_weight = info.weight.min(::MaximumBlockWeight::get()); + T::WeightToFee::convert(capped_weight) + }; - // everything except for tip - let basic_fee = len_fee.saturating_add(weight_fee); - let fee_update = NextFeeMultiplier::get(); - let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); + // everything except for tip + let basic_fee = len_fee.saturating_add(weight_fee); + let fee_update = NextFeeMultiplier::get(); + let adjusted_fee = fee_update.saturated_multiply_accumulate(basic_fee); - adjusted_fee.saturating_add(tip) + adjusted_fee.saturating_add(tip) + } else { + tip + } } } @@ -451,12 +451,14 @@ mod tests { // 1 ain't have a penny. assert_eq!(Balances::free_balance(&1), 0); + let len = 100; + // like a FreeOperational let operational_transaction = DispatchInfo { weight: 0, - class: DispatchClass::Operational + class: DispatchClass::Operational, + pays_fee: false, }; - let len = 100; assert!( ChargeTransactionPayment::::from(0) .validate(&1, CALL, operational_transaction , len) @@ -466,7 +468,8 @@ mod tests { // like a FreeNormal let free_transaction = DispatchInfo { weight: 0, - class: DispatchClass::Normal + class: DispatchClass::Normal, + pays_fee: false }; assert!( ChargeTransactionPayment::::from(0) diff --git a/primitives/sr-primitives/src/weights.rs b/primitives/sr-primitives/src/weights.rs index 09ebe3591394b..af0f11ab919d5 100644 --- a/primitives/sr-primitives/src/weights.rs +++ b/primitives/sr-primitives/src/weights.rs @@ -72,6 +72,13 @@ pub trait WeighBlock { fn on_finalize(_: BlockNumber) -> Weight { Zero::zero() } } +pub trait PaysFee { + /// Indicates if dispatch function should pays fee. + fn pays_fee(&self) -> bool { + true + } +} + /// Maybe I can do something to remove the duplicate code here. #[impl_for_tuples(30)] impl WeighBlock for SingleModule { @@ -132,17 +139,8 @@ pub struct DispatchInfo { pub weight: Weight, /// Class of this transaction. pub class: DispatchClass, -} - -impl DispatchInfo { - /// Determine if this dispatch should pay the base length-related fee or not. - pub fn pay_length_fee(&self) -> bool { - match self.class { - DispatchClass::Normal => true, - // For now we assume all operational transactions don't pay the length fee. - DispatchClass::Operational => false, - } - } + /// Does this transaction pays fee. + pub pays_fee: bool, } /// A `Dispatchable` function (aka transaction) that can carry some static information along with @@ -206,6 +204,20 @@ impl ClassifyDispatch for SimpleDispatchInfo { } } +impl PaysFee for SimpleDispatchInfo { + fn pays_fee(&self) -> bool { + match self { + SimpleDispatchInfo::FixedNormal(_) => true, + SimpleDispatchInfo::MaxNormal => true, + SimpleDispatchInfo::FreeNormal => false, + + SimpleDispatchInfo::FixedOperational(_) => true, + SimpleDispatchInfo::MaxOperational => true, + SimpleDispatchInfo::FreeOperational => false, + } + } +} + impl Default for SimpleDispatchInfo { fn default() -> Self { // Default weight of all transactions.