diff --git a/pallets/asset/src/lib.rs b/pallets/asset/src/lib.rs index 613ab74bb..c195e4d0b 100644 --- a/pallets/asset/src/lib.rs +++ b/pallets/asset/src/lib.rs @@ -565,8 +565,11 @@ decl_module! { #[weight = ::WeightInfo::create_asset( asset_name.len() as u32, asset_identifiers.len() as u32, - funding_round_name.as_ref().map_or(0, |name| name.len()) as u32 - ) + ::WeightInfo::register_custom_asset_type(custom_asset_type.len() as u32)] + funding_round_name.as_ref().map_or(0, |name| name.len()) as u32, + ) + .saturating_add(::WeightInfo::register_custom_asset_type( + custom_asset_type.len() as u32, + ))] pub fn create_asset_with_custom_type( origin, asset_name: AssetName, diff --git a/pallets/common/src/traits/portfolio.rs b/pallets/common/src/traits/portfolio.rs index 7463c9ece..bbad3a0f2 100644 --- a/pallets/common/src/traits/portfolio.rs +++ b/pallets/common/src/traits/portfolio.rs @@ -100,7 +100,7 @@ pub trait PortfolioSubTrait { } pub trait WeightInfo { - fn create_portfolio() -> Weight; + fn create_portfolio(l: u32) -> Weight; fn delete_portfolio() -> Weight; fn rename_portfolio(i: u32) -> Weight; fn quit_portfolio_custody() -> Weight; diff --git a/pallets/portfolio/src/benchmarking.rs b/pallets/portfolio/src/benchmarking.rs index 38f4f464e..848ec8df1 100644 --- a/pallets/portfolio/src/benchmarking.rs +++ b/pallets/portfolio/src/benchmarking.rs @@ -67,13 +67,14 @@ benchmarks! { where_clause { where T: TestUtilsFn> + AssetConfig } create_portfolio { - let target = user::("target", 0); - let did = target.did(); - let portfolio_name = PortfolioName(vec![65u8; PORTFOLIO_NAME_LEN]); - let next_portfolio_num = NextPortfolioNumber::get(&did); - }: _(target.origin, portfolio_name.clone()) + let l in 1..PORTFOLIO_NAME_LEN.try_into().unwrap(); + + let alice = UserBuilder::::default().generate_did().build("Alice"); + let next_portfolio_num = NextPortfolioNumber::get(alice.did()); + let portfolio_name = PortfolioName(vec![65; l as usize]); + }: _(alice.origin.clone(), portfolio_name.clone()) verify { - assert_eq!(Portfolios::get(&did, &next_portfolio_num), Some(portfolio_name)); + assert_eq!(Portfolios::get(alice.did(), next_portfolio_num), Some(portfolio_name)); } delete_portfolio { diff --git a/pallets/portfolio/src/lib.rs b/pallets/portfolio/src/lib.rs index 8ad23ca97..6c6600ff5 100644 --- a/pallets/portfolio/src/lib.rs +++ b/pallets/portfolio/src/lib.rs @@ -171,7 +171,9 @@ decl_error! { /// The caller doesn't have permission to create portfolios on the owner's behalf. MissingOwnersPermission, /// The sender identity can't be the same as the receiver identity. - InvalidTransferSenderIdMatchesReceiverId + InvalidTransferSenderIdMatchesReceiverId, + /// Adding itself as an AllowedCustodian is not permitted. + SelfAdditionNotAllowed } } @@ -190,7 +192,7 @@ decl_module! { } /// Creates a portfolio with the given `name`. - #[weight = ::WeightInfo::create_portfolio()] + #[weight = ::WeightInfo::create_portfolio(name.len() as u32)] pub fn create_portfolio(origin, name: PortfolioName) -> DispatchResult { let callers_did = Identity::::ensure_perms(origin)?; Self::base_create_portfolio(callers_did, name) @@ -857,6 +859,10 @@ impl Module { trusted_identity: IdentityId, ) -> DispatchResult { let callers_did = Identity::::ensure_perms(origin)?; + ensure!( + callers_did != trusted_identity, + Error::::SelfAdditionNotAllowed + ); AllowedCustodians::insert(callers_did, trusted_identity, true); Ok(()) } diff --git a/pallets/runtime/tests/src/portfolio.rs b/pallets/runtime/tests/src/portfolio.rs index 48199ba29..db3661765 100644 --- a/pallets/runtime/tests/src/portfolio.rs +++ b/pallets/runtime/tests/src/portfolio.rs @@ -1118,3 +1118,15 @@ fn create_custody_portfolio_revoke_permission() { ); }); } + +#[test] +fn allow_identity_to_create_portfolios_not_allowed() { + ExtBuilder::default().build().execute_with(|| { + let alice = User::new(AccountKeyring::Alice); + + assert_noop!( + Portfolio::allow_identity_to_create_portfolios(alice.origin(), alice.did), + Error::SelfAdditionNotAllowed + ); + }); +} diff --git a/pallets/utility/src/benchmarking.rs b/pallets/utility/src/benchmarking.rs index 69d10f010..55a987297 100644 --- a/pallets/utility/src/benchmarking.rs +++ b/pallets/utility/src/benchmarking.rs @@ -29,9 +29,6 @@ use polymesh_common_utilities::traits::TestUtilsFn; use super::*; -// POLYMESH: -const MAX_CALLS: u32 = 30; - const SEED: u32 = 0; fn assert_last_event(generic_event: ::RuntimeEvent) { @@ -151,45 +148,6 @@ benchmarks! { assert!(Pallet::::ensure_root(u.origin.into()).is_err()); } - // POLYMESH: - batch_old { - let c in 0..MAX_CALLS; - - let u = UserBuilder::::default().generate_did().build("ALICE"); - let calls = make_calls::(c); - - }: _(u.origin, calls) - verify { - // NB In this case we are using `frame_system::Call::::remark` which makes *no DB - // operations*. This helps us to fetch the DB read/write ops only from `batch` instead of - // its batched calls. - // So there is no way to verify it. - // The following cases use `balances::transfer` to be able to verify their outputs. - } - - // POLYMESH: - batch_atomic { - let c in 0..MAX_CALLS; - - let alice = UserBuilder::::default().generate_did().build("ALICE"); - let calls = make_calls::(c); - }: _(alice.origin, calls) - verify { - // NB see comment at `batch` verify section. - } - - // POLYMESH: - batch_optimistic { - let c in 0..MAX_CALLS; - - let alice = UserBuilder::::default().generate_did().build("ALICE"); - let calls = make_calls::(c); - - }: _(alice.origin, calls) - verify { - // NB see comment at `batch` verify section. - } - // POLYMESH: as_derivative { let index = 1; diff --git a/pallets/utility/src/lib.rs b/pallets/utility/src/lib.rs index d09b05986..ba67cfbff 100644 --- a/pallets/utility/src/lib.rs +++ b/pallets/utility/src/lib.rs @@ -69,13 +69,13 @@ mod benchmarking; use codec::{Decode, Encode}; +use frame_support::dispatch::DispatchClass; use frame_support::dispatch::{extract_actual_weight, GetDispatchInfo, PostDispatchInfo}; use frame_support::dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight}; use frame_support::ensure; -use frame_support::storage::{with_transaction, TransactionOutcome}; use frame_support::traits::GetCallMetadata; use frame_support::traits::{IsSubType, OriginTrait, UnfilteredDispatchable}; -use frame_system::{ensure_root, ensure_signed, Pallet as System, RawOrigin}; +use frame_system::{ensure_root, ensure_signed, RawOrigin}; use scale_info::TypeInfo; use sp_core::Get; use sp_io::hashing::blake2_256; @@ -101,9 +101,6 @@ pub trait WeightInfo { // POLYMESH: fn ensure_root() -> Weight; fn relay_tx() -> Weight; - fn batch_old(c: u32) -> Weight; - fn batch_atomic(c: u32) -> Weight; - fn batch_optimistic(c: u32) -> Weight; fn as_derivative() -> Weight; } @@ -197,20 +194,6 @@ pub mod pallet { target: T::AccountId, result: DispatchResult, }, - /// Batch of dispatches did not complete fully. - /// Includes a vector of event counts for each dispatch and - /// the index of the first failing dispatch as well as the error. - /// POLYMESH: event deprecated. - BatchInterruptedOld(EventCounts, ErrorAt), - /// Batch of dispatches did not complete fully. - /// Includes a vector of event counts for each call and - /// a vector of any failed dispatches with their indices and associated error. - /// POLYMESH: event deprecated. - BatchOptimisticFailed(EventCounts, Vec), - /// Batch of dispatches completed fully with no error. - /// Includes a vector of event counts for each dispatch. - /// POLYMESH: event deprecated. - BatchCompletedOld(EventCounts), } // Align the call size to 1KB. As we are currently compiling the runtime for native/wasm @@ -295,23 +278,10 @@ pub mod pallet { /// event is deposited. #[pallet::call_index(0)] #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::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) - })] + let (dispatch_weight, dispatch_class) = Pallet::::weight_and_dispatch_class(&calls); + let dispatch_weight = dispatch_weight.saturating_add(::WeightInfo::batch(calls.len() as u32)); + (dispatch_weight, dispatch_class) + })] pub fn batch( origin: OriginFor, calls: Vec<::RuntimeCall>, @@ -345,13 +315,13 @@ pub mod pallet { let base_weight = ::WeightInfo::batch(index.saturating_add(1) as u32); // Return the actual used weight + base_weight of this call. - return Ok(Some(base_weight + weight).into()); + return Ok(Some(base_weight.saturating_add(weight)).into()); } Self::deposit_event(Event::::ItemCompleted); } Self::deposit_event(Event::::BatchCompleted); let base_weight = ::WeightInfo::batch(calls_len as u32); - Ok(Some(base_weight + weight).into()) + Ok(Some(base_weight.saturating_add(weight)).into()) } /// Relay a call for a target from an origin @@ -433,23 +403,10 @@ pub mod pallet { /// - O(C) where C is the number of calls to be batched. #[pallet::call_index(2)] #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::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) - })] + let (dispatch_weight, dispatch_class) = Pallet::::weight_and_dispatch_class(&calls); + let dispatch_weight = dispatch_weight.saturating_add(::WeightInfo::batch_all(calls.len() as u32)); + (dispatch_weight, dispatch_class) + })] pub fn batch_all( origin: OriginFor, calls: Vec<::RuntimeCall>, @@ -492,7 +449,7 @@ pub mod pallet { let base_weight = ::WeightInfo::batch_all(index.saturating_add(1) as u32); // Return the actual used weight + base_weight of this call. - err.post_info = Some(base_weight + weight).into(); + err.post_info = Some(base_weight.saturating_add(weight)).into(); err })?; Self::deposit_event(Event::::ItemCompleted); @@ -540,23 +497,10 @@ pub mod pallet { /// - O(C) where C is the number of calls to be batched. #[pallet::call_index(4)] #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::WeightInfo::force_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) - })] + let (dispatch_weight, dispatch_class) = Pallet::::weight_and_dispatch_class(&calls); + let dispatch_weight = dispatch_weight.saturating_add(::WeightInfo::force_batch(calls.len() as u32)); + (dispatch_weight, dispatch_class) + })] pub fn force_batch( origin: OriginFor, calls: Vec<::RuntimeCall>, @@ -618,177 +562,6 @@ pub mod pallet { Ok(().into()) } - /// Dispatch multiple calls from the sender's origin. - /// - /// This will execute until the first one fails and then stop. - /// - /// May be called from root or a signed origin. - /// - ///# Parameters - /// - `calls`: The calls to be dispatched from the same origin. - /// - /// # Weight - /// - The sum of the weights of the `calls`. - /// - One event. - /// - /// This will return `Ok` in all circumstances except an unsigned origin. To determine the success of the batch, an - /// event is deposited. If a call failed and the batch was interrupted, then the - /// `BatchInterruptedOld` event is deposited, along with the number of successful calls made - /// and the error of the failed call. If all were successful, then the `BatchCompletedOld` - /// event is deposited. - /// - /// POLYMESH: Renamed from `batch` and deprecated. - #[pallet::call_index(6)] - #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::WeightInfo::batch_old(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) - })] - #[allow(deprecated)] - #[deprecated(note = "Please use `batch` instead.")] - pub fn batch_old( - origin: OriginFor, - calls: Vec<::RuntimeCall>, - ) -> DispatchResult { - let is_root = Self::ensure_root_or_signed(origin.clone())?; - - // Run batch - Self::deposit_event(Self::run_batch(origin, is_root, calls, true)); - Ok(()) - } - - /// Dispatch multiple calls from the sender's origin. - /// - /// This will execute all calls, in order, stopping at the first failure, - /// in which case the state changes are rolled back. - /// On failure, an event `BatchInterruptedOld(failure_idx, error)` is deposited. - /// - /// May be called from root or a signed origin. - /// - ///# Parameters - /// - `calls`: The calls to be dispatched from the same origin. - /// - /// # Weight - /// - The sum of the weights of the `calls`. - /// - One event. - /// - /// This will return `Ok` in all circumstances except an unsigned origin. - /// To determine the success of the batch, an event is deposited. - /// If any call failed, then `BatchInterruptedOld` is deposited. - /// If all were successful, then the `BatchCompletedOld` event is deposited. - /// - /// POLYMESH: deprecated. - #[pallet::call_index(7)] - #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::WeightInfo::batch_atomic(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) - })] - #[allow(deprecated)] - #[deprecated(note = "Please use `batch_all` instead.")] - pub fn batch_atomic( - origin: OriginFor, - calls: Vec<::RuntimeCall>, - ) -> DispatchResult { - let is_root = Self::ensure_root_or_signed(origin.clone())?; - - // Run batch inside a transaction - Self::deposit_event(with_transaction( - || -> TransactionOutcome> { - // Run batch. - match Self::run_batch(origin, is_root, calls, true) { - ev @ Event::::BatchCompletedOld(_) => TransactionOutcome::Commit(Ok(ev)), - ev => { - // Batch didn't complete. Rollback transaction. - TransactionOutcome::Rollback(Ok(ev)) - } - } - }, - )?); - Ok(()) - } - - /// Dispatch multiple calls from the sender's origin. - /// - /// This will execute all calls, in order, irrespective of failures. - /// Any failures will be available in a `BatchOptimisticFailed` event. - /// - /// May be called from root or a signed origin. - /// - ///# Parameters - /// - `calls`: The calls to be dispatched from the same origin. - /// - /// - /// # Weight - /// - The sum of the weights of the `calls`. - /// - One event. - /// - /// This will return `Ok` in all circumstances except an unsigned origin. - /// To determine the success of the batch, an event is deposited. - /// If any call failed, then `BatchOptimisticFailed` is deposited, - /// with a vector of event counts for each call as well as a vector - /// of errors. - /// If all were successful, then the `BatchCompletedOld` event is deposited. - /// - /// POLYMESH: deprecated. - #[pallet::call_index(8)] - #[pallet::weight({ - let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()).collect::>(); - let dispatch_weight = dispatch_infos.iter() - .map(|di| di.weight) - .fold(Weight::zero(), |total: Weight, weight: Weight| total.saturating_add(weight)) - .saturating_add(::WeightInfo::batch_optimistic(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) - })] - #[allow(deprecated)] - #[deprecated(note = "Please use `force_batch` instead.")] - pub fn batch_optimistic( - origin: OriginFor, - calls: Vec<::RuntimeCall>, - ) -> DispatchResult { - let is_root = Self::ensure_root_or_signed(origin.clone())?; - - // Optimistically (hey, it's in the function name, :wink:) assume no errors. - Self::deposit_event(Self::run_batch(origin, is_root, calls, false)); - Ok(()) - } - /// Send a call through an indexed pseudonym of the sender. /// /// Filter from origin are passed along. The call will be dispatched with an origin which @@ -815,6 +588,29 @@ pub mod pallet { } } +impl Pallet { + /// Get the accumulated `weight` and the dispatch class for the given `calls`. + fn weight_and_dispatch_class(calls: &[::RuntimeCall]) -> (Weight, DispatchClass) { + let dispatch_infos = calls.iter().map(|call| call.get_dispatch_info()); + let (dispatch_weight, dispatch_class) = dispatch_infos.fold( + (Weight::zero(), DispatchClass::Operational), + |(total_weight, dispatch_class): (Weight, DispatchClass), di| { + ( + total_weight.saturating_add(di.weight), + // If not all are `Operational`, we want to use `DispatchClass::Normal`. + if di.class == DispatchClass::Normal { + di.class + } else { + dispatch_class + }, + ) + }, + ); + + (dispatch_weight, dispatch_class) + } +} + // POLYMESH: impl Pallet { fn dispatch_call( @@ -832,38 +628,6 @@ impl Pallet { }) } - fn run_batch( - origin: T::RuntimeOrigin, - is_root: bool, - calls: Vec<::RuntimeCall>, - stop_on_errors: bool, - ) -> Event { - let mut counts = EventCounts::with_capacity(calls.len()); - let mut errors = Vec::new(); - for (index, call) in calls.into_iter().enumerate() { - let count = System::::event_count(); - - // Dispatch the call in a modified metadata context. - let res = Self::dispatch_call(origin.clone(), is_root, call); - counts.push(System::::event_count().saturating_sub(count)); - - // Handle call error. - if let Err(e) = res { - let err_at = (index as u32, e.error); - if stop_on_errors { - // Interrupt the batch on first error. - return Event::::BatchInterruptedOld(counts, err_at); - } - errors.push(err_at); - } - } - if errors.is_empty() { - Event::::BatchCompletedOld(counts) - } else { - Event::::BatchOptimisticFailed(counts, errors) - } - } - /// Ensure `origin` is Root, if not return a fix small weight. pub(crate) fn ensure_root(origin: T::RuntimeOrigin) -> DispatchResultWithPostInfo { // Ensure the origin is Root. @@ -877,14 +641,6 @@ impl Pallet { Ok(().into()) } - fn ensure_root_or_signed(origin: T::RuntimeOrigin) -> Result { - let is_root = ensure_root(origin.clone()).is_ok(); - if !is_root { - ensure_signed(origin)?; - } - Ok(is_root) - } - fn base_dispatch_as( origin: T::RuntimeOrigin, as_origin: Box, diff --git a/pallets/weights/src/pallet_portfolio.rs b/pallets/weights/src/pallet_portfolio.rs index 4cc764454..4f1b23ccb 100644 --- a/pallets/weights/src/pallet_portfolio.rs +++ b/pallets/weights/src/pallet_portfolio.rs @@ -61,9 +61,12 @@ impl pallet_portfolio::WeightInfo for SubstrateWeight { // Proof Skipped: Portfolio NextPortfolioNumber (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio Portfolios (r:0 w:1) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) - fn create_portfolio() -> Weight { + /// The range of component `l` is `[1, 500]`. + fn create_portfolio(l: u32) -> Weight { // Minimum execution time: 39_290 nanoseconds. Weight::from_ref_time(47_172_000) + // Standard Error: 356 + .saturating_add(Weight::from_ref_time(7_568).saturating_mul(l.into())) .saturating_add(DbWeight::get().reads(3)) .saturating_add(DbWeight::get().writes(3)) } diff --git a/pallets/weights/src/pallet_utility.rs b/pallets/weights/src/pallet_utility.rs index 636c70b72..e90dbe6a5 100644 --- a/pallets/weights/src/pallet_utility.rs +++ b/pallets/weights/src/pallet_utility.rs @@ -128,45 +128,6 @@ impl pallet_utility::WeightInfo for SubstrateWeight { // Minimum execution time: 732 nanoseconds. Weight::from_ref_time(793_000) } - // Storage: Permissions CurrentPalletName (r:1 w:1) - // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) - // Storage: Permissions CurrentDispatchableName (r:1 w:1) - // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) - /// The range of component `c` is `[0, 30]`. - fn batch_old(c: u32) -> Weight { - // Minimum execution time: 9_093 nanoseconds. - Weight::from_ref_time(14_138_346) - // Standard Error: 52_467 - .saturating_add(Weight::from_ref_time(10_800_694).saturating_mul(c.into())) - .saturating_add(DbWeight::get().reads(2)) - .saturating_add(DbWeight::get().writes(2)) - } - // Storage: Permissions CurrentPalletName (r:1 w:1) - // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) - // Storage: Permissions CurrentDispatchableName (r:1 w:1) - // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) - /// The range of component `c` is `[0, 30]`. - fn batch_atomic(c: u32) -> Weight { - // Minimum execution time: 10_366 nanoseconds. - Weight::from_ref_time(17_579_219) - // Standard Error: 49_493 - .saturating_add(Weight::from_ref_time(10_695_749).saturating_mul(c.into())) - .saturating_add(DbWeight::get().reads(2)) - .saturating_add(DbWeight::get().writes(2)) - } - // Storage: Permissions CurrentPalletName (r:1 w:1) - // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) - // Storage: Permissions CurrentDispatchableName (r:1 w:1) - // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) - /// The range of component `c` is `[0, 30]`. - fn batch_optimistic(c: u32) -> Weight { - // Minimum execution time: 8_483 nanoseconds. - Weight::from_ref_time(14_635_522) - // Standard Error: 48_924 - .saturating_add(Weight::from_ref_time(10_810_780).saturating_mul(c.into())) - .saturating_add(DbWeight::get().reads(2)) - .saturating_add(DbWeight::get().writes(2)) - } // Storage: Identity CurrentPayer (r:1 w:1) // Proof Skipped: Identity CurrentPayer (max_values: Some(1), max_size: None, mode: Measured) // Storage: Permissions CurrentPalletName (r:1 w:1)