diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index a59aa5d0c8e83..94618c9349815 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -1628,7 +1628,6 @@ impl Module { /// For each element in the iterator the given number of points in u32 is added to the /// validator, thus duplicates are handled. pub fn reward_by_indices(validators_points: impl IntoIterator) { - // TODO: This can be optimised once #3302 is implemented. let current_elected_len = >::current_elected().len() as u32; CurrentEraPointsEarned::mutate(|rewards| { diff --git a/frame/staking/src/slashing.rs b/frame/staking/src/slashing.rs index 6d591603fdbcc..7322b9a1d3118 100644 --- a/frame/staking/src/slashing.rs +++ b/frame/staking/src/slashing.rs @@ -649,9 +649,6 @@ fn pay_reporters( T::Slash::on_unbalanced(value_slashed); } -// TODO: function for undoing a slash. -// - #[cfg(test)] mod tests { use super::*; diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index f1092b500230b..e44ab16458836 100644 --- a/frame/support/src/weights.rs +++ b/frame/support/src/weights.rs @@ -236,6 +236,36 @@ impl SimpleDispatchInfo { } } +/// A struct to represent a weight which is a function of the input arguments. The given items have +/// the following types: +/// +/// - `F`: a closure with the same argument list as the dispatched, wrapped in a tuple. +/// - `DispatchClass`: class of the dispatch. +/// - `bool`: whether this dispatch pays fee or not. +pub struct FunctionOf(pub F, pub DispatchClass, pub bool); + +impl WeighData for FunctionOf +where + F : Fn(Args) -> Weight +{ + fn weigh_data(&self, args: Args) -> Weight { + (self.0)(args) + } +} + +impl ClassifyDispatch for FunctionOf { + fn classify_dispatch(&self, _: Args) -> DispatchClass { + self.1.clone() + } +} + +impl PaysFee for FunctionOf { + fn pays_fee(&self, _: T) -> bool { + self.2 + } +} + + /// Implementation for unchecked extrinsic. impl GetDispatchInfo for UncheckedExtrinsic @@ -271,3 +301,46 @@ impl GetDispatchInfo for sp_runtime::testing::TestX } } } + +#[cfg(test)] +#[allow(dead_code)] +mod tests { + use crate::decl_module; + use super::*; + + pub trait Trait { + type Origin; + type Balance; + type BlockNumber; + } + + pub struct TraitImpl {} + + impl Trait for TraitImpl { + type Origin = u32; + type BlockNumber = u32; + type Balance = u32; + } + + decl_module! { + pub struct Module for enum Call where origin: T::Origin { + // no arguments, fixed weight + #[weight = SimpleDispatchInfo::FixedNormal(1000)] + fn f0(_origin) { unimplemented!(); } + + // weight = a x 10 + b + #[weight = FunctionOf(|args: (&u32, &u32)| args.0 * 10 + args.1, DispatchClass::Normal, true)] + fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); } + + #[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, true)] + fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); } + } + } + + #[test] + fn weights_are_correct() { + assert_eq!(Call::::f11(10, 20).get_dispatch_info().weight, 120); + assert_eq!(Call::::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); + assert_eq!(Call::::f0().get_dispatch_info().weight, 1000); + } +}