From f170af615c0dc413482100892758b236d1fda93b Mon Sep 17 00:00:00 2001 From: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:53:25 +0200 Subject: [PATCH] Coretime auto-renew (#4424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds functionality that allows tasks to enable auto-renewal. Each task eligible for renewal can enable auto-renewal. A new storage value is added to track all the cores with auto-renewal enabled and the associated task running on the core. The `BoundedVec` is sorted by `CoreIndex` to make disabling auto-renewal more efficient. Cores are renewed at the start of a new bulk sale. If auto-renewal fails(e.g. due to the sovereign account of the task not holding sufficient balance), an event will be emitted, and the renewal will continue for the other cores. The two added extrinsics are: - `enable_auto_renew`: Extrinsic for enabling auto renewal. - `disable_auto_renew`: Extrinsic for disabling auto renewal. TODOs: - [x] Write benchmarks for the newly added extrinsics. Closes: #4351 --------- Co-authored-by: Dónal Murray --- .../coretime/coretime-rococo/src/coretime.rs | 21 +- .../src/weights/pallet_broker.rs | 38 ++ .../coretime/coretime-westend/src/coretime.rs | 19 +- .../src/weights/pallet_broker.rs | 38 ++ prdoc/pr_4424.prdoc | 20 + substrate/bin/node/runtime/src/lib.rs | 16 +- substrate/frame/broker/src/benchmarking.rs | 151 +++++- .../frame/broker/src/dispatchable_impls.rs | 69 ++- substrate/frame/broker/src/lib.rs | 109 ++++- substrate/frame/broker/src/mock.rs | 18 +- substrate/frame/broker/src/tests.rs | 288 ++++++++++++ substrate/frame/broker/src/tick_impls.rs | 51 ++- substrate/frame/broker/src/types.rs | 13 + substrate/frame/broker/src/utility_impls.rs | 2 +- substrate/frame/broker/src/weights.rs | 432 ++++++++++-------- 15 files changed, 1078 insertions(+), 207 deletions(-) create mode 100644 prdoc/pr_4424.prdoc diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs index fa0c2644421e..76ee06a87e8d 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/coretime.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use crate::*; +use crate::{xcm_config::LocationToAccountId, *}; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelaychainDataProvider; use cumulus_primitives_core::relay_chain; @@ -27,12 +27,14 @@ use frame_support::{ }, }; use frame_system::Pallet as System; -use pallet_broker::{CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf}; +use pallet_broker::{ + CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, TaskId, +}; use parachains_common::{AccountId, Balance}; use rococo_runtime_constants::system_parachain::coretime; -use sp_runtime::traits::AccountIdConversion; +use sp_runtime::traits::{AccountIdConversion, MaybeConvert}; use xcm::latest::prelude::*; -use xcm_executor::traits::TransactAsset; +use xcm_executor::traits::{ConvertLocation, TransactAsset}; pub struct BurnCoretimeRevenue; impl OnUnbalanced> for BurnCoretimeRevenue { @@ -263,6 +265,15 @@ impl CoretimeInterface for CoretimeAllocator { } } +pub struct SovereignAccountOf; +impl MaybeConvert for SovereignAccountOf { + fn maybe_convert(id: TaskId) -> Option { + // Currently all tasks are parachains. + let location = Location::new(1, [Parachain(id)]); + LocationToAccountId::convert_location(&location) + } +} + impl pallet_broker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -275,5 +286,7 @@ impl pallet_broker::Config for Runtime { type WeightInfo = weights::pallet_broker::WeightInfo; type PalletId = BrokerPalletId; type AdminOrigin = EnsureRoot; + type SovereignAccountOf = SovereignAccountOf; + type MaxAutoRenewals = ConstU32<100>; type PriceAdapter = pallet_broker::CenterTargetPrice; } diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs index 83e80e2e91e7..35708f22de20 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_broker.rs @@ -549,6 +549,44 @@ impl pallet_broker::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:1 w:2) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn enable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `914` + // Estimated: `4698` + // Minimum execution time: 51_938_000 picoseconds. + Weight::from_parts(55_025_000, 4698) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + } + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + fn disable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `480` + // Estimated: `1516` + // Minimum execution time: 9_628_000 picoseconds. + Weight::from_parts(10_400_000, 1516) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0) diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs index 4f06e3e3669c..865ff68d4c65 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/coretime.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -use crate::*; +use crate::{xcm_config::LocationToAccountId, *}; use codec::{Decode, Encode}; use cumulus_pallet_parachain_system::RelaychainDataProvider; use cumulus_primitives_core::relay_chain; @@ -28,13 +28,13 @@ use frame_support::{ }; use frame_system::Pallet as System; use pallet_broker::{ - CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, Timeslice, + CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, TaskId, Timeslice, }; use parachains_common::{AccountId, Balance}; -use sp_runtime::traits::AccountIdConversion; +use sp_runtime::traits::{AccountIdConversion, MaybeConvert}; use westend_runtime_constants::system_parachain::coretime; use xcm::latest::prelude::*; -use xcm_executor::traits::TransactAsset; +use xcm_executor::traits::{ConvertLocation, TransactAsset}; pub struct BurnCoretimeRevenue; impl OnUnbalanced> for BurnCoretimeRevenue { @@ -277,6 +277,15 @@ impl CoretimeInterface for CoretimeAllocator { } } +pub struct SovereignAccountOf; +impl MaybeConvert for SovereignAccountOf { + fn maybe_convert(id: TaskId) -> Option { + // Currently all tasks are parachains. + let location = Location::new(1, [Parachain(id)]); + LocationToAccountId::convert_location(&location) + } +} + impl pallet_broker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -290,5 +299,7 @@ impl pallet_broker::Config for Runtime { type WeightInfo = weights::pallet_broker::WeightInfo; type PalletId = BrokerPalletId; type AdminOrigin = EnsureRoot; + type SovereignAccountOf = SovereignAccountOf; + type MaxAutoRenewals = ConstU32<20>; type PriceAdapter = pallet_broker::CenterTargetPrice; } diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs index d130b306f7a5..74b1c4e47029 100644 --- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs +++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_broker.rs @@ -549,6 +549,44 @@ impl pallet_broker::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:1 w:2) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn enable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `914` + // Estimated: `4698` + // Minimum execution time: 51_938_000 picoseconds. + Weight::from_parts(55_025_000, 4698) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + } + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + fn disable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `480` + // Estimated: `1516` + // Minimum execution time: 9_628_000 picoseconds. + Weight::from_parts(10_400_000, 1516) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } /// Storage: `System::Account` (r:1 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn on_new_timeslice() -> Weight { diff --git a/prdoc/pr_4424.prdoc b/prdoc/pr_4424.prdoc new file mode 100644 index 000000000000..7131ebfca274 --- /dev/null +++ b/prdoc/pr_4424.prdoc @@ -0,0 +1,20 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: Coretime auto renewal + +doc: + - audience: Runtime User + description: | + With the additions in this PR, any task that utilizes a core that can be auto-renewed + can enable auto-renewal. The renewal is paid from the task's sovereign account. + The two new extrinsics for controlling auto-renewal are `enable_auto_renew` and + `disable_auto_renew`. + +crates: + - name: pallet-broker + bump: major + - name: coretime-rococo-runtime + bump: minor + - name: coretime-westend-runtime + bump: minor diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index fd8597563a02..a94838cf20c0 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -79,6 +79,7 @@ use pallet_nis::WithMaximumOf; use pallet_session::historical as pallet_session_historical; // Can't use `FungibleAdapter` here until Treasury pallet migrates to fungibles // +use pallet_broker::TaskId; #[allow(deprecated)] pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment}; use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; @@ -97,8 +98,8 @@ use sp_runtime::{ curve::PiecewiseLinear, generic, impl_opaque_keys, traits::{ - self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, NumberFor, - OpaqueKeys, SaturatedConversion, StaticLookup, + self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, + MaybeConvert, NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perbill, Percent, Permill, Perquintill, @@ -2115,6 +2116,15 @@ impl CoretimeInterface for CoretimeProvider { } } +pub struct SovereignAccountOf; +// Dummy implementation which converts `TaskId` to `AccountId`. +impl MaybeConvert for SovereignAccountOf { + fn maybe_convert(task: TaskId) -> Option { + let mut account: [u8; 32] = [0; 32]; + account[..4].copy_from_slice(&task.to_le_bytes()); + Some(account.into()) + } +} impl pallet_broker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -2127,6 +2137,8 @@ impl pallet_broker::Config for Runtime { type WeightInfo = (); type PalletId = BrokerPalletId; type AdminOrigin = EnsureRoot; + type SovereignAccountOf = SovereignAccountOf; + type MaxAutoRenewals = ConstU32<10>; type PriceAdapter = pallet_broker::CenterTargetPrice; } diff --git a/substrate/frame/broker/src/benchmarking.rs b/substrate/frame/broker/src/benchmarking.rs index 33df56c95f65..595bf564f7e1 100644 --- a/substrate/frame/broker/src/benchmarking.rs +++ b/substrate/frame/broker/src/benchmarking.rs @@ -32,7 +32,10 @@ use frame_support::{ use frame_system::{Pallet as System, RawOrigin}; use sp_arithmetic::{traits::Zero, Perbill}; use sp_core::Get; -use sp_runtime::{traits::BlockNumberProvider, Saturating}; +use sp_runtime::{ + traits::{BlockNumberProvider, MaybeConvert}, + SaturatedConversion, Saturating, +}; const SEED: u32 = 0; const MAX_CORE_COUNT: u16 = 1_000; @@ -41,6 +44,10 @@ fn assert_last_event(generic_event: ::RuntimeEvent) { frame_system::Pallet::::assert_last_event(generic_event.into()); } +fn assert_has_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_has_event(generic_event.into()); +} + fn new_config_record() -> ConfigRecordOf { ConfigRecord { advance_notice: 2u32.into(), @@ -776,7 +783,7 @@ mod benches { } #[benchmark] - fn rotate_sale(n: Linear<0, { MAX_CORE_COUNT.into() }>) { + fn rotate_sale(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { let core_count = n.try_into().unwrap(); let config = new_config_record::(); @@ -810,6 +817,27 @@ mod benches { // Assume Leases to be filled for worst case setup_leases::(T::MaxLeasedCores::get(), 1, 10); + // Assume max auto renewals for worst case. + (0..T::MaxAutoRenewals::get()).try_for_each(|indx| -> Result<(), BenchmarkError> { + let task = 1000 + indx; + let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) + .expect("Failed to get sovereign account"); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(100u32.into()), + ); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_assign(region, None, task, Final) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_enable_auto_renew(caller, region.core, task, None)?; + + Ok(()) + })?; + #[block] { Broker::::rotate_sale(sale.clone(), &config, &status); @@ -833,6 +861,30 @@ mod benches { } .into(), ); + + // Make sure all cores got renewed: + (0..T::MaxAutoRenewals::get()).for_each(|indx| { + let task = 1000 + indx; + let who = T::SovereignAccountOf::maybe_convert(task) + .expect("Failed to get sovereign account"); + assert_has_event::( + Event::Renewed { + who, + old_core: 10 + indx as u16, // first ten cores are allocated to leases. + core: 10 + indx as u16, + price: 10u32.saturated_into(), + begin: 7, + duration: 3, + workload: Schedule::truncate_from(vec![ScheduleItem { + assignment: Task(task), + mask: CoreMask::complete(), + }]), + } + .into(), + ); + }); + + Ok(()) } #[benchmark] @@ -960,6 +1012,101 @@ mod benches { Ok(()) } + #[benchmark] + fn enable_auto_renew() -> Result<(), BenchmarkError> { + let _core = setup_and_start_sale::()?; + + advance_to::(2); + + // We assume max auto renewals for worst case. + (0..T::MaxAutoRenewals::get() - 1).try_for_each(|indx| -> Result<(), BenchmarkError> { + let task = 1000 + indx; + let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) + .expect("Failed to get sovereign account"); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(100u32.into()), + ); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_assign(region, None, task, Final) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_enable_auto_renew(caller, region.core, task, Some(7))?; + + Ok(()) + })?; + + let caller: T::AccountId = + T::SovereignAccountOf::maybe_convert(2001).expect("Failed to get sovereign account"); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(100u32.into()), + ); + + // The region for which we benchmark enable auto renew. + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_assign(region, None, 2001, Final) + .map_err(|_| BenchmarkError::Weightless)?; + + // The most 'intensive' path is when we renew the core upon enabling auto-renewal. + // Therefore, we advance to next bulk sale: + advance_to::(6); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region.core, 2001, None); + + assert_last_event::(Event::AutoRenewalEnabled { core: region.core, task: 2001 }.into()); + // Make sure we indeed renewed: + assert!(PotentialRenewals::::get(PotentialRenewalId { + core: region.core, + when: 10 // region end after renewal + }) + .is_some()); + + Ok(()) + } + + #[benchmark] + fn disable_auto_renew() -> Result<(), BenchmarkError> { + let _core = setup_and_start_sale::()?; + + advance_to::(2); + + // We assume max auto renewals for worst case. + (0..T::MaxAutoRenewals::get() - 1).try_for_each(|indx| -> Result<(), BenchmarkError> { + let task = 1000 + indx; + let caller: T::AccountId = T::SovereignAccountOf::maybe_convert(task) + .expect("Failed to get sovereign account"); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(100u32.into()), + ); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_assign(region, None, task, Final) + .map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_enable_auto_renew(caller, region.core, task, Some(7))?; + + Ok(()) + })?; + + let caller: T::AccountId = + T::SovereignAccountOf::maybe_convert(1000).expect("Failed to get sovereign account"); + #[extrinsic_call] + _(RawOrigin::Signed(caller), _core, 1000); + + assert_last_event::(Event::AutoRenewalDisabled { core: _core, task: 1000 }.into()); + + Ok(()) + } + #[benchmark] fn on_new_timeslice() -> Result<(), BenchmarkError> { setup_and_start_sale::()?; diff --git a/substrate/frame/broker/src/dispatchable_impls.rs b/substrate/frame/broker/src/dispatchable_impls.rs index a8ded084a801..5fbd957d7908 100644 --- a/substrate/frame/broker/src/dispatchable_impls.rs +++ b/substrate/frame/broker/src/dispatchable_impls.rs @@ -16,9 +16,8 @@ // limitations under the License. use super::*; -use coretime_interface::CoretimeInterface; use frame_support::{ - pallet_prelude::{DispatchResult, *}, + pallet_prelude::*, traits::{fungible::Mutate, tokens::Preservation::Expendable, DefensiveResult}, }; use sp_arithmetic::traits::{CheckedDiv, Saturating, Zero}; @@ -487,6 +486,72 @@ impl Pallet { Ok(()) } + pub(crate) fn do_enable_auto_renew( + sovereign_account: T::AccountId, + core: CoreIndex, + task: TaskId, + workload_end_hint: Option, + ) -> DispatchResult { + let sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + + // Check if the core is expiring in the next bulk period; if so, we will renew it now. + // + // In case we renew it now, we don't need to check the workload end since we know it is + // eligible for renewal. + if PotentialRenewals::::get(PotentialRenewalId { core, when: sale.region_begin }) + .is_some() + { + Self::do_renew(sovereign_account.clone(), core)?; + } else if let Some(workload_end) = workload_end_hint { + ensure!( + PotentialRenewals::::get(PotentialRenewalId { core, when: workload_end }) + .is_some(), + Error::::NotAllowed + ); + } else { + return Err(Error::::NotAllowed.into()) + } + + // We are sorting auto renewals by `CoreIndex`. + AutoRenewals::::try_mutate(|renewals| { + let pos = renewals + .binary_search_by(|r: &AutoRenewalRecord| r.core.cmp(&core)) + .unwrap_or_else(|e| e); + renewals.try_insert( + pos, + AutoRenewalRecord { + core, + task, + next_renewal: workload_end_hint.unwrap_or(sale.region_end), + }, + ) + }) + .map_err(|_| Error::::TooManyAutoRenewals)?; + + Self::deposit_event(Event::AutoRenewalEnabled { core, task }); + Ok(()) + } + + pub(crate) fn do_disable_auto_renew(core: CoreIndex, task: TaskId) -> DispatchResult { + AutoRenewals::::try_mutate(|renewals| -> DispatchResult { + let pos = renewals + .binary_search_by(|r: &AutoRenewalRecord| r.core.cmp(&core)) + .map_err(|_| Error::::AutoRenewalNotEnabled)?; + + let renewal_record = renewals.get(pos).ok_or(Error::::AutoRenewalNotEnabled)?; + + ensure!( + renewal_record.core == core && renewal_record.task == task, + Error::::NoPermission + ); + renewals.remove(pos); + Ok(()) + })?; + + Self::deposit_event(Event::AutoRenewalDisabled { core, task }); + Ok(()) + } + pub(crate) fn ensure_cores_for_sale( status: &StatusRecord, sale: &SaleInfoRecordOf, diff --git a/substrate/frame/broker/src/lib.rs b/substrate/frame/broker/src/lib.rs index 45c33c1bfa61..10745544fadf 100644 --- a/substrate/frame/broker/src/lib.rs +++ b/substrate/frame/broker/src/lib.rs @@ -65,7 +65,7 @@ pub mod pallet { PalletId, }; use frame_system::pallet_prelude::*; - use sp_runtime::traits::{Convert, ConvertBack}; + use sp_runtime::traits::{Convert, ConvertBack, MaybeConvert}; const STORAGE_VERSION: StorageVersion = StorageVersion::new(3); @@ -101,6 +101,10 @@ pub mod pallet { type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; + /// Type used for getting the associated account of a task. This account is controlled by + /// the task itself. + type SovereignAccountOf: MaybeConvert; + /// Identifier from which the internal Pot is generated. #[pallet::constant] type PalletId: Get; @@ -116,6 +120,9 @@ pub mod pallet { /// Maximum number of system cores. #[pallet::constant] type MaxReservedCores: Get; + + #[pallet::constant] + type MaxAutoRenewals: Get; } /// The current configuration of this pallet. @@ -176,6 +183,13 @@ pub mod pallet { #[pallet::storage] pub type CoreCountInbox = StorageValue<_, CoreIndex, OptionQuery>; + /// Keeping track of cores which have auto-renewal enabled. + /// + /// Sorted by `CoreIndex` to make the removal of cores from auto-renewal more efficient. + #[pallet::storage] + pub type AutoRenewals = + StorageValue<_, BoundedVec, ValueQuery>; + /// Received revenue info from the relay chain. #[pallet::storage] pub type RevenueInbox = StorageValue<_, OnDemandRevenueRecordOf, OptionQuery>; @@ -426,6 +440,33 @@ pub mod pallet { /// The core whose workload is no longer available to be renewed for `when`. core: CoreIndex, }, + AutoRenewalEnabled { + /// The core for which the renewal was enabled. + core: CoreIndex, + /// The task for which the renewal was enabled. + task: TaskId, + }, + AutoRenewalDisabled { + /// The core for which the renewal was disabled. + core: CoreIndex, + /// The task for which the renewal was disabled. + task: TaskId, + }, + /// Failed to auto-renew a core, likely due to the payer account not being sufficiently + /// funded. + AutoRenewalFailed { + /// The core for which the renewal failed. + core: CoreIndex, + /// The account which was supposed to pay for renewal. + /// + /// If `None` it indicates that we failed to get the sovereign account of a task. + payer: Option, + }, + /// The auto-renewal limit has been reached upon renewing cores. + /// + /// This should never happen, given that enable_auto_renew checks for this before enabling + /// auto-renewal. + AutoRenewalLimitReached, } #[pallet::error] @@ -492,6 +533,16 @@ pub mod pallet { InvalidConfig, /// The revenue must be claimed for 1 or more timeslices. NoClaimTimeslices, + /// The caller doesn't have the permission to enable or disable auto-renewal. + NoPermission, + /// We reached the limit for auto-renewals. + TooManyAutoRenewals, + /// Only cores which are assigned to a task can be auto-renewed. + NonTaskAutoRenewal, + /// Failed to get the sovereign account of a task. + SovereignAccountNotFound, + /// Attempted to disable auto-renewal for a core that didn't have it enabled. + AutoRenewalNotEnabled, } #[derive(frame_support::DefaultNoBound)] @@ -835,6 +886,62 @@ pub mod pallet { Ok(()) } + /// Extrinsic for enabling auto renewal. + /// + /// Callable by the sovereign account of the task on the specified core. This account + /// will be charged at the start of every bulk period for renewing core time. + /// + /// - `origin`: Must be the sovereign account of the task + /// - `core`: The core to which the task to be renewed is currently assigned. + /// - `task`: The task for which we want to enable auto renewal. + /// - `workload_end_hint`: should be used when enabling auto-renewal for a core that is not + /// expiring in the upcoming bulk period (e.g., due to holding a lease) since it would be + /// inefficient to look up when the core expires to schedule the next renewal. + #[pallet::call_index(21)] + #[pallet::weight(T::WeightInfo::enable_auto_renew())] + pub fn enable_auto_renew( + origin: OriginFor, + core: CoreIndex, + task: TaskId, + workload_end_hint: Option, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + let sovereign_account = T::SovereignAccountOf::maybe_convert(task) + .ok_or(Error::::SovereignAccountNotFound)?; + // Only the sovereign account of a task can enable auto renewal for its own core. + ensure!(who == sovereign_account, Error::::NoPermission); + + Self::do_enable_auto_renew(sovereign_account, core, task, workload_end_hint)?; + Ok(()) + } + + /// Extrinsic for disabling auto renewal. + /// + /// Callable by the sovereign account of the task on the specified core. + /// + /// - `origin`: Must be the sovereign account of the task. + /// - `core`: The core for which we want to disable auto renewal. + /// - `task`: The task for which we want to disable auto renewal. + #[pallet::call_index(22)] + #[pallet::weight(T::WeightInfo::disable_auto_renew())] + pub fn disable_auto_renew( + origin: OriginFor, + core: CoreIndex, + task: TaskId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + + let sovereign_account = T::SovereignAccountOf::maybe_convert(task) + .ok_or(Error::::SovereignAccountNotFound)?; + // Only the sovereign account of the task can disable auto-renewal. + ensure!(who == sovereign_account, Error::::NoPermission); + + Self::do_disable_auto_renew(core, task)?; + + Ok(()) + } + #[pallet::call_index(99)] #[pallet::weight(T::WeightInfo::swap_leases())] pub fn swap_leases(origin: OriginFor, id: TaskId, other: TaskId) -> DispatchResult { diff --git a/substrate/frame/broker/src/mock.rs b/substrate/frame/broker/src/mock.rs index 6b1d2bbf7015..42377eefdb22 100644 --- a/substrate/frame/broker/src/mock.rs +++ b/substrate/frame/broker/src/mock.rs @@ -32,7 +32,7 @@ use frame_system::{EnsureRoot, EnsureSignedBy}; use sp_arithmetic::Perbill; use sp_core::{ConstU32, ConstU64, Get}; use sp_runtime::{ - traits::{BlockNumberProvider, Identity}, + traits::{BlockNumberProvider, Identity, MaybeConvert}, BuildStorage, Saturating, }; @@ -180,6 +180,14 @@ ord_parameter_types! { } type EnsureOneOrRoot = EitherOfDiverse, EnsureSignedBy>; +// Dummy implementation which converts `TaskId` to `AccountId`. +pub struct SovereignAccountOf; +impl MaybeConvert for SovereignAccountOf { + fn maybe_convert(task: TaskId) -> Option { + Some(task.into()) + } +} + impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; @@ -192,6 +200,8 @@ impl crate::Config for Test { type WeightInfo = (); type PalletId = TestBrokerId; type AdminOrigin = EnsureOneOrRoot; + type SovereignAccountOf = SovereignAccountOf; + type MaxAutoRenewals = ConstU32<3>; type PriceAdapter = CenterTargetPrice>; } @@ -246,6 +256,10 @@ pub fn new_config() -> ConfigRecordOf { } } +pub fn endow(who: u64, amount: u64) { + assert_ok!(<::Currency as Mutate<_>>::mint_into(&who, amount)); +} + pub struct TestExt(ConfigRecordOf); #[allow(dead_code)] impl TestExt { @@ -298,7 +312,7 @@ impl TestExt { } pub fn endow(self, who: u64, amount: u64) -> Self { - assert_ok!(<::Currency as Mutate<_>>::mint_into(&who, amount)); + endow(who, amount); self } diff --git a/substrate/frame/broker/src/tests.rs b/substrate/frame/broker/src/tests.rs index 3ea68c5a74d6..f3fd5234e4ca 100644 --- a/substrate/frame/broker/src/tests.rs +++ b/substrate/frame/broker/src/tests.rs @@ -1530,6 +1530,294 @@ fn renewal_works_leases_ended_before_start_sales() { }); } +#[test] +fn enable_auto_renew_works() { + TestExt::new().endow(1, 1000).limit_cores_offered(Some(10)).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 5)); + advance_to(2); + let region_id = Broker::do_purchase(1, u64::max_value()).unwrap(); + let record = Regions::::get(region_id).unwrap(); + + // Cannot enable auto renewal with provisional finality: + assert_ok!(Broker::do_assign(region_id, Some(1), 1001, Provisional)); + assert_noop!( + Broker::do_enable_auto_renew(1001, region_id.core, 1001, Some(7)), + Error::::NotAllowed + ); + + // Eligible for renewal after final assignment: + assert_ok!(Broker::do_assign(region_id, Some(1), 1001, Final)); + assert!(PotentialRenewals::::get(PotentialRenewalId { + core: region_id.core, + when: record.end + }) + .is_some()); + + // Only the task's sovereign account can enable auto renewal. + assert_noop!( + Broker::enable_auto_renew(RuntimeOrigin::signed(1), region_id.core, 1001, Some(7)), + Error::::NoPermission + ); + + // Works when calling with the sovereign account: + assert_ok!(Broker::do_enable_auto_renew(1001, region_id.core, 1001, Some(7))); + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![AutoRenewalRecord { core: 0, task: 1001, next_renewal: 7 }] + ); + System::assert_has_event( + Event::::AutoRenewalEnabled { core: region_id.core, task: 1001 }.into(), + ); + + // Enabling auto-renewal for more cores to ensure they are sorted based on core index. + let region_2 = Broker::do_purchase(1, u64::max_value()).unwrap(); + let region_3 = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region_2, Some(1), 1002, Final)); + assert_ok!(Broker::do_assign(region_3, Some(1), 1003, Final)); + assert_ok!(Broker::do_enable_auto_renew(1003, region_3.core, 1003, Some(7))); + assert_ok!(Broker::do_enable_auto_renew(1002, region_2.core, 1002, Some(7))); + + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![ + AutoRenewalRecord { core: 0, task: 1001, next_renewal: 7 }, + AutoRenewalRecord { core: 1, task: 1002, next_renewal: 7 }, + AutoRenewalRecord { core: 2, task: 1003, next_renewal: 7 }, + ] + ); + + // Ensure that we cannot enable more auto renewals than `MaxAutoRenewals`. + // We already enabled it for three cores, and the limit is set to 3. + let region_4 = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region_4, Some(1), 1004, Final)); + + assert_noop!( + Broker::do_enable_auto_renew(1004, region_4.core, 1004, Some(7)), + Error::::TooManyAutoRenewals + ); + }); +} + +#[test] +fn enable_auto_renewal_works_for_legacy_leases() { + TestExt::new().endow(1, 1000).execute_with(|| { + // With this test, we ensure that we don't renew unnecessarily if the task has Coretime + // reserved (due to having a lease) + + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + + let record = PotentialRenewalRecord { + price: 100, + completion: CompletionStatus::Complete( + vec![ScheduleItem { mask: CoreMask::complete(), assignment: Task(1001) }] + .try_into() + .unwrap(), + ), + }; + // For lease holding tasks, the renewal record is set for when the lease expires, which is + // likely further in the future than the start of the next sale. + PotentialRenewals::::insert(PotentialRenewalId { core: 0, when: 10 }, &record); + + endow(1001, 1000); + + // Will fail if we don't provide the end hint since it expects renewal record to be at next + // sale start. + assert_noop!(Broker::do_enable_auto_renew(1001, 0, 1001, None), Error::::NotAllowed); + + assert_ok!(Broker::do_enable_auto_renew(1001, 0, 1001, Some(10))); + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![AutoRenewalRecord { core: 0, task: 1001, next_renewal: 10 },] + ); + System::assert_has_event(Event::::AutoRenewalEnabled { core: 0, task: 1001 }.into()); + + // Next cycle starting at 7. + advance_to(7); + + // Ensure that the renewal didn't happen by checking that the balance remained the same, as + // there is still no need to renew. + assert_eq!(balance(1001), 1000); + + // The next sale starts at 13. The renewal should happen now and the account should be + // charged. + advance_to(13); + assert_eq!(balance(1001), 900); + + // Make sure that the renewal happened: + System::assert_has_event( + Event::::Renewed { + who: 1001, // sovereign account + old_core: 0, + core: 0, + price: 100, + begin: 10, + duration: 3, + workload: Schedule::truncate_from(vec![ScheduleItem { + assignment: Task(1001), + mask: CoreMask::complete(), + }]), + } + .into(), + ); + }); +} + +#[test] +fn enable_auto_renew_renews() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region_id = Broker::do_purchase(1, u64::max_value()).unwrap(); + + assert_ok!(Broker::do_assign(region_id, Some(1), 1001, Final)); + // advance to next bulk sale: + advance_to(6); + + // Since we didn't renew for the next bulk period, enabling auto-renewal will renew, + // ensuring the task continues execution. + + // Will fail because we didn't fund the sovereign account: + assert_noop!( + Broker::do_enable_auto_renew(1001, region_id.core, 1001, None), + TokenError::FundsUnavailable + ); + + // Will succeed after funding the sovereign account: + endow(1001, 1000); + + assert_ok!(Broker::do_enable_auto_renew(1001, region_id.core, 1001, None)); + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![AutoRenewalRecord { core: 0, task: 1001, next_renewal: 10 }] + ); + assert!(PotentialRenewals::::get(PotentialRenewalId { + core: region_id.core, + when: 10 + }) + .is_some()); + + System::assert_has_event( + Event::::AutoRenewalEnabled { core: region_id.core, task: 1001 }.into(), + ); + }); +} + +#[test] +fn auto_renewal_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 3)); + advance_to(2); + let region_1 = Broker::do_purchase(1, u64::max_value()).unwrap(); + let region_2 = Broker::do_purchase(1, u64::max_value()).unwrap(); + let region_3 = Broker::do_purchase(1, u64::max_value()).unwrap(); + + // Eligible for renewal after final assignment: + assert_ok!(Broker::do_assign(region_1, Some(1), 1001, Final)); + assert_ok!(Broker::do_assign(region_2, Some(1), 1002, Final)); + assert_ok!(Broker::do_assign(region_3, Some(1), 1003, Final)); + assert_ok!(Broker::do_enable_auto_renew(1001, region_1.core, 1001, Some(7))); + assert_ok!(Broker::do_enable_auto_renew(1002, region_2.core, 1002, Some(7))); + assert_ok!(Broker::do_enable_auto_renew(1003, region_3.core, 1003, Some(7))); + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![ + AutoRenewalRecord { core: 0, task: 1001, next_renewal: 7 }, + AutoRenewalRecord { core: 1, task: 1002, next_renewal: 7 }, + AutoRenewalRecord { core: 2, task: 1003, next_renewal: 7 }, + ] + ); + + // We have to fund the sovereign account: + endow(1001, 1000); + // We skip funding the sovereign account of task 1002 on purpose. + endow(1003, 1000); + + // Next cycle starting at 7. + advance_to(7); + System::assert_has_event( + Event::::Renewed { + who: 1001, // sovereign account + old_core: 0, + core: 0, + price: 100, + begin: 7, + duration: 3, + workload: Schedule::truncate_from(vec![ScheduleItem { + assignment: Task(1001), + mask: CoreMask::complete(), + }]), + } + .into(), + ); + // Sovereign account wasn't funded so it fails: + System::assert_has_event( + Event::::AutoRenewalFailed { core: 1, payer: Some(1002) }.into(), + ); + System::assert_has_event( + Event::::Renewed { + who: 1003, // sovereign account + old_core: 2, + core: 1, // Core #1 didn't get renewed, so core #2 will take its place. + price: 100, + begin: 7, + duration: 3, + workload: Schedule::truncate_from(vec![ScheduleItem { + assignment: Task(1003), + mask: CoreMask::complete(), + }]), + } + .into(), + ); + + // Given that core #1 didn't get renewed due to the account not being sufficiently funded, + // Task (1003) will now be assigned to that core instead of core #2. + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![ + AutoRenewalRecord { core: 0, task: 1001, next_renewal: 10 }, + AutoRenewalRecord { core: 1, task: 1003, next_renewal: 10 }, + ] + ); + }); +} + +#[test] +fn disable_auto_renew_works() { + TestExt::new().endow(1, 1000).limit_cores_offered(Some(10)).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 3)); + advance_to(2); + let region_id = Broker::do_purchase(1, u64::max_value()).unwrap(); + + // Eligible for renewal after final assignment: + assert_ok!(Broker::do_assign(region_id, Some(1), 1001, Final)); + + // Cannot disable auto-renewal if we don't have it enabled. + assert_noop!( + Broker::do_disable_auto_renew(region_id.core, 1001), + Error::::AutoRenewalNotEnabled + ); + + assert_ok!(Broker::do_enable_auto_renew(1001, region_id.core, 1001, Some(7))); + assert_eq!( + AutoRenewals::::get().to_vec(), + vec![AutoRenewalRecord { core: 0, task: 1001, next_renewal: 7 }] + ); + + // Only the sovereign account can disable: + assert_noop!( + Broker::disable_auto_renew(RuntimeOrigin::signed(1), 0, 1001), + Error::::NoPermission + ); + assert_ok!(Broker::do_disable_auto_renew(0, 1001)); + + assert_eq!(AutoRenewals::::get().to_vec(), vec![]); + System::assert_has_event( + Event::::AutoRenewalDisabled { core: region_id.core, task: 1001 }.into(), + ); + }); +} + #[test] fn start_sales_sets_correct_core_count() { TestExt::new().endow(1, 1000).execute_with(|| { diff --git a/substrate/frame/broker/src/tick_impls.rs b/substrate/frame/broker/src/tick_impls.rs index 71a1286d7391..8dbd5df57166 100644 --- a/substrate/frame/broker/src/tick_impls.rs +++ b/substrate/frame/broker/src/tick_impls.rs @@ -19,7 +19,7 @@ use super::*; use alloc::{vec, vec::Vec}; use frame_support::{pallet_prelude::*, traits::defensive_prelude::*, weights::WeightMeter}; use sp_arithmetic::traits::{One, SaturatedConversion, Saturating, Zero}; -use sp_runtime::traits::ConvertBack; +use sp_runtime::traits::{ConvertBack, MaybeConvert}; use CompletionStatus::Complete; impl Pallet { @@ -263,6 +263,9 @@ impl Pallet { }; SaleInfo::::put(&new_sale); + + Self::renew_cores(&new_sale); + Self::deposit_event(Event::SaleInitialized { sale_start, leadin_length, @@ -334,4 +337,50 @@ impl Pallet { T::Coretime::assign_core(core, rc_begin, assignment.clone(), None); Self::deposit_event(Event::::CoreAssigned { core, when: rc_begin, assignment }); } + + /// Renews all the cores which have auto-renewal enabled. + pub(crate) fn renew_cores(sale: &SaleInfoRecordOf) { + let renewals = AutoRenewals::::get(); + + let Ok(auto_renewals) = renewals + .into_iter() + .flat_map(|record| { + // Check if the next renewal is scheduled further in the future than the start of + // the next region beginning. If so, we skip the renewal for this core. + if sale.region_begin < record.next_renewal { + return Some(record) + } + + let Some(payer) = T::SovereignAccountOf::maybe_convert(record.task) else { + Self::deposit_event(Event::::AutoRenewalFailed { + core: record.core, + payer: None, + }); + return None + }; + + if let Ok(new_core_index) = Self::do_renew(payer.clone(), record.core) { + Some(AutoRenewalRecord { + core: new_core_index, + task: record.task, + next_renewal: sale.region_end, + }) + } else { + Self::deposit_event(Event::::AutoRenewalFailed { + core: record.core, + payer: Some(payer), + }); + + None + } + }) + .collect::>() + .try_into() + else { + Self::deposit_event(Event::::AutoRenewalLimitReached); + return; + }; + + AutoRenewals::::set(auto_renewals); + } } diff --git a/substrate/frame/broker/src/types.rs b/substrate/frame/broker/src/types.rs index dcfa9a77e4f3..10e6756bc90e 100644 --- a/substrate/frame/broker/src/types.rs +++ b/substrate/frame/broker/src/types.rs @@ -311,3 +311,16 @@ where Ok(()) } } + +/// A record containing information regarding auto-renewal for a specific core. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct AutoRenewalRecord { + /// The core for which auto renewal is enabled. + pub core: CoreIndex, + /// The task assigned to the core. We keep track of it so we don't have to look it up when + /// performing auto-renewal. + pub task: TaskId, + /// Specifies when the upcoming renewal should be performed. This is used for lease holding + /// tasks to ensure that the renewal process does not begin until the lease expires. + pub next_renewal: Timeslice, +} diff --git a/substrate/frame/broker/src/utility_impls.rs b/substrate/frame/broker/src/utility_impls.rs index 5c66ebb9674b..e937e0cbbec5 100644 --- a/substrate/frame/broker/src/utility_impls.rs +++ b/substrate/frame/broker/src/utility_impls.rs @@ -17,7 +17,7 @@ use super::*; use frame_support::{ - pallet_prelude::{DispatchResult, *}, + pallet_prelude::*, traits::{ fungible::Balanced, tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, diff --git a/substrate/frame/broker/src/weights.rs b/substrate/frame/broker/src/weights.rs index 4889c2577ddd..2f25fddc2050 100644 --- a/substrate/frame/broker/src/weights.rs +++ b/substrate/frame/broker/src/weights.rs @@ -18,25 +18,27 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-06-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-05-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-x5tnzzy-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `sergej-B650-AORUS-ELITE-AX`, CPU: `AMD Ryzen 9 7900X3D 12-Core Processor` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/release/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_broker +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_broker -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/broker/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -79,6 +81,8 @@ pub trait WeightInfo { fn do_tick_base() -> Weight; fn swap_leases() -> Weight; fn on_new_timeslice() -> Weight; + fn enable_auto_renew() -> Weight; + fn disable_auto_renew() -> Weight; } /// Weights for `pallet_broker` using the Substrate node and recommended hardware. @@ -90,8 +94,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_977_000 picoseconds. - Weight::from_parts(2_114_000, 0) + // Minimum execution time: 1_593_000 picoseconds. + Weight::from_parts(1_703_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -100,8 +104,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 16_880_000 picoseconds. - Weight::from_parts(17_506_000, 7496) + // Minimum execution time: 12_864_000 picoseconds. + Weight::from_parts(13_174_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -111,8 +115,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 15_569_000 picoseconds. - Weight::from_parts(16_123_000, 7496) + // Minimum execution time: 12_284_000 picoseconds. + Weight::from_parts(13_566_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -122,8 +126,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 8_962_000 picoseconds. - Weight::from_parts(9_389_000, 1526) + // Minimum execution time: 6_743_000 picoseconds. + Weight::from_parts(7_094_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -135,6 +139,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:0 w:1) @@ -146,12 +152,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 27_119_000 picoseconds. - Weight::from_parts(47_930_900, 8499) - // Standard Error: 464 - .saturating_add(Weight::from_parts(2_940, 0).saturating_mul(n.into())) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(15_u64)) + // Minimum execution time: 21_120_000 picoseconds. + Weight::from_parts(40_929_422, 8499) + // Standard Error: 471 + .saturating_add(Weight::from_parts(1_004, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(7_u64)) + .saturating_add(T::DbWeight::get().writes(16_u64)) } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) @@ -167,8 +173,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `651` // Estimated: `2136` - // Minimum execution time: 42_429_000 picoseconds. - Weight::from_parts(43_538_000, 2136) + // Minimum execution time: 31_169_000 picoseconds. + Weight::from_parts(32_271_000, 2136) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -190,8 +196,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `769` // Estimated: `4698` - // Minimum execution time: 62_957_000 picoseconds. - Weight::from_parts(66_821_000, 4698) + // Minimum execution time: 44_945_000 picoseconds. + Weight::from_parts(47_119_000, 4698) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -201,8 +207,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 16_146_000 picoseconds. - Weight::from_parts(16_775_000, 3551) + // Minimum execution time: 11_562_000 picoseconds. + Weight::from_parts(11_943_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -212,8 +218,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 17_720_000 picoseconds. - Weight::from_parts(18_916_000, 3551) + // Minimum execution time: 13_075_000 picoseconds. + Weight::from_parts(13_616_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -223,8 +229,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 19_088_000 picoseconds. - Weight::from_parts(19_732_000, 3551) + // Minimum execution time: 13_695_000 picoseconds. + Weight::from_parts(14_658_000, 3551) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -240,8 +246,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `741` // Estimated: `4681` - // Minimum execution time: 30_522_000 picoseconds. - Weight::from_parts(31_573_000, 4681) + // Minimum execution time: 22_623_000 picoseconds. + Weight::from_parts(23_233_000, 4681) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -259,8 +265,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `776` // Estimated: `5996` - // Minimum execution time: 35_833_000 picoseconds. - Weight::from_parts(36_830_000, 5996) + // Minimum execution time: 26_901_000 picoseconds. + Weight::from_parts(27_472_000, 5996) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -273,12 +279,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `859` + // Measured: `878` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 65_882_000 picoseconds. - Weight::from_parts(67_506_904, 6196) - // Standard Error: 49_386 - .saturating_add(Weight::from_parts(1_197_959, 0).saturating_mul(m.into())) + // Minimum execution time: 51_778_000 picoseconds. + Weight::from_parts(53_726_731, 6196) + // Standard Error: 45_279 + .saturating_add(Weight::from_parts(677_769, 0).saturating_mul(m.into())) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(T::DbWeight::get().writes(5_u64)) @@ -290,8 +296,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 41_860_000 picoseconds. - Weight::from_parts(42_478_000, 3593) + // Minimum execution time: 31_790_000 picoseconds. + Weight::from_parts(32_601_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -303,8 +309,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `604` // Estimated: `3551` - // Minimum execution time: 32_593_000 picoseconds. - Weight::from_parts(35_399_000, 3551) + // Minimum execution time: 18_465_000 picoseconds. + Weight::from_parts(21_050_000, 3551) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -318,8 +324,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 41_934_000 picoseconds. - Weight::from_parts(50_480_000, 3533) + // Minimum execution time: 23_825_000 picoseconds. + Weight::from_parts(26_250_000, 3533) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -333,10 +339,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `995` + // Measured: `1014` // Estimated: `3593` - // Minimum execution time: 47_167_000 picoseconds. - Weight::from_parts(54_289_000, 3593) + // Minimum execution time: 28_103_000 picoseconds. + Weight::from_parts(32_622_000, 3593) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -348,20 +354,18 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `661` // Estimated: `4698` - // Minimum execution time: 29_755_000 picoseconds. - Weight::from_parts(32_857_000, 4698) + // Minimum execution time: 16_751_000 picoseconds. + Weight::from_parts(17_373_000, 4698) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_793_000 picoseconds. - Weight::from_parts(4_086_907, 0) - // Standard Error: 14 - .saturating_add(Weight::from_parts(60, 0).saturating_mul(n.into())) + // Minimum execution time: 2_705_000 picoseconds. + Weight::from_parts(2_991_768, 0) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -370,13 +374,13 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `404` // Estimated: `1487` - // Minimum execution time: 6_262_000 picoseconds. - Weight::from_parts(6_734_896, 1487) + // Minimum execution time: 4_598_000 picoseconds. + Weight::from_parts(4_937_302, 1487) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Broker::RevenueInbox` (r:1 w:1) - /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Storage: `Broker::InstaPoolHistory` (r:1 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) @@ -387,32 +391,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `829` - // Estimated: `3593` - // Minimum execution time: 39_812_000 picoseconds. - Weight::from_parts(41_227_000, 3593) + // Measured: `991` + // Estimated: `4456` + // Minimum execution time: 37_601_000 picoseconds. + Weight::from_parts(38_262_000, 4456) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } - /// Storage: `Broker::InstaPoolIo` (r:3 w:3) - /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Broker::Reservations` (r:1 w:0) - /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) - /// Storage: `Broker::Leases` (r:1 w:1) - /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) - /// Storage: `Broker::SaleInfo` (r:0 w:1) - /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Broker::Workplan` (r:0 w:10) - /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn rotate_sale(_n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6281` - // Estimated: `8499` - // Minimum execution time: 34_576_000 picoseconds. - Weight::from_parts(36_303_629, 8499) - .saturating_add(T::DbWeight::get().reads(5_u64)) - .saturating_add(T::DbWeight::get().writes(15_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -422,8 +414,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 6_978_000 picoseconds. - Weight::from_parts(7_206_000, 3493) + // Minimum execution time: 5_391_000 picoseconds. + Weight::from_parts(5_630_000, 3493) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -435,8 +427,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 15_063_000 picoseconds. - Weight::from_parts(15_463_000, 4681) + // Minimum execution time: 10_249_000 picoseconds. + Weight::from_parts(10_529_000, 4681) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -444,8 +436,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 126_000 picoseconds. - Weight::from_parts(157_000, 0) + // Minimum execution time: 120_000 picoseconds. + Weight::from_parts(140_000, 0) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -453,8 +445,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_803_000 picoseconds. - Weight::from_parts(1_965_000, 0) + // Minimum execution time: 1_402_000 picoseconds. + Weight::from_parts(1_513_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::RevenueInbox` (r:0 w:1) @@ -473,16 +465,16 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::CoreCountInbox` (r:1 w:0) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: `Broker::RevenueInbox` (r:1 w:0) - /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `441` - // Estimated: `1516` - // Minimum execution time: 9_313_000 picoseconds. - Weight::from_parts(9_699_000, 1516) + // Measured: `603` + // Estimated: `4068` + // Minimum execution time: 8_897_000 picoseconds. + Weight::from_parts(9_218_000, 4068) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) @@ -490,8 +482,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 5_984_000 picoseconds. - Weight::from_parts(6_296_000, 1526) + // Minimum execution time: 4_678_000 picoseconds. + Weight::from_parts(4_920_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -502,6 +494,44 @@ impl WeightInfo for SubstrateWeight { // Minimum execution time: 229_000 picoseconds. Weight::from_parts(268_000, 0) } + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:1 w:2) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn enable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `930` + // Estimated: `4698` + // Minimum execution time: 51_597_000 picoseconds. + Weight::from_parts(52_609_000, 4698) + .saturating_add(T::DbWeight::get().reads(8_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) + } + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + fn disable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `484` + // Estimated: `1586` + // Minimum execution time: 8_907_000 picoseconds. + Weight::from_parts(9_167_000, 1586) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } } // For backwards compatibility and tests. @@ -512,8 +542,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_977_000 picoseconds. - Weight::from_parts(2_114_000, 0) + // Minimum execution time: 1_593_000 picoseconds. + Weight::from_parts(1_703_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -522,8 +552,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 16_880_000 picoseconds. - Weight::from_parts(17_506_000, 7496) + // Minimum execution time: 12_864_000 picoseconds. + Weight::from_parts(13_174_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -533,8 +563,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 15_569_000 picoseconds. - Weight::from_parts(16_123_000, 7496) + // Minimum execution time: 12_284_000 picoseconds. + Weight::from_parts(13_566_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -544,8 +574,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 8_962_000 picoseconds. - Weight::from_parts(9_389_000, 1526) + // Minimum execution time: 6_743_000 picoseconds. + Weight::from_parts(7_094_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -557,6 +587,8 @@ impl WeightInfo for () { /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) /// Storage: `Broker::InstaPoolIo` (r:3 w:3) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) /// Storage: `Broker::SaleInfo` (r:0 w:1) /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) /// Storage: `Broker::Status` (r:0 w:1) @@ -568,12 +600,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 27_119_000 picoseconds. - Weight::from_parts(47_930_900, 8499) - // Standard Error: 464 - .saturating_add(Weight::from_parts(2_940, 0).saturating_mul(n.into())) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(15_u64)) + // Minimum execution time: 21_120_000 picoseconds. + Weight::from_parts(40_929_422, 8499) + // Standard Error: 471 + .saturating_add(Weight::from_parts(1_004, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(7_u64)) + .saturating_add(RocksDbWeight::get().writes(16_u64)) } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) @@ -589,8 +621,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `651` // Estimated: `2136` - // Minimum execution time: 42_429_000 picoseconds. - Weight::from_parts(43_538_000, 2136) + // Minimum execution time: 31_169_000 picoseconds. + Weight::from_parts(32_271_000, 2136) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -612,8 +644,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `769` // Estimated: `4698` - // Minimum execution time: 62_957_000 picoseconds. - Weight::from_parts(66_821_000, 4698) + // Minimum execution time: 44_945_000 picoseconds. + Weight::from_parts(47_119_000, 4698) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -623,8 +655,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 16_146_000 picoseconds. - Weight::from_parts(16_775_000, 3551) + // Minimum execution time: 11_562_000 picoseconds. + Weight::from_parts(11_943_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -634,8 +666,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 17_720_000 picoseconds. - Weight::from_parts(18_916_000, 3551) + // Minimum execution time: 13_075_000 picoseconds. + Weight::from_parts(13_616_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -645,8 +677,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `496` // Estimated: `3551` - // Minimum execution time: 19_088_000 picoseconds. - Weight::from_parts(19_732_000, 3551) + // Minimum execution time: 13_695_000 picoseconds. + Weight::from_parts(14_658_000, 3551) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -662,8 +694,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `741` // Estimated: `4681` - // Minimum execution time: 30_522_000 picoseconds. - Weight::from_parts(31_573_000, 4681) + // Minimum execution time: 22_623_000 picoseconds. + Weight::from_parts(23_233_000, 4681) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -681,8 +713,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `776` // Estimated: `5996` - // Minimum execution time: 35_833_000 picoseconds. - Weight::from_parts(36_830_000, 5996) + // Minimum execution time: 26_901_000 picoseconds. + Weight::from_parts(27_472_000, 5996) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -695,12 +727,12 @@ impl WeightInfo for () { /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `859` + // Measured: `878` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 65_882_000 picoseconds. - Weight::from_parts(67_506_904, 6196) - // Standard Error: 49_386 - .saturating_add(Weight::from_parts(1_197_959, 0).saturating_mul(m.into())) + // Minimum execution time: 51_778_000 picoseconds. + Weight::from_parts(53_726_731, 6196) + // Standard Error: 45_279 + .saturating_add(Weight::from_parts(677_769, 0).saturating_mul(m.into())) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(m.into()))) .saturating_add(RocksDbWeight::get().writes(5_u64)) @@ -712,8 +744,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 41_860_000 picoseconds. - Weight::from_parts(42_478_000, 3593) + // Minimum execution time: 31_790_000 picoseconds. + Weight::from_parts(32_601_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -725,8 +757,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `604` // Estimated: `3551` - // Minimum execution time: 32_593_000 picoseconds. - Weight::from_parts(35_399_000, 3551) + // Minimum execution time: 18_465_000 picoseconds. + Weight::from_parts(21_050_000, 3551) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -740,8 +772,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 41_934_000 picoseconds. - Weight::from_parts(50_480_000, 3533) + // Minimum execution time: 23_825_000 picoseconds. + Weight::from_parts(26_250_000, 3533) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -755,10 +787,10 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { // Proof Size summary in bytes: - // Measured: `995` + // Measured: `1014` // Estimated: `3593` - // Minimum execution time: 47_167_000 picoseconds. - Weight::from_parts(54_289_000, 3593) + // Minimum execution time: 28_103_000 picoseconds. + Weight::from_parts(32_622_000, 3593) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -770,20 +802,18 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `661` // Estimated: `4698` - // Minimum execution time: 29_755_000 picoseconds. - Weight::from_parts(32_857_000, 4698) + // Minimum execution time: 16_751_000 picoseconds. + Weight::from_parts(17_373_000, 4698) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// The range of component `n` is `[0, 1000]`. - fn request_core_count(n: u32, ) -> Weight { + fn request_core_count(_n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_793_000 picoseconds. - Weight::from_parts(4_086_907, 0) - // Standard Error: 14 - .saturating_add(Weight::from_parts(60, 0).saturating_mul(n.into())) + // Minimum execution time: 2_705_000 picoseconds. + Weight::from_parts(2_991_768, 0) } /// Storage: `Broker::CoreCountInbox` (r:1 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -792,13 +822,13 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `404` // Estimated: `1487` - // Minimum execution time: 6_262_000 picoseconds. - Weight::from_parts(6_734_896, 1487) + // Minimum execution time: 4_598_000 picoseconds. + Weight::from_parts(4_937_302, 1487) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Broker::RevenueInbox` (r:1 w:1) - /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) /// Storage: `Broker::InstaPoolHistory` (r:1 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) @@ -809,32 +839,20 @@ impl WeightInfo for () { /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn process_revenue() -> Weight { // Proof Size summary in bytes: - // Measured: `829` - // Estimated: `3593` - // Minimum execution time: 39_812_000 picoseconds. - Weight::from_parts(41_227_000, 3593) + // Measured: `991` + // Estimated: `4456` + // Minimum execution time: 37_601_000 picoseconds. + Weight::from_parts(38_262_000, 4456) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } - /// Storage: `Broker::InstaPoolIo` (r:3 w:3) - /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Broker::Reservations` (r:1 w:0) - /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) - /// Storage: `Broker::Leases` (r:1 w:1) - /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) - /// Storage: `Broker::SaleInfo` (r:0 w:1) - /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) - /// Storage: `Broker::Workplan` (r:0 w:10) - /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 1000]`. fn rotate_sale(_n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `6281` - // Estimated: `8499` - // Minimum execution time: 34_576_000 picoseconds. - Weight::from_parts(36_303_629, 8499) - .saturating_add(RocksDbWeight::get().reads(5_u64)) - .saturating_add(RocksDbWeight::get().writes(15_u64)) + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 0_000 picoseconds. + Weight::from_parts(0, 0) } /// Storage: `Broker::InstaPoolIo` (r:1 w:0) /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) @@ -844,8 +862,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 6_978_000 picoseconds. - Weight::from_parts(7_206_000, 3493) + // Minimum execution time: 5_391_000 picoseconds. + Weight::from_parts(5_630_000, 3493) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -857,8 +875,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 15_063_000 picoseconds. - Weight::from_parts(15_463_000, 4681) + // Minimum execution time: 10_249_000 picoseconds. + Weight::from_parts(10_529_000, 4681) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -866,8 +884,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 126_000 picoseconds. - Weight::from_parts(157_000, 0) + // Minimum execution time: 120_000 picoseconds. + Weight::from_parts(140_000, 0) } /// Storage: `Broker::CoreCountInbox` (r:0 w:1) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) @@ -875,8 +893,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_803_000 picoseconds. - Weight::from_parts(1_965_000, 0) + // Minimum execution time: 1_402_000 picoseconds. + Weight::from_parts(1_513_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::RevenueInbox` (r:0 w:1) @@ -895,16 +913,16 @@ impl WeightInfo for () { /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) /// Storage: `Broker::CoreCountInbox` (r:1 w:0) /// Proof: `Broker::CoreCountInbox` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) - /// Storage: `Broker::RevenueInbox` (r:1 w:0) - /// Proof: `Broker::RevenueInbox` (`max_values`: Some(1), `max_size`: Some(20), added: 515, mode: `MaxEncodedLen`) + /// Storage: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) + /// Proof: UNKNOWN KEY `0xf308d869daf021a7724e69c557dd8dbe` (r:1 w:1) fn do_tick_base() -> Weight { // Proof Size summary in bytes: - // Measured: `441` - // Estimated: `1516` - // Minimum execution time: 9_313_000 picoseconds. - Weight::from_parts(9_699_000, 1516) + // Measured: `603` + // Estimated: `4068` + // Minimum execution time: 8_897_000 picoseconds. + Weight::from_parts(9_218_000, 4068) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Broker::Leases` (r:1 w:1) /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) @@ -912,8 +930,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 5_984_000 picoseconds. - Weight::from_parts(6_296_000, 1526) + // Minimum execution time: 4_678_000 picoseconds. + Weight::from_parts(4_920_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -924,4 +942,42 @@ impl WeightInfo for () { // Minimum execution time: 229_000 picoseconds. Weight::from_parts(268_000, 0) } -} + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::PotentialRenewals` (r:1 w:2) + /// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Authorship::Author` (r:1 w:0) + /// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `System::Digest` (r:1 w:0) + /// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn enable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `930` + // Estimated: `4698` + // Minimum execution time: 51_597_000 picoseconds. + Weight::from_parts(52_609_000, 4698) + .saturating_add(RocksDbWeight::get().reads(8_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) + } + /// Storage: `Broker::AutoRenewals` (r:1 w:1) + /// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(101), added: 596, mode: `MaxEncodedLen`) + fn disable_auto_renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `484` + // Estimated: `1586` + // Minimum execution time: 8_907_000 picoseconds. + Weight::from_parts(9_167_000, 1586) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} \ No newline at end of file