diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index a59aa5d0c8e831b4eb007c5dbdd11270dbfdff16..94618c9349815c7ed5581e89cf5aff7a0c55b5ed 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -1628,7 +1628,6 @@ impl<T: Trait> Module<T> { /// 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<Item = (u32, u32)>) { - // TODO: This can be optimised once #3302 is implemented. let current_elected_len = <Module<T>>::current_elected().len() as u32; CurrentEraPointsEarned::mutate(|rewards| { diff --git a/substrate/frame/staking/src/slashing.rs b/substrate/frame/staking/src/slashing.rs index 6d591603fdbccb4e154deef2a5c31c95189ff301..7322b9a1d3118022cbc113f47be5c0dc7ded8822 100644 --- a/substrate/frame/staking/src/slashing.rs +++ b/substrate/frame/staking/src/slashing.rs @@ -649,9 +649,6 @@ fn pay_reporters<T: Trait>( T::Slash::on_unbalanced(value_slashed); } -// TODO: function for undoing a slash. -// - #[cfg(test)] mod tests { use super::*; diff --git a/substrate/frame/support/src/weights.rs b/substrate/frame/support/src/weights.rs index f1092b500230b5888385f0e14427ede776c3d2ce..e44ab16458836bd50503d3c1ee1fbd7d0842b5d7 100644 --- a/substrate/frame/support/src/weights.rs +++ b/substrate/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<F>(pub F, pub DispatchClass, pub bool); + +impl<Args, F> WeighData<Args> for FunctionOf<F> +where + F : Fn(Args) -> Weight +{ + fn weigh_data(&self, args: Args) -> Weight { + (self.0)(args) + } +} + +impl<Args, F> ClassifyDispatch<Args> for FunctionOf<F> { + fn classify_dispatch(&self, _: Args) -> DispatchClass { + self.1.clone() + } +} + +impl<T, F> PaysFee<T> for FunctionOf<F> { + fn pays_fee(&self, _: T) -> bool { + self.2 + } +} + + /// Implementation for unchecked extrinsic. impl<Address, Call, Signature, Extra> GetDispatchInfo for UncheckedExtrinsic<Address, Call, Signature, Extra> @@ -271,3 +301,46 @@ impl<Call: Encode, Extra: Encode> 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<T: Trait> 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::<TraitImpl>::f11(10, 20).get_dispatch_info().weight, 120); + assert_eq!(Call::<TraitImpl>::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal); + assert_eq!(Call::<TraitImpl>::f0().get_dispatch_info().weight, 1000); + } +}