From 1d73b011a906a5cba97f1c9b31ba3153c5a07168 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 8 Jan 2021 12:04:46 -0400 Subject: [PATCH] Store dispatch info of calls locally in weight calculation (#7849) * utility * sudo * more * recovery * better formatting --- substrate/frame/multisig/src/lib.rs | 17 +++++---- substrate/frame/recovery/src/lib.rs | 17 +++++---- substrate/frame/sudo/src/lib.rs | 22 +++++++---- substrate/frame/utility/src/lib.rs | 57 ++++++++++++++++------------- 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/substrate/frame/multisig/src/lib.rs b/substrate/frame/multisig/src/lib.rs index f58fe549fe..a015f291bc 100644 --- a/substrate/frame/multisig/src/lib.rs +++ b/substrate/frame/multisig/src/lib.rs @@ -223,13 +223,16 @@ decl_module! { /// - DB Weight: None /// - Plus Call Weight /// # - #[weight = ( - T::WeightInfo::as_multi_threshold_1(call.using_encoded(|c| c.len() as u32)) - .saturating_add(call.get_dispatch_info().weight) - // AccountData for inner call origin accountdata. - .saturating_add(T::DbWeight::get().reads_writes(1, 1)), - call.get_dispatch_info().class, - )] + #[weight = { + let dispatch_info = call.get_dispatch_info(); + ( + T::WeightInfo::as_multi_threshold_1(call.using_encoded(|c| c.len() as u32)) + .saturating_add(dispatch_info.weight) + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)), + dispatch_info.class, + ) + }] fn as_multi_threshold_1(origin, other_signatories: Vec, call: Box<::Call>, diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs index 7cd1eb4b02..606cb82250 100644 --- a/substrate/frame/recovery/src/lib.rs +++ b/substrate/frame/recovery/src/lib.rs @@ -352,13 +352,16 @@ decl_module! { /// - The weight of the `call` + 10,000. /// - One storage lookup to check account is recovered by `who`. O(1) /// # - #[weight = ( - call.get_dispatch_info().weight - .saturating_add(10_000) - // AccountData for inner call origin accountdata. - .saturating_add(T::DbWeight::get().reads_writes(1, 1)), - call.get_dispatch_info().class - )] + #[weight = { + let dispatch_info = call.get_dispatch_info(); + ( + dispatch_info.weight + .saturating_add(10_000) + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)), + dispatch_info.class, + ) + }] fn as_recovered(origin, account: T::AccountId, call: Box<::Call> diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs index 1d20fd2bb7..c7cc38a81c 100644 --- a/substrate/frame/sudo/src/lib.rs +++ b/substrate/frame/sudo/src/lib.rs @@ -130,7 +130,10 @@ decl_module! { /// - One DB write (event). /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = (call.get_dispatch_info().weight + 10_000, call.get_dispatch_info().class)] + #[weight = { + let dispatch_info = call.get_dispatch_info(); + (dispatch_info.weight.saturating_add(10_000), dispatch_info.class) + }] fn sudo(origin, call: Box<::Call>) -> DispatchResultWithPostInfo { // This is a public call, so we ensure that the origin is some signed account. let sender = ensure_signed(origin)?; @@ -197,13 +200,16 @@ decl_module! { /// - One DB write (event). /// - Weight of derivative `call` execution + 10,000. /// # - #[weight = ( - call.get_dispatch_info().weight - .saturating_add(10_000) - // AccountData for inner call origin accountdata. - .saturating_add(T::DbWeight::get().reads_writes(1, 1)), - call.get_dispatch_info().class - )] + #[weight = { + let dispatch_info = call.get_dispatch_info(); + ( + dispatch_info.weight + .saturating_add(10_000) + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)), + dispatch_info.class, + ) + }] fn sudo_as(origin, who: ::Source, call: Box<::Call> diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs index 2286c64fcf..28345e5ffe 100644 --- a/substrate/frame/utility/src/lib.rs +++ b/substrate/frame/utility/src/lib.rs @@ -133,22 +133,24 @@ decl_module! { /// `BatchInterrupted` event is deposited, along with the number of successful calls made /// and the error of the failed call. If all were successful, then the `BatchCompleted` /// event is deposited. - #[weight = ( - calls.iter() - .map(|call| call.get_dispatch_info().weight) + #[weight = { + let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); + let dispatch_weight = dispatch_infos.iter() + .map(|di| di.weight) .fold(0, |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(T::WeightInfo::batch(calls.len() as u32)), - { - let all_operational = calls.iter() - .map(|call| call.get_dispatch_info().class) + .saturating_add(T::WeightInfo::batch(calls.len() as u32)); + let dispatch_class = { + let all_operational = dispatch_infos.iter() + .map(|di| di.class) .all(|class| class == DispatchClass::Operational); if all_operational { DispatchClass::Operational } else { DispatchClass::Normal } - }, - )] + }; + (dispatch_weight, dispatch_class) + }] fn batch(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { let is_root = ensure_root(origin.clone()).is_ok(); let calls_len = calls.len(); @@ -190,13 +192,16 @@ decl_module! { /// NOTE: Prior to version *12, this was called `as_limited_sub`. /// /// The dispatch origin for this call must be _Signed_. - #[weight = ( - T::WeightInfo::as_derivative() - .saturating_add(call.get_dispatch_info().weight) - // AccountData for inner call origin accountdata. - .saturating_add(T::DbWeight::get().reads_writes(1, 1)), - call.get_dispatch_info().class, - )] + #[weight = { + let dispatch_info = call.get_dispatch_info(); + ( + T::WeightInfo::as_derivative() + .saturating_add(dispatch_info.weight) + // AccountData for inner call origin accountdata. + .saturating_add(T::DbWeight::get().reads_writes(1, 1)), + dispatch_info.class, + ) + }] fn as_derivative(origin, index: u16, call: Box<::Call>) -> DispatchResultWithPostInfo { let mut origin = origin; let who = ensure_signed(origin.clone())?; @@ -227,22 +232,24 @@ decl_module! { /// # /// - Complexity: O(C) where C is the number of calls to be batched. /// # - #[weight = ( - calls.iter() - .map(|call| call.get_dispatch_info().weight) + #[weight = { + let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); + let dispatch_weight = dispatch_infos.iter() + .map(|di| di.weight) .fold(0, |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(T::WeightInfo::batch_all(calls.len() as u32)), - { - let all_operational = calls.iter() - .map(|call| call.get_dispatch_info().class) + .saturating_add(T::WeightInfo::batch_all(calls.len() as u32)); + let dispatch_class = { + let all_operational = dispatch_infos.iter() + .map(|di| di.class) .all(|class| class == DispatchClass::Operational); if all_operational { DispatchClass::Operational } else { DispatchClass::Normal } - }, - )] + }; + (dispatch_weight, dispatch_class) + }] #[transactional] fn batch_all(origin, calls: Vec<::Call>) -> DispatchResultWithPostInfo { let is_root = ensure_root(origin.clone()).is_ok();