From bec7b6846369cd4b72756b572a4a076c0279dc3f Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 8 Jul 2023 18:27:20 +0200 Subject: [PATCH 001/131] Add Broker pallet --- Cargo.toml | 1 + frame/broker/Cargo.toml | 49 ++++++++ frame/broker/README.md | 30 +++++ frame/broker/src/benchmarking.rs | 50 +++++++++ frame/broker/src/lib.rs | 186 +++++++++++++++++++++++++++++++ frame/broker/src/mock.rs | 172 ++++++++++++++++++++++++++++ frame/broker/src/tests.rs | 31 ++++++ frame/broker/src/weights.rs | 45 ++++++++ 8 files changed, 564 insertions(+) create mode 100644 frame/broker/Cargo.toml create mode 100644 frame/broker/README.md create mode 100644 frame/broker/src/benchmarking.rs create mode 100644 frame/broker/src/lib.rs create mode 100644 frame/broker/src/mock.rs create mode 100644 frame/broker/src/tests.rs create mode 100644 frame/broker/src/weights.rs diff --git a/Cargo.toml b/Cargo.toml index d616c03c71f61..7fc0b018d9ee0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -89,6 +89,7 @@ members = [ "frame/benchmarking", "frame/benchmarking/pov", "frame/bounties", + "frame/broker", "frame/child-bounties", "frame/collective", "frame/contracts", diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml new file mode 100644 index 0000000000000..8e08f583ca4f4 --- /dev/null +++ b/frame/broker/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "pallet-broker" +version = "0.1.0" +description = "Brokerage tool for managing Polkadot Core scheduling" +authors = ["Parity Technologies "] +homepage = "https://substrate.io" +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/paritytech/substrate" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive"] } +scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } +bitvec = "1" + +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } + +[dev-dependencies] +sp-core = { version = "21.0.0", git = "https://github.com/paritytech/substrate" } +sp-io = { version = "23.0.0", git = "https://github.com/paritytech/substrate" } +sp-runtime = { version = "24.0.0", git = "https://github.com/paritytech/substrate" } + +[features] +default = ["std"] + +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-runtime/std", +] + +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] + +try-runtime = [ + "frame-support/try-runtime" +] diff --git a/frame/broker/README.md b/frame/broker/README.md new file mode 100644 index 0000000000000..0a4337903c42f --- /dev/null +++ b/frame/broker/README.md @@ -0,0 +1,30 @@ +# Pallet Broker + +Brokerage tool for managing Polkadot Core scheduling +(TODO add more). + +# Design Goals + +1. TODO + +# Design + +TODO + +# Examples + +```rust +use pallet_broker::Pallet as Broker; + +fn main() { + +} +``` + +# License + +Apache-2.0 + +# References +This crate was auto generated by FRAMY CLI . +Please report bugs and build failures at . diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs new file mode 100644 index 0000000000000..9dcc6714eb65d --- /dev/null +++ b/frame/broker/src/benchmarking.rs @@ -0,0 +1,50 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; + +#[benchmarks] +mod benches { + use super::*; + + /// Benchmarks the slowest path of `change_value`. + #[benchmark] + fn change_value() -> Result<(), BenchmarkError> { + let caller: T::AccountId = whitelisted_caller(); + + // You can mock the storage here: + DummyValue::::put(1); + + #[extrinsic_call] + _(RawOrigin::Signed(caller.clone()), 9); + + Ok(()) + } + + // Implements a test for each benchmark. Execute with: + // `cargo test -p pallet-broker --features runtime-benchmarks`. + impl_benchmark_test_suite!( + Pallet, + crate::mock::new_test_ext(), + crate::mock::Test + ); +} diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs new file mode 100644 index 0000000000000..a4aa1907ef501 --- /dev/null +++ b/frame/broker/src/lib.rs @@ -0,0 +1,186 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg_attr(not(feature = "std"), no_std)] +#![doc = include_str!("../README.md")] + +pub use pallet::*; + +mod mock; +mod tests; +mod benchmarking; + +pub mod weights; +pub use weights::WeightInfo; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use bitvec::BitArr; + use frame_support::{pallet_prelude::*, traits::fungible::{self, Inspect, Mutate, MutateHold}}; + use frame_system::pallet_prelude::*; + use sp_runtime::AccountId32; + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + type Currency: Inspect;//Mutate + MutateHold; + + /// Weight information for all calls of this pallet. + type WeightInfo: WeightInfo; + } + + pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; + + pub type Timeslice = u32; + pub type CoreIndex = u16; + // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. + pub type CorePart = [u8; 10]; + pub type RelayAccountId = AccountId32; + pub type Balance = u128; + pub type ParaId = u32; + /// Counter for the total CoreParts which could be dedicated to a pool. `u32` so we don't ever + /// get an overflow. + pub type PartCount = u32; + pub type SignedPartCount = i32; + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct RegionId { + begin: Timeslice, + core: CoreIndex, + part: CorePart, + } + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct RegionRecord { + end: Timeslice, + owner: AccountId, + } + pub type RegionRecordOf = RegionRecord<::AccountId>; + + // TODO: Use a more specialised 32-bit type which puts Off and InstaPool into unused 32-bit values. + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum CoreTask { + Off, + Assigned { target: ParaId }, + InstaPool, + } + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct ScheduleItem { + part: CorePart, + task: CoreTask, + } + pub type Schedule = BoundedVec>; + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub enum Contributor { + System, + Private(AccountId), + } + pub type ContributorOf = Contributor<::AccountId>; + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct ContributionRecord { + begin: Timeslice, + end: Timeslice, + core: CoreIndex, + parts: CorePart, + payee: Contributor, + } + pub type ContributionRecordOf = ContributionRecord<::AccountId>; + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct InstaPoolHistoryRecord { + total_contributions: PartCount, + maybe_payout: Option, + } + pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; + + #[pallet::storage] + pub type Regions = StorageMap<_, Blake2_128Concat, RegionId, RegionRecordOf, OptionQuery>; + + /// The work we plan on having each core do at a particular time in the future. + #[pallet::storage] + pub type Workplan = StorageMap<_, Twox64Concat, (Timeslice, CoreIndex), Schedule, OptionQuery>; + + /// The current workload of each core. This gets updated with workplan as timeslices pass. + #[pallet::storage] + pub type Workload = StorageMap<_, Twox64Concat, CoreIndex, Schedule, OptionQuery>; + + #[pallet::storage] + pub type InstaPoolSize = StorageValue<_, PartCount, ValueQuery>; + + #[pallet::storage] + pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, ContributionRecordOf, (), OptionQuery>; + + #[pallet::storage] + pub type InstaPoolIo = StorageMap<_, Blake2_128Concat, Timeslice, SignedPartCount, ValueQuery>; + + /// Total InstaPool rewards for each Timeslice and the number of core parts which contributed. + #[pallet::storage] + pub type InstaPoolHistory = StorageMap<_, Blake2_128Concat, Timeslice, InstaPoolHistoryRecordOf>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + Transferred { + region_id: RegionId, + old_owner: T::AccountId, + owner: T::AccountId, + } + } + + // Errors inform users that something went wrong. + #[pallet::error] + pub enum Error { + UnknownRegion, + NotOwner, + } + + #[pallet::call(weight(::WeightInfo))] + impl Pallet { + #[pallet::call_index(0)] + pub fn transfer(origin: OriginFor, region_id: RegionId, new_owner: T::AccountId) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_transfer(region_id, Some(who), new_owner)?; + Ok(()) + } + } + + impl Pallet { + /// Logic for call `Self::change_value`. + pub(crate) fn do_transfer(region_id: RegionId, maybe_check_owner: Option, new_owner: T::AccountId) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + let old_owner = region.owner; + region.owner = new_owner; + Regions::::insert(®ion_id, ®ion); + Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); + + Ok(()) + } + } +} diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs new file mode 100644 index 0000000000000..ff8815f6f635d --- /dev/null +++ b/frame/broker/src/mock.rs @@ -0,0 +1,172 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use frame_support::{ + parameter_types, + traits::{ConstU16, ConstU64, fungibles, fungible::ItemOf, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} +}; +use sp_core::{H256, Get, ConstU32, TypedGet}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Broker: crate, + } +); + +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +pub struct TestFungibles(core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance)>); + +use std::collections::HashMap; + +parameter_types! { + static TestAssetOf: HashMap<(u32, Vec), Vec> = Default::default(); + static TestBalanceOf: HashMap<(u32, Vec, Vec), Vec> = Default::default(); +} + +use codec::{Encode, Decode}; +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, +> fungibles::Inspect for TestFungibles +where + MinimumBalance::Type: tokens::Balance, + +{ + type AssetId = AssetId; + type Balance = MinimumBalance::Type; + + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + TestAssetOf::get().get(&(Instance::get(), asset.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() + } + + fn active_issuance(asset: Self::AssetId) -> Self::Balance { + Self::total_issuance(asset) + } + + /// The minimum balance any single account may have. + fn minimum_balance(asset: Self::AssetId) -> Self::Balance { + MinimumBalance::get() + } + + fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + TestBalanceOf::get().get(&(Instance::get(), asset.encode(), who.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() + } + + fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + Self::total_balance(asset, who) + } + + fn reducible_balance( + asset: Self::AssetId, + who: &AccountId, + _preservation: Preservation, + _force: Fortitude, + ) -> Self::Balance { + Self::total_balance(asset, who) + } + + fn can_deposit( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + _provenance: Provenance, + ) -> DepositConsequence { + if !Self::asset_exists(asset) { + return DepositConsequence::UnknownAsset; + } + if amount + Self::balance(asset, who) < Self::minimum_balance(asset) { + return DepositConsequence::BelowMinimum; + } + DepositConsequence::Success + } + + fn can_withdraw( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + if Self::reducible_balance(asset, who, Preservation::Expendable, Fortitude::Polite) < amount { + return WithdrawConsequence::BalanceLow; + } + if Self::total_balance(asset, who) < Self::minimum_balance(asset) + amount { + return WithdrawConsequence::WouldDie; + } + WithdrawConsequence::Success + } + + fn asset_exists(asset: Self::AssetId) -> bool { + TestAssetOf::get().contains_key(&(Instance::get(), asset.encode())) + } +} + +impl crate::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Currency = ItemOf>, (), u64>; + type WeightInfo = (); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default().build_storage::().unwrap().into() +} diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs new file mode 100644 index 0000000000000..78679ae6fa9f0 --- /dev/null +++ b/frame/broker/src/tests.rs @@ -0,0 +1,31 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +use crate::{mock::*, Error}; +use frame_support::{assert_noop, assert_ok}; + +#[test] +fn bitvec_size() { + use bitvec::BitArr; + type CoreParts = BitArr!(for 80, in u8); + new_test_ext().execute_with(|| { + println!("{}", core::mem::size_of::()); + panic!(); + }); +} diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs new file mode 100644 index 0000000000000..ed6f964377ce0 --- /dev/null +++ b/frame/broker/src/weights.rs @@ -0,0 +1,45 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for `pallet-broker`. + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for `pallet-broker`. +pub trait WeightInfo { + fn transfer() -> Weight; +} + +/// Weights for `pallet-broker` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn transfer() -> Weight { + Weight::from_parts(123, 456) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn transfer() -> Weight { + Weight::from_parts(123, 456) + } +} From c73ce75846512aba1dd456ae86dc9e31f120e146 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 8 Jul 2023 18:55:37 +0200 Subject: [PATCH 002/131] Flesh out CorePart --- Cargo.lock | 3070 ++++++++++++++++++++++--------------- frame/broker/Cargo.toml | 2 +- frame/broker/src/lib.rs | 20 +- frame/broker/src/mock.rs | 99 +- frame/broker/src/tests.rs | 5 +- 5 files changed, 1830 insertions(+), 1366 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19cc8cd781a71..f94c214a88363 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -826,8 +826,8 @@ dependencies = [ "env_logger 0.9.3", "hash-db", "log", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", ] [[package]] @@ -1186,8 +1186,8 @@ dependencies = [ "rand 0.8.5", "sc-chain-spec", "sc-keystore", - "sp-core", - "sp-keystore", + "sp-core 21.0.0", + "sp-keystore 0.27.0", ] [[package]] @@ -2614,9 +2614,9 @@ name = "frame-benchmarking" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-support", - "frame-support-procedural", - "frame-system", + "frame-support 4.0.0-dev", + "frame-support-procedural 4.0.0-dev", + "frame-system 4.0.0-dev", "linregress", "log", "parity-scale-codec", @@ -2624,15 +2624,40 @@ dependencies = [ "rusty-fork", "scale-info", "serde", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "static_assertions", +] + +[[package]] +name = "frame-benchmarking" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "frame-support-procedural 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "frame-system 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "linregress", + "log", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "sp-api 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "sp-application-crypto 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", "static_assertions", ] @@ -2645,9 +2670,9 @@ dependencies = [ "chrono", "clap 4.3.2", "comfy-table", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "gethostname", "handlebars", "itertools", @@ -2666,19 +2691,19 @@ dependencies = [ "sc-sysinfo", "serde", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-database", - "sp-externalities", - "sp-inherents", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-state-machine", - "sp-storage", - "sp-trie", - "sp-wasm-interface", + "sp-externalities 0.19.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-storage 13.0.0", + "sp-trie 22.0.0", + "sp-wasm-interface 14.0.0", "thiserror", "thousands", ] @@ -2687,14 +2712,14 @@ dependencies = [ name = "frame-benchmarking-pallet-pov" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -2702,13 +2727,13 @@ name = "frame-election-provider-solution-type" version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support", + "frame-support 4.0.0-dev", "parity-scale-codec", "proc-macro-crate", "proc-macro2", "quote", "scale-info", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "syn 2.0.18", "trybuild", ] @@ -2718,17 +2743,17 @@ name = "frame-election-provider-support" version = "4.0.0-dev" dependencies = [ "frame-election-provider-solution-type", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-npos-elections", - "sp-runtime", - "sp-std", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -2738,14 +2763,14 @@ dependencies = [ "clap 4.3.2", "frame-election-provider-solution-type", "frame-election-provider-support", - "frame-support", + "frame-support 4.0.0-dev", "honggfuzz", "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "sp-npos-elections", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] @@ -2753,20 +2778,20 @@ name = "frame-executive" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "frame-try-runtime", "pallet-balances", "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", - "sp-version", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-version 22.0.0", ] [[package]] @@ -2786,7 +2811,7 @@ name = "frame-remote-externalities" version = "0.10.0-dev" dependencies = [ "async-recursion", - "frame-support", + "frame-support 4.0.0-dev", "futures", "indicatif", "jsonrpsee", @@ -2794,9 +2819,9 @@ dependencies = [ "pallet-elections-phragmen", "parity-scale-codec", "serde", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "spinners", "substrate-rpc-client", "tokio", @@ -2813,8 +2838,8 @@ dependencies = [ "bitflags", "environmental", "frame-metadata", - "frame-support-procedural", - "frame-system", + "frame-support-procedural 4.0.0-dev", + "frame-system 4.0.0-dev", "impl-trait-for-tuples", "k256", "log", @@ -2826,19 +2851,53 @@ dependencies = [ "serde", "serde_json", "smallvec", - "sp-api", - "sp-arithmetic", - "sp-core", - "sp-core-hashing-proc-macro", - "sp-debug-derive", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-weights", + "sp-api 4.0.0-dev", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-core-hashing-proc-macro 9.0.0", + "sp-debug-derive 8.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-weights 20.0.0", + "tt-call", +] + +[[package]] +name = "frame-support" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "bitflags", + "environmental", + "frame-metadata", + "frame-support-procedural 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "impl-trait-for-tuples", + "k256", + "log", + "macro_magic", + "parity-scale-codec", + "paste", + "scale-info", + "serde", + "smallvec", + "sp-api 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core-hashing-proc-macro 9.0.0 (git+https://github.com/paritytech/substrate)", + "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-inherents 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-staking 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", + "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", "tt-call", ] @@ -2850,7 +2909,7 @@ dependencies = [ "cfg-expr", "derive-syn-parse", "expander", - "frame-support-procedural-tools", + "frame-support-procedural-tools 4.0.0-dev", "itertools", "macro_magic", "proc-macro-warning", @@ -2859,11 +2918,41 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "frame-support-procedural" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "Inflector", + "cfg-expr", + "derive-syn-parse", + "expander", + "frame-support-procedural-tools 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "itertools", + "macro_magic", + "proc-macro-warning", + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "frame-support-procedural-tools" +version = "4.0.0-dev" +dependencies = [ + "frame-support-procedural-tools-derive 3.0.0", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ - "frame-support-procedural-tools-derive", + "frame-support-procedural-tools-derive 3.0.0 (git+https://github.com/paritytech/substrate)", "proc-macro-crate", "proc-macro2", "quote", @@ -2879,28 +2968,38 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "frame-support-procedural-tools-derive" +version = "3.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "frame-support-test" version = "3.0.0" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-executive", - "frame-support", + "frame-support 4.0.0-dev", "frame-support-test-pallet", - "frame-system", + "frame-system 4.0.0-dev", "parity-scale-codec", "pretty_assertions", "rustversion", "scale-info", "serde", - "sp-api", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-std", - "sp-version", + "sp-api 4.0.0-dev", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-version 22.0.0", "static_assertions", "trybuild", ] @@ -2909,21 +3008,21 @@ dependencies = [ name = "frame-support-test-compile-pass" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-core", - "sp-runtime", - "sp-version", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-version 22.0.0", ] [[package]] name = "frame-support-test-pallet" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", @@ -2935,36 +3034,55 @@ version = "4.0.0-dev" dependencies = [ "cfg-if", "criterion", - "frame-support", + "frame-support 4.0.0-dev", "log", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-externalities", - "sp-io", - "sp-runtime", - "sp-std", - "sp-version", - "sp-weights", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-version 22.0.0", + "sp-weights 20.0.0", "substrate-test-runtime-client", ] +[[package]] +name = "frame-system" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "cfg-if", + "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "log", + "parity-scale-codec", + "scale-info", + "serde", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-version 22.0.0 (git+https://github.com/paritytech/substrate)", + "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", +] + [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-core", - "sp-externalities", - "sp-io", - "sp-runtime", - "sp-std", - "sp-version", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-version 22.0.0", ] [[package]] @@ -2972,18 +3090,18 @@ name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" dependencies = [ "parity-scale-codec", - "sp-api", + "sp-api 4.0.0-dev", ] [[package]] name = "frame-try-runtime" version = "0.10.0-dev" dependencies = [ - "frame-support", + "frame-support 4.0.0-dev", "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -3161,8 +3279,8 @@ version = "4.0.0-dev" dependencies = [ "chrono", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "num-format", "pallet-staking", ] @@ -4042,12 +4160,12 @@ dependencies = [ name = "kitchensink-runtime" version = "3.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-benchmarking-pallet-pov", "frame-election-provider-support", "frame-executive", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", @@ -4127,22 +4245,22 @@ dependencies = [ "parity-scale-codec", "primitive-types", "scale-info", - "sp-api", + "sp-api 4.0.0-dev", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core", - "sp-inherents", - "sp-io", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", "sp-offchain", - "sp-runtime", + "sp-runtime 24.0.0", "sp-session", - "sp-staking", + "sp-staking 4.0.0-dev", "sp-statement-store", - "sp-std", + "sp-std 8.0.0", "sp-transaction-pool", - "sp-version", + "sp-version 22.0.0", "static_assertions", "substrate-wasm-builder", ] @@ -5071,14 +5189,14 @@ dependencies = [ "sc-block-builder", "sc-client-api", "sc-offchain", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core", + "sp-core 21.0.0", "sp-mmr-primitives", - "sp-runtime", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-test-runtime-client", "tokio", ] @@ -5092,11 +5210,11 @@ dependencies = [ "parity-scale-codec", "serde", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-mmr-primitives", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] @@ -5374,13 +5492,13 @@ dependencies = [ "serde", "serde_json", "sp-consensus", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-timestamp", - "sp-tracing", - "sp-trie", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", "tempfile", ] @@ -5394,7 +5512,7 @@ dependencies = [ "clap_complete", "criterion", "frame-benchmarking-cli", - "frame-system", + "frame-system 4.0.0-dev", "frame-system-rpc-runtime-api", "futures", "jsonrpsee", @@ -5446,21 +5564,21 @@ dependencies = [ "serde", "serde_json", "soketto", - "sp-api", + "sp-api 4.0.0-dev", "sp-authority-discovery", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core", - "sp-inherents", - "sp-io", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", "sp-keyring", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-statement-store", "sp-timestamp", - "sp-tracing", + "sp-tracing 10.0.0", "sp-transaction-storage-proof", "substrate-build-script-utils", "substrate-cli-test-utils", @@ -5478,9 +5596,9 @@ name = "node-executor" version = "3.0.0-dev" dependencies = [ "criterion", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "futures", "kitchensink-runtime", "node-primitives", @@ -5497,17 +5615,17 @@ dependencies = [ "parity-scale-codec", "sc-executor", "scale-info", - "sp-application-crypto", + "sp-application-crypto 23.0.0", "sp-consensus-babe", - "sp-core", - "sp-externalities", + "sp-core 21.0.0", + "sp-externalities 0.19.0", "sp-keyring", - "sp-keystore", - "sp-runtime", - "sp-state-machine", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-statement-store", - "sp-tracing", - "sp-trie", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", "wat", ] @@ -5521,8 +5639,8 @@ dependencies = [ "sc-client-api", "sc-service", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "thiserror", ] @@ -5530,8 +5648,8 @@ dependencies = [ name = "node-primitives" version = "2.0.0" dependencies = [ - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", ] [[package]] @@ -5553,13 +5671,13 @@ dependencies = [ "sc-rpc-spec-v2", "sc-sync-state-rpc", "sc-transaction-pool-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-statement-store", "substrate-frame-rpc-system", "substrate-state-trie-migration-rpc", @@ -5579,9 +5697,9 @@ name = "node-template" version = "4.0.0-dev" dependencies = [ "clap 4.3.2", - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-benchmarking-cli", - "frame-system", + "frame-system 4.0.0-dev", "futures", "jsonrpsee", "node-template-runtime", @@ -5600,16 +5718,16 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core", - "sp-inherents", - "sp-io", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", "sp-keyring", - "sp-runtime", + "sp-runtime 24.0.0", "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", @@ -5634,10 +5752,10 @@ dependencies = [ name = "node-template-runtime" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-executive", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", @@ -5651,18 +5769,18 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core", - "sp-inherents", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", "sp-offchain", - "sp-runtime", + "sp-runtime 24.0.0", "sp-session", - "sp-std", + "sp-std 8.0.0", "sp-transaction-pool", - "sp-version", + "sp-version 22.0.0", "substrate-wasm-builder", ] @@ -5670,7 +5788,7 @@ dependencies = [ name = "node-testing" version = "3.0.0-dev" dependencies = [ - "frame-system", + "frame-system 4.0.0-dev", "fs_extra", "futures", "kitchensink-runtime", @@ -5688,15 +5806,15 @@ dependencies = [ "sc-consensus", "sc-executor", "sc-service", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-inherents", - "sp-io", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", "sp-keyring", - "sp-runtime", + "sp-runtime 24.0.0", "sp-timestamp", "substrate-test-client", "tempfile", @@ -5955,84 +6073,84 @@ name = "pallet-alliance" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-collective", "pallet-identity", "parity-scale-codec", "scale-info", - "sp-core", - "sp-core-hashing", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-core-hashing 9.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-asset-conversion" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-assets", "pallet-balances", "parity-scale-codec", "primitive-types", "scale-info", - "sp-api", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-asset-conversion-tx-payment" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-storage", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", ] [[package]] name = "pallet-asset-rate" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-asset-tx-payment" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-assets", "pallet-authorship", "pallet-balances", @@ -6041,101 +6159,101 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-storage", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", ] [[package]] name = "pallet-assets" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-atomic-swap" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-aura" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 23.0.0", "sp-consensus-aura", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 23.0.0", "sp-authority-discovery", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-authorship" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-babe" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-authorship", "pallet-balances", @@ -6146,33 +6264,33 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 23.0.0", "sp-consensus-babe", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "sp-session", - "sp-staking", - "sp-std", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-bags-list" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", ] [[package]] @@ -6191,34 +6309,34 @@ version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", "frame-remote-externalities", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-bags-list", "pallet-staking", - "sp-core", - "sp-runtime", - "sp-std", - "sp-storage", - "sp-tracing", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "sp-tracing 10.0.0", ] [[package]] name = "pallet-balances" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-transaction-payment", "parity-scale-codec", "paste", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6226,8 +6344,8 @@ name = "pallet-beefy" version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-authorship", "pallet-balances", "pallet-offences", @@ -6239,12 +6357,12 @@ dependencies = [ "scale-info", "serde", "sp-consensus-beefy", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "sp-session", - "sp-staking", - "sp-std", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] @@ -6253,8 +6371,8 @@ version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", "binary-merkle-tree", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-beefy", "pallet-mmr", @@ -6262,66 +6380,82 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api", + "sp-api 4.0.0-dev", "sp-consensus-beefy", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-bounties" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "pallet-broker" +version = "0.1.0" +dependencies = [ + "bitvec", + "frame-benchmarking 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "frame-system 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "parity-scale-codec", + "scale-info", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-bounties", "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-collective" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6333,9 +6467,9 @@ dependencies = [ "bitflags", "env_logger 0.9.3", "environmental", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "impl-trait-for-tuples", "log", "pallet-balances", @@ -6352,12 +6486,12 @@ dependencies = [ "scale-info", "serde", "smallvec", - "sp-api", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "wasm-instrument 0.4.0", "wasmi", "wasmparser-nostd", @@ -6371,9 +6505,9 @@ dependencies = [ "bitflags", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-weights 20.0.0", ] [[package]] @@ -6390,58 +6524,58 @@ name = "pallet-conviction-voting" version = "4.0.0-dev" dependencies = [ "assert_matches", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-scheduler", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-core-fellowship" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-default-config-example" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-io", - "sp-runtime", - "sp-std", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-democracy" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-preimage", @@ -6449,26 +6583,26 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-dev-mode" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6476,8 +6610,8 @@ name = "pallet-election-provider-e2e-test" version = "1.0.0" dependencies = [ "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-bags-list", "pallet-balances", @@ -6487,23 +6621,23 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-npos-elections", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-tracing 10.0.0", ] [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-election-provider-support-benchmarking", @@ -6511,13 +6645,13 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-npos-elections", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "strum", ] @@ -6525,31 +6659,31 @@ dependencies = [ name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-system", + "frame-system 4.0.0-dev", "parity-scale-codec", "sp-npos-elections", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-npos-elections", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "substrate-test-utils", ] @@ -6557,66 +6691,66 @@ dependencies = [ name = "pallet-example-basic" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-example-kitchensink" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-example-offchain-worker" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "lite-json", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-example-split" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6636,10 +6770,10 @@ name = "pallet-fast-unstake" version = "4.0.0-dev" dependencies = [ "docify", - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-staking", @@ -6647,12 +6781,12 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-tracing", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "substrate-test-utils", ] @@ -6661,17 +6795,17 @@ name = "pallet-glutton" version = "4.0.0-dev" dependencies = [ "blake2", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6679,10 +6813,10 @@ name = "pallet-grandpa" version = "4.0.0-dev" dependencies = [ "finality-grandpa", - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-authorship", "pallet-balances", @@ -6693,15 +6827,15 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto", + "sp-application-crypto 23.0.0", "sp-consensus-grandpa", - "sp-core", - "sp-io", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-keyring", - "sp-runtime", + "sp-runtime 24.0.0", "sp-session", - "sp-staking", - "sp-std", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] @@ -6709,123 +6843,123 @@ name = "pallet-identity" version = "4.0.0-dev" dependencies = [ "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-im-online" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-authorship", "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-indices" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-keyring", - "sp-runtime", - "sp-std", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-insecure-randomness-collective-flip" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "safe-mix", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-lottery" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", "frame-support-test", - "frame-system", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-membership" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-message-queue" version = "7.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "rand 0.8.5", "rand_distr", "scale-info", "serde", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", - "sp-weights", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-weights 20.0.0", ] [[package]] @@ -6834,53 +6968,53 @@ version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", "env_logger 0.9.3", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "itertools", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-mmr-primitives", - "sp-runtime", - "sp-std", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-multisig" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-nft-fractionalization" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-assets", "pallet-balances", "pallet-nfts", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -6888,103 +7022,103 @@ name = "pallet-nfts" version = "4.0.0-dev" dependencies = [ "enumflags2", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-nfts-runtime-api" version = "4.0.0-dev" dependencies = [ - "frame-support", + "frame-support 4.0.0-dev", "pallet-nfts", "parity-scale-codec", - "sp-api", + "sp-api 4.0.0-dev", ] [[package]] name = "pallet-nicks" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-nis" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-node-authorization" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-nomination-pools" version = "1.0.0" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-tracing", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-tracing 10.0.0", ] [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-bags-list", "pallet-balances", "pallet-nomination-pools", @@ -6993,27 +7127,27 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-runtime-interface", - "sp-staking", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-nomination-pools-fuzzer" version = "2.0.0" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "honggfuzz", "log", "pallet-nomination-pools", "rand 0.8.5", - "sp-io", - "sp-runtime", - "sp-tracing", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", ] [[package]] @@ -7022,8 +7156,8 @@ version = "1.0.0-dev" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", - "sp-api", - "sp-std", + "sp-api 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] @@ -7031,8 +7165,8 @@ name = "pallet-nomination-pools-test-staking" version = "1.0.0" dependencies = [ "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-bags-list", "pallet-balances", @@ -7042,40 +7176,40 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-tracing", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-tracing 10.0.0", ] [[package]] name = "pallet-offences" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-babe", "pallet-balances", @@ -7088,78 +7222,78 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-preimage" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-proxy" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-utility", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-recovery" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -7167,9 +7301,9 @@ name = "pallet-referenda" version = "4.0.0-dev" dependencies = [ "assert_matches", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-preimage", @@ -7177,27 +7311,27 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-remark" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -7205,8 +7339,8 @@ name = "pallet-root-offences" version = "1.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-session", "pallet-staking", @@ -7214,60 +7348,60 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", ] [[package]] name = "pallet-root-testing" version = "1.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-salary" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-scheduler" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-preimage", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-weights", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-weights 20.0.0", "substrate-test-utils", ] @@ -7275,45 +7409,45 @@ dependencies = [ name = "pallet-scored-pool" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-session" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "impl-trait-for-tuples", "log", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "sp-session", - "sp-staking", - "sp-std", - "sp-trie", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-trie 22.0.0", ] [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-session", "pallet-staking", @@ -7322,42 +7456,42 @@ dependencies = [ "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "sp-session", - "sp-std", + "sp-std 8.0.0", ] [[package]] name = "pallet-society" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", "frame-support-test", - "frame-system", + "frame-system 4.0.0-dev", "hex-literal", "log", "pallet-balances", "parity-scale-codec", "rand_chacha 0.2.2", "scale-info", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-staking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-election-provider-support", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-authorship", "pallet-bags-list", @@ -7369,14 +7503,14 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "serde", - "sp-application-crypto", - "sp-core", - "sp-io", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", "sp-npos-elections", - "sp-runtime", - "sp-staking", - "sp-std", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "substrate-test-utils", ] @@ -7387,7 +7521,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "sp-runtime", + "sp-runtime 24.0.0", "syn 2.0.18", ] @@ -7396,7 +7530,7 @@ name = "pallet-staking-reward-fn" version = "4.0.0-dev" dependencies = [ "log", - "sp-arithmetic", + "sp-arithmetic 16.0.0", ] [[package]] @@ -7404,28 +7538,28 @@ name = "pallet-staking-runtime-api" version = "4.0.0-dev" dependencies = [ "parity-scale-codec", - "sp-api", + "sp-api 4.0.0-dev", ] [[package]] name = "pallet-state-trie-migration" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", + "frame-benchmarking 4.0.0-dev", "frame-remote-externalities", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "parking_lot 0.12.1", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-tracing", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "substrate-state-trie-migration-rpc", "thousands", "tokio", @@ -7436,64 +7570,64 @@ dependencies = [ name = "pallet-statement" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-api", - "sp-core", - "sp-io", - "sp-runtime", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", "sp-statement-store", - "sp-std", + "sp-std 8.0.0", ] [[package]] name = "pallet-sudo" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-template" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", ] [[package]] name = "pallet-timestamp" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "parity-scale-codec", "scale-info", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "sp-timestamp", ] @@ -7501,37 +7635,37 @@ dependencies = [ name = "pallet-tips" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "pallet-treasury", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "sp-storage", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", ] [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "parity-scale-codec", "scale-info", "serde", "serde_json", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -7541,12 +7675,12 @@ dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-rpc", - "sp-runtime", - "sp-weights", + "sp-runtime 24.0.0", + "sp-weights 20.0.0", ] [[package]] @@ -7555,9 +7689,9 @@ version = "4.0.0-dev" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", - "sp-api", - "sp-runtime", - "sp-weights", + "sp-api 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-weights 20.0.0", ] [[package]] @@ -7565,19 +7699,19 @@ name = "pallet-transaction-storage" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-inherents", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "sp-transaction-storage-proof", ] @@ -7585,90 +7719,90 @@ dependencies = [ name = "pallet-treasury" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "impl-trait-for-tuples", "pallet-balances", "pallet-utility", "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-uniques" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-utility" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-collective", "pallet-root-testing", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-vesting" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "pallet-whitelist" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking", - "frame-support", - "frame-system", + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "pallet-balances", "pallet-preimage", "parity-scale-codec", "scale-info", - "sp-api", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -8942,8 +9076,8 @@ name = "sc-allocator" version = "4.1.0-dev" dependencies = [ "log", - "sp-core", - "sp-wasm-interface", + "sp-core 21.0.0", + "sp-wasm-interface 14.0.0", "thiserror", ] @@ -8965,13 +9099,13 @@ dependencies = [ "rand 0.8.5", "sc-client-api", "sc-network", - "sp-api", + "sp-api 4.0.0-dev", "sp-authority-discovery", "sp-blockchain", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-tracing", + "sp-core 21.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -8992,12 +9126,12 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-inherents", - "sp-runtime", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", ] @@ -9008,13 +9142,13 @@ version = "0.10.0-dev" dependencies = [ "parity-scale-codec", "sc-client-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "substrate-test-runtime-client", ] @@ -9031,9 +9165,9 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", ] [[package]] @@ -9074,13 +9208,13 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-keystore", - "sp-panic-handler", - "sp-runtime", - "sp-tracing", - "sp-version", + "sp-keystore 0.27.0", + "sp-panic-handler 8.0.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", + "sp-version 22.0.0", "tempfile", "thiserror", "tiny-bip39", @@ -9099,17 +9233,17 @@ dependencies = [ "sc-executor", "sc-transaction-pool-api", "sc-utils", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 21.0.0", "sp-database", - "sp-externalities", - "sp-keystore", - "sp-runtime", - "sp-state-machine", + "sp-externalities 0.19.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-statement-store", - "sp-storage", + "sp-storage 13.0.0", "sp-test-primitives", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -9137,14 +9271,14 @@ dependencies = [ "sc-client-api", "sc-state-db", "schnellru", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-database", - "sp-runtime", - "sp-state-machine", - "sp-tracing", - "sp-trie", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", "substrate-test-runtime-client", "tempfile", ] @@ -9163,12 +9297,12 @@ dependencies = [ "sc-client-api", "sc-utils", "serde", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-test-primitives", "substrate-prometheus-endpoint", "thiserror", @@ -9191,20 +9325,20 @@ dependencies = [ "sc-network", "sc-network-test", "sc-telemetry", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-slots", - "sp-core", - "sp-inherents", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", "sp-keyring", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-timestamp", - "sp-tracing", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -9235,20 +9369,20 @@ dependencies = [ "sc-network-test", "sc-telemetry", "scale-info", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", - "sp-core", - "sp-inherents", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", "sp-keyring", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-timestamp", - "sp-tracing", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9268,15 +9402,15 @@ dependencies = [ "sc-rpc-api", "serde", "serde_json", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-keystore", - "sp-runtime", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9303,19 +9437,19 @@ dependencies = [ "sc-network-test", "sc-utils", "serde", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-arithmetic 16.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-keystore", + "sp-keystore 0.27.0", "sp-mmr-primitives", - "sp-runtime", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -9338,8 +9472,8 @@ dependencies = [ "serde", "serde_json", "sp-consensus-beefy", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9354,7 +9488,7 @@ dependencies = [ "sc-client-api", "sc-consensus", "sp-blockchain", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] @@ -9386,17 +9520,17 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-arithmetic 16.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-keystore", - "sp-runtime", - "sp-tracing", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9419,9 +9553,9 @@ dependencies = [ "serde", "sp-blockchain", "sp-consensus-grandpa", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-runtime", + "sp-runtime 24.0.0", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9447,16 +9581,16 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "serde", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-slots", - "sp-core", - "sp-inherents", - "sp-keystore", - "sp-runtime", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-timestamp", "substrate-prometheus-endpoint", "substrate-test-runtime-client", @@ -9477,14 +9611,14 @@ dependencies = [ "parking_lot 0.12.1", "sc-client-api", "sc-consensus", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-pow", - "sp-core", - "sp-inherents", - "sp-runtime", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", "substrate-prometheus-endpoint", "thiserror", ] @@ -9501,14 +9635,14 @@ dependencies = [ "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "substrate-test-runtime-client", ] @@ -9530,19 +9664,19 @@ dependencies = [ "sc-executor-wasmtime", "sc-runtime-test", "sc-tracing", - "sp-api", - "sp-core", - "sp-externalities", - "sp-io", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-io 23.0.0", "sp-maybe-compressed-blob", - "sp-panic-handler", - "sp-runtime", - "sp-runtime-interface", - "sp-state-machine", - "sp-tracing", - "sp-trie", - "sp-version", - "sp-wasm-interface", + "sp-panic-handler 8.0.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", + "sp-state-machine 0.28.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", + "sp-version 22.0.0", + "sp-wasm-interface 14.0.0", "substrate-test-runtime", "tempfile", "tracing", @@ -9556,7 +9690,7 @@ version = "0.10.0-dev" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface", + "sp-wasm-interface 14.0.0", "thiserror", "wasm-instrument 0.3.0", ] @@ -9576,9 +9710,9 @@ dependencies = [ "sc-allocator", "sc-executor-common", "sc-runtime-test", - "sp-io", - "sp-runtime-interface", - "sp-wasm-interface", + "sp-io 23.0.0", + "sp-runtime-interface 17.0.0", + "sp-wasm-interface 14.0.0", "tempfile", "wasmtime", "wat", @@ -9596,7 +9730,7 @@ dependencies = [ "sc-network", "sc-network-common", "sp-blockchain", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] @@ -9606,9 +9740,9 @@ dependencies = [ "array-bytes 4.2.0", "parking_lot 0.12.1", "serde_json", - "sp-application-crypto", - "sp-core", - "sp-keystore", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-keystore 0.27.0", "tempfile", "thiserror", ] @@ -9646,12 +9780,12 @@ dependencies = [ "serde", "serde_json", "smallvec", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "sp-test-primitives", - "sp-tracing", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime", "substrate-test-runtime-client", @@ -9682,8 +9816,8 @@ dependencies = [ "sc-network", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "substrate-test-runtime", "substrate-test-runtime-client", "thiserror", @@ -9704,7 +9838,7 @@ dependencies = [ "sc-consensus", "sp-consensus", "sp-consensus-grandpa", - "sp-runtime", + "sp-runtime 24.0.0", "tempfile", ] @@ -9721,7 +9855,7 @@ dependencies = [ "quickcheck", "sc-network", "sc-network-common", - "sp-runtime", + "sp-runtime 24.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tokio", @@ -9743,8 +9877,8 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "thiserror", ] @@ -9790,14 +9924,14 @@ dependencies = [ "sc-network-common", "sc-utils", "smallvec", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "sp-test-primitives", - "sp-tracing", + "sp-tracing 10.0.0", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9826,9 +9960,9 @@ dependencies = [ "sc-utils", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-tracing", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-test-runtime", "substrate-test-runtime-client", "tokio", @@ -9847,7 +9981,7 @@ dependencies = [ "sc-network-common", "sc-utils", "sp-consensus", - "sp-runtime", + "sp-runtime 24.0.0", "substrate-prometheus-endpoint", ] @@ -9876,12 +10010,12 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "sc-utils", - "sp-api", + "sp-api 4.0.0-dev", "sp-consensus", - "sp-core", + "sp-core 21.0.0", "sp-offchain", - "sp-runtime", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-test-runtime-client", "threadpool", "tokio", @@ -9918,18 +10052,18 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-io", - "sp-keystore", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", "sp-offchain", "sp-rpc", - "sp-runtime", + "sp-runtime 24.0.0", "sp-session", "sp-statement-store", - "sp-version", + "sp-version 22.0.0", "substrate-test-runtime-client", "tokio", ] @@ -9945,10 +10079,10 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core", + "sp-core 21.0.0", "sp-rpc", - "sp-runtime", - "sp-version", + "sp-runtime 24.0.0", + "sp-version 22.0.0", "thiserror", ] @@ -9987,13 +10121,13 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 21.0.0", "sp-maybe-compressed-blob", - "sp-runtime", - "sp-version", + "sp-runtime 24.0.0", + "sp-version 22.0.0", "substrate-test-runtime", "substrate-test-runtime-client", "thiserror", @@ -10005,11 +10139,11 @@ dependencies = [ name = "sc-runtime-test" version = "2.0.0" dependencies = [ - "sp-core", - "sp-io", - "sp-runtime", - "sp-runtime-interface", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", "substrate-wasm-builder", ] @@ -10054,20 +10188,20 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", "sp-session", - "sp-state-machine", - "sp-storage", + "sp-state-machine 0.28.0", + "sp-storage 13.0.0", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie", - "sp-version", + "sp-trie 22.0.0", + "sp-version 22.0.0", "static_init", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -10099,16 +10233,16 @@ dependencies = [ "sc-network-sync", "sc-service", "sc-transaction-pool-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-io", - "sp-runtime", - "sp-state-machine", - "sp-storage", - "sp-tracing", - "sp-trie", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-storage 13.0.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", "substrate-test-runtime", "substrate-test-runtime-client", "tempfile", @@ -10122,7 +10256,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core", + "sp-core 21.0.0", ] [[package]] @@ -10134,10 +10268,10 @@ dependencies = [ "parity-db", "parking_lot 0.12.1", "sc-client-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "sp-statement-store", "substrate-prometheus-endpoint", "tempfile", @@ -10152,7 +10286,7 @@ dependencies = [ "fs4", "log", "sc-client-db", - "sp-core", + "sp-core 21.0.0", "thiserror", "tokio", ] @@ -10171,7 +10305,7 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-runtime", + "sp-runtime 24.0.0", "thiserror", ] @@ -10188,10 +10322,10 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -10229,12 +10363,12 @@ dependencies = [ "sc-client-api", "sc-tracing-proc-macro", "serde", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", - "sp-core", + "sp-core 21.0.0", "sp-rpc", - "sp-runtime", - "sp-tracing", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "thiserror", "tracing", "tracing-log", @@ -10270,12 +10404,12 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "serde", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-tracing", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "sp-transaction-pool", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -10295,8 +10429,8 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "thiserror", ] @@ -10311,7 +10445,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "prometheus", - "sp-arithmetic", + "sp-arithmetic 16.0.0", "tokio-test", ] @@ -10786,15 +10920,35 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-api-proc-macro", - "sp-core", - "sp-metadata-ir", - "sp-runtime", - "sp-state-machine", - "sp-std", + "sp-api-proc-macro 4.0.0-dev", + "sp-core 21.0.0", + "sp-metadata-ir 0.1.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", "sp-test-primitives", - "sp-trie", - "sp-version", + "sp-trie 22.0.0", + "sp-version 22.0.0", + "thiserror", +] + +[[package]] +name = "sp-api" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "scale-info", + "sp-api-proc-macro 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-metadata-ir 0.1.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", + "sp-version 22.0.0 (git+https://github.com/paritytech/substrate)", "thiserror", ] @@ -10812,6 +10966,20 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "sp-api-proc-macro" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "Inflector", + "blake2", + "expander", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "sp-api-test" version = "2.0.1" @@ -10823,13 +10991,13 @@ dependencies = [ "rustversion", "sc-block-builder", "scale-info", - "sp-api", + "sp-api 4.0.0-dev", "sp-consensus", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-tracing", - "sp-version", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-tracing 10.0.0", + "sp-version 22.0.0", "static_assertions", "substrate-test-runtime-client", "trybuild", @@ -10842,19 +11010,32 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-io", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-application-crypto" +version = "23.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] name = "sp-application-crypto-test" version = "2.0.0" dependencies = [ - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-keystore", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-keystore 0.27.0", "substrate-test-runtime-client", ] @@ -10870,8 +11051,22 @@ dependencies = [ "rand 0.8.5", "scale-info", "serde", - "sp-core", - "sp-std", + "sp-core 21.0.0", + "sp-std 8.0.0", + "static_assertions", +] + +[[package]] +name = "sp-arithmetic" +version = "16.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", "static_assertions", ] @@ -10883,7 +11078,7 @@ dependencies = [ "fraction", "honggfuzz", "num-bigint", - "sp-arithmetic", + "sp-arithmetic 16.0.0", ] [[package]] @@ -10986,20 +11181,20 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api", - "sp-application-crypto", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "sp-block-builder" version = "4.0.0-dev" dependencies = [ - "sp-api", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11011,11 +11206,11 @@ dependencies = [ "lru", "parity-scale-codec", "parking_lot 0.12.1", - "sp-api", + "sp-api 4.0.0-dev", "sp-consensus", "sp-database", - "sp-runtime", - "sp-state-machine", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "thiserror", ] @@ -11026,10 +11221,10 @@ dependencies = [ "async-trait", "futures", "log", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-state-machine", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-test-primitives", "thiserror", ] @@ -11041,12 +11236,12 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-consensus-slots", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "sp-timestamp", ] @@ -11058,13 +11253,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-consensus-slots", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "sp-timestamp", ] @@ -11077,14 +11272,14 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-io", - "sp-keystore", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-keystore 0.27.0", "sp-mmr-primitives", - "sp-runtime", - "sp-std", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "strum", ] @@ -11097,12 +11292,12 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-keystore", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11110,10 +11305,10 @@ name = "sp-consensus-pow" version = "0.10.0-dev" dependencies = [ "parity-scale-codec", - "sp-api", - "sp-core", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11123,7 +11318,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std", + "sp-std 8.0.0", "sp-timestamp", ] @@ -11160,13 +11355,13 @@ dependencies = [ "secrecy", "serde", "serde_json", - "sp-core-hashing", - "sp-core-hashing-proc-macro", - "sp-debug-derive", - "sp-externalities", - "sp-runtime-interface", - "sp-std", - "sp-storage", + "sp-core-hashing 9.0.0", + "sp-core-hashing-proc-macro 9.0.0", + "sp-debug-derive 8.0.0", + "sp-externalities 0.19.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", "ss58-registry", "substrate-bip39", "thiserror", @@ -11175,6 +11370,50 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sp-core" +version = "21.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "array-bytes 6.1.0", + "bitflags", + "blake2", + "bounded-collections", + "bs58", + "dyn-clonable", + "ed25519-zebra", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde", + "lazy_static", + "libsecp256k1", + "log", + "merlin", + "parity-scale-codec", + "parking_lot 0.12.1", + "paste", + "primitive-types", + "rand 0.8.5", + "regex", + "scale-info", + "schnorrkel", + "secp256k1", + "secrecy", + "serde", + "sp-core-hashing 9.0.0 (git+https://github.com/paritytech/substrate)", + "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tiny-bip39", + "zeroize", +] + [[package]] name = "sp-core-hashing" version = "9.0.0" @@ -11187,12 +11426,35 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "sp-core-hashing" +version = "9.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.6", + "sha3", + "twox-hash", +] + [[package]] name = "sp-core-hashing-proc-macro" version = "9.0.0" dependencies = [ "quote", - "sp-core-hashing", + "sp-core-hashing 9.0.0", + "syn 2.0.18", +] + +[[package]] +name = "sp-core-hashing-proc-macro" +version = "9.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "quote", + "sp-core-hashing 9.0.0 (git+https://github.com/paritytech/substrate)", "syn 2.0.18", ] @@ -11218,9 +11480,9 @@ dependencies = [ "sp-ark-ed-on-bls12-377", "sp-ark-ed-on-bls12-381-bandersnatch", "sp-ark-models", - "sp-io", - "sp-runtime-interface", - "sp-std", + "sp-io 23.0.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11240,14 +11502,35 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "sp-debug-derive" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "sp-externalities" version = "0.19.0" dependencies = [ "environmental", "parity-scale-codec", - "sp-std", - "sp-storage", + "sp-std 8.0.0", + "sp-storage 13.0.0", +] + +[[package]] +name = "sp-externalities" +version = "0.19.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] @@ -11255,9 +11538,9 @@ name = "sp-genesis-builder" version = "0.1.0" dependencies = [ "serde_json", - "sp-api", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11269,8 +11552,22 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime", - "sp-std", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "thiserror", +] + +[[package]] +name = "sp-inherents" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "async-trait", + "impl-trait-for-tuples", + "parity-scale-codec", + "scale-info", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", "thiserror", ] @@ -11286,14 +11583,39 @@ dependencies = [ "parity-scale-codec", "rustversion", "secp256k1", - "sp-core", - "sp-externalities", - "sp-keystore", - "sp-runtime-interface", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-trie", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-keystore 0.27.0", + "sp-runtime-interface 17.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-trie 22.0.0", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-io" +version = "23.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "bytes", + "ed25519", + "ed25519-dalek", + "libsecp256k1", + "log", + "parity-scale-codec", + "rustversion", + "secp256k1", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", + "sp-keystore 0.27.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", + "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", + "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", "tracing", "tracing-core", ] @@ -11303,8 +11625,8 @@ name = "sp-keyring" version = "24.0.0" dependencies = [ "lazy_static", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "strum", ] @@ -11316,8 +11638,20 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.7.3", "rand_chacha 0.2.2", - "sp-core", - "sp-externalities", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "thiserror", +] + +[[package]] +name = "sp-keystore" +version = "0.27.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "parity-scale-codec", + "parking_lot 0.12.1", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", "thiserror", ] @@ -11336,7 +11670,18 @@ dependencies = [ "frame-metadata", "parity-scale-codec", "scale-info", - "sp-std", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-metadata-ir" +version = "0.1.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-info", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] @@ -11349,11 +11694,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api", - "sp-core", - "sp-debug-derive", - "sp-runtime", - "sp-std", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-debug-derive 8.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "thiserror", ] @@ -11365,10 +11710,10 @@ dependencies = [ "rand 0.8.5", "scale-info", "serde", - "sp-arithmetic", - "sp-core", - "sp-runtime", - "sp-std", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "substrate-test-utils", ] @@ -11380,21 +11725,31 @@ dependencies = [ "honggfuzz", "rand 0.8.5", "sp-npos-elections", - "sp-runtime", + "sp-runtime 24.0.0", ] [[package]] name = "sp-offchain" version = "4.0.0-dev" dependencies = [ - "sp-api", - "sp-core", - "sp-runtime", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-runtime 24.0.0", +] + +[[package]] +name = "sp-panic-handler" +version = "8.0.0" +dependencies = [ + "backtrace", + "lazy_static", + "regex", ] [[package]] name = "sp-panic-handler" version = "8.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "backtrace", "lazy_static", @@ -11408,7 +11763,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "sp-core", + "sp-core 21.0.0", ] [[package]] @@ -11425,19 +11780,41 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-api", - "sp-application-crypto", - "sp-arithmetic", - "sp-core", - "sp-io", - "sp-state-machine", - "sp-std", - "sp-tracing", - "sp-weights", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", + "sp-weights 20.0.0", "substrate-test-runtime-client", "zstd 0.12.3+zstd.1.5.2", ] +[[package]] +name = "sp-runtime" +version = "24.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "paste", + "rand 0.8.5", + "scale-info", + "serde", + "sp-application-crypto 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", +] + [[package]] name = "sp-runtime-interface" version = "17.0.0" @@ -11447,20 +11824,38 @@ dependencies = [ "parity-scale-codec", "primitive-types", "rustversion", - "sp-core", - "sp-externalities", - "sp-io", - "sp-runtime-interface-proc-macro", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-io 23.0.0", + "sp-runtime-interface-proc-macro 11.0.0", "sp-runtime-interface-test-wasm", - "sp-state-machine", - "sp-std", - "sp-storage", - "sp-tracing", - "sp-wasm-interface", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-storage 13.0.0", + "sp-tracing 10.0.0", + "sp-wasm-interface 14.0.0", "static_assertions", "trybuild", ] +[[package]] +name = "sp-runtime-interface" +version = "17.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "primitive-types", + "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime-interface-proc-macro 11.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", + "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", + "sp-wasm-interface 14.0.0 (git+https://github.com/paritytech/substrate)", + "static_assertions", +] + [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" @@ -11472,18 +11867,30 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "11.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "Inflector", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "sp-runtime-interface-test" version = "2.0.0" dependencies = [ "sc-executor", "sc-executor-common", - "sp-io", - "sp-runtime", - "sp-runtime-interface", + "sp-io 23.0.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", "sp-runtime-interface-test-wasm", "sp-runtime-interface-test-wasm-deprecated", - "sp-state-machine", + "sp-state-machine 0.28.0", "tracing", "tracing-core", ] @@ -11493,10 +11900,10 @@ name = "sp-runtime-interface-test-wasm" version = "2.0.0" dependencies = [ "bytes", - "sp-core", - "sp-io", - "sp-runtime-interface", - "sp-std", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", "substrate-wasm-builder", ] @@ -11504,9 +11911,9 @@ dependencies = [ name = "sp-runtime-interface-test-wasm-deprecated" version = "2.0.0" dependencies = [ - "sp-core", - "sp-io", - "sp-runtime-interface", + "sp-core 21.0.0", + "sp-io 23.0.0", + "sp-runtime-interface 17.0.0", "substrate-wasm-builder", ] @@ -11516,23 +11923,36 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api", - "sp-core", - "sp-runtime", - "sp-staking", - "sp-std", + "sp-api 4.0.0-dev", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-staking 4.0.0-dev", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-staking" +version = "4.0.0-dev" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] name = "sp-staking" version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] @@ -11548,12 +11968,33 @@ dependencies = [ "pretty_assertions", "rand 0.8.5", "smallvec", - "sp-core", - "sp-externalities", - "sp-panic-handler", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-panic-handler 8.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-trie 22.0.0", + "thiserror", + "tracing", + "trie-db", +] + +[[package]] +name = "sp-state-machine" +version = "0.28.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "parking_lot 0.12.1", + "rand 0.8.5", + "smallvec", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", + "sp-panic-handler 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", "thiserror", "tracing", "trie-db", @@ -11565,13 +12006,13 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api", - "sp-application-crypto", - "sp-core", - "sp-externalities", - "sp-runtime", - "sp-runtime-interface", - "sp-std", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-runtime 24.0.0", + "sp-runtime-interface 17.0.0", + "sp-std 8.0.0", "thiserror", ] @@ -11579,6 +12020,11 @@ dependencies = [ name = "sp-std" version = "8.0.0" +[[package]] +name = "sp-std" +version = "8.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" + [[package]] name = "sp-storage" version = "13.0.0" @@ -11587,8 +12033,21 @@ dependencies = [ "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive", - "sp-std", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + +[[package]] +name = "sp-storage" +version = "13.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] @@ -11598,10 +12057,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-application-crypto", - "sp-core", - "sp-runtime", - "sp-std", + "sp-application-crypto 23.0.0", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", ] [[package]] @@ -11610,9 +12069,9 @@ version = "4.0.0-dev" dependencies = [ "async-trait", "parity-scale-codec", - "sp-inherents", - "sp-runtime", - "sp-std", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "thiserror", ] @@ -11621,7 +12080,19 @@ name = "sp-tracing" version = "10.0.0" dependencies = [ "parity-scale-codec", - "sp-std", + "sp-std 8.0.0", + "tracing", + "tracing-core", + "tracing-subscriber 0.2.25", +] + +[[package]] +name = "sp-tracing" +version = "10.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "parity-scale-codec", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -11631,8 +12102,8 @@ dependencies = [ name = "sp-transaction-pool" version = "4.0.0-dev" dependencies = [ - "sp-api", - "sp-runtime", + "sp-api 4.0.0-dev", + "sp-runtime 24.0.0", ] [[package]] @@ -11642,11 +12113,11 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-core", - "sp-inherents", - "sp-runtime", - "sp-std", - "sp-trie", + "sp-core 21.0.0", + "sp-inherents 4.0.0-dev", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-trie 22.0.0", ] [[package]] @@ -11665,9 +12136,9 @@ dependencies = [ "parking_lot 0.12.1", "scale-info", "schnellru", - "sp-core", - "sp-runtime", - "sp-std", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", "thiserror", "tracing", "trie-bench", @@ -11676,6 +12147,29 @@ dependencies = [ "trie-standardmap", ] +[[package]] +name = "sp-trie" +version = "22.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "ahash 0.8.3", + "hash-db", + "hashbrown 0.13.2", + "lazy_static", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot 0.12.1", + "scale-info", + "schnellru", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "thiserror", + "tracing", + "trie-db", + "trie-root", +] + [[package]] name = "sp-version" version = "22.0.0" @@ -11685,21 +12179,49 @@ dependencies = [ "parity-wasm", "scale-info", "serde", - "sp-core-hashing-proc-macro", - "sp-runtime", - "sp-std", - "sp-version-proc-macro", + "sp-core-hashing-proc-macro 9.0.0", + "sp-runtime 24.0.0", + "sp-std 8.0.0", + "sp-version-proc-macro 8.0.0", "thiserror", ] +[[package]] +name = "sp-version" +version = "22.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "impl-serde", + "parity-scale-codec", + "parity-wasm", + "scale-info", + "serde", + "sp-core-hashing-proc-macro 9.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-version-proc-macro 8.0.0 (git+https://github.com/paritytech/substrate)", + "thiserror", +] + +[[package]] +name = "sp-version-proc-macro" +version = "8.0.0" +dependencies = [ + "parity-scale-codec", + "proc-macro2", + "quote", + "sp-version 22.0.0", + "syn 2.0.18", +] + [[package]] name = "sp-version-proc-macro" version = "8.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "sp-version", "syn 2.0.18", ] @@ -11711,22 +12233,50 @@ dependencies = [ "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std", + "sp-std 8.0.0", "wasmtime", ] +[[package]] +name = "sp-wasm-interface" +version = "14.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" +dependencies = [ + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "wasmtime", +] + +[[package]] +name = "sp-weights" +version = "20.0.0" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic 16.0.0", + "sp-core 21.0.0", + "sp-debug-derive 8.0.0", + "sp-std 8.0.0", +] + [[package]] name = "sp-weights" version = "20.0.0" +source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "parity-scale-codec", "scale-info", "serde", "smallvec", - "sp-arithmetic", - "sp-core", - "sp-debug-derive", - "sp-std", + "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", + "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", ] [[package]] @@ -11918,27 +12468,27 @@ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ "clap 4.3.2", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "sc-cli", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", ] [[package]] name = "substrate-frame-rpc-support" version = "3.0.0" dependencies = [ - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "jsonrpsee", "parity-scale-codec", "sc-rpc-api", "scale-info", "serde", - "sp-core", - "sp-runtime", - "sp-storage", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-storage 13.0.0", "tokio", ] @@ -11955,12 +12505,12 @@ dependencies = [ "sc-rpc-api", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api", + "sp-api 4.0.0-dev", "sp-block-builder", "sp-blockchain", - "sp-core", - "sp-runtime", - "sp-tracing", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-tracing 10.0.0", "substrate-test-runtime-client", "tokio", ] @@ -11985,8 +12535,8 @@ dependencies = [ "log", "sc-rpc-api", "serde", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "tokio", ] @@ -12000,10 +12550,10 @@ dependencies = [ "sc-rpc-api", "serde", "serde_json", - "sp-core", - "sp-runtime", - "sp-state-machine", - "sp-trie", + "sp-core 21.0.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", + "sp-trie 22.0.0", "trie-db", ] @@ -12025,11 +12575,11 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-consensus", - "sp-core", + "sp-core 21.0.0", "sp-keyring", - "sp-keystore", - "sp-runtime", - "sp-state-machine", + "sp-keystore 0.27.0", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", ] [[package]] @@ -12038,8 +12588,8 @@ version = "2.0.0" dependencies = [ "array-bytes 6.1.0", "frame-executive", - "frame-support", - "frame-system", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", "frame-system-rpc-runtime-api", "futures", "log", @@ -12051,27 +12601,27 @@ dependencies = [ "sc-executor", "sc-service", "scale-info", - "sp-api", - "sp-application-crypto", + "sp-api 4.0.0-dev", + "sp-application-crypto 23.0.0", "sp-block-builder", "sp-consensus", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core", - "sp-externalities", - "sp-inherents", - "sp-io", + "sp-core 21.0.0", + "sp-externalities 0.19.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", "sp-keyring", "sp-offchain", - "sp-runtime", + "sp-runtime 24.0.0", "sp-session", - "sp-state-machine", - "sp-std", - "sp-tracing", + "sp-state-machine 0.28.0", + "sp-std 8.0.0", + "sp-tracing 10.0.0", "sp-transaction-pool", - "sp-trie", - "sp-version", + "sp-trie 22.0.0", + "sp-version 22.0.0", "substrate-test-runtime-client", "substrate-wasm-builder", "trie-db", @@ -12085,11 +12635,11 @@ dependencies = [ "sc-block-builder", "sc-client-api", "sc-consensus", - "sp-api", + "sp-api 4.0.0-dev", "sp-blockchain", "sp-consensus", - "sp-core", - "sp-runtime", + "sp-core 21.0.0", + "sp-runtime 24.0.0", "substrate-test-client", "substrate-test-runtime", ] @@ -12104,7 +12654,7 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "sp-blockchain", - "sp-runtime", + "sp-runtime 24.0.0", "substrate-test-runtime-client", "thiserror", ] @@ -12839,22 +13389,22 @@ dependencies = [ "sc-executor", "serde", "serde_json", - "sp-api", + "sp-api 4.0.0-dev", "sp-consensus-aura", "sp-consensus-babe", - "sp-core", - "sp-debug-derive", - "sp-externalities", - "sp-inherents", - "sp-io", - "sp-keystore", + "sp-core 21.0.0", + "sp-debug-derive 8.0.0", + "sp-externalities 0.19.0", + "sp-inherents 4.0.0-dev", + "sp-io 23.0.0", + "sp-keystore 0.27.0", "sp-rpc", - "sp-runtime", - "sp-state-machine", + "sp-runtime 24.0.0", + "sp-state-machine 0.28.0", "sp-timestamp", "sp-transaction-storage-proof", - "sp-version", - "sp-weights", + "sp-version 22.0.0", + "sp-weights 20.0.0", "substrate-cli-test-utils", "substrate-rpc-client", "tempfile", diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index 8e08f583ca4f4..f0909ae5bbfc3 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive"] } scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } bitvec = "1" - +sp-std = { version = "8.0.0", git = "https://github.com/paritytech/substrate" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate" } frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index a4aa1907ef501..cf8691d848355 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -23,6 +23,8 @@ pub use pallet::*; mod mock; mod tests; mod benchmarking; +mod test_fungibles; +mod types; pub mod weights; pub use weights::WeightInfo; @@ -30,10 +32,10 @@ pub use weights::WeightInfo; #[frame_support::pallet] pub mod pallet { use super::*; - use bitvec::BitArr; use frame_support::{pallet_prelude::*, traits::fungible::{self, Inspect, Mutate, MutateHold}}; use frame_system::pallet_prelude::*; use sp_runtime::AccountId32; + use types::CorePart; #[pallet::pallet] pub struct Pallet(_); @@ -52,8 +54,6 @@ pub mod pallet { pub type Timeslice = u32; pub type CoreIndex = u16; - // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. - pub type CorePart = [u8; 10]; pub type RelayAccountId = AccountId32; pub type Balance = u128; pub type ParaId = u32; @@ -149,7 +149,6 @@ pub mod pallet { } } - // Errors inform users that something went wrong. #[pallet::error] pub enum Error { UnknownRegion, @@ -167,7 +166,6 @@ pub mod pallet { } impl Pallet { - /// Logic for call `Self::change_value`. pub(crate) fn do_transfer(region_id: RegionId, maybe_check_owner: Option, new_owner: T::AccountId) -> Result<(), Error> { let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; @@ -182,5 +180,17 @@ pub mod pallet { Ok(()) } + + pub(crate) fn issue( + core: CoreIndex, + begin: Timeslice, + length: Timeslice, + owner: T::AccountId, + ) -> Result<(), Error> { + let id = RegionId { begin, core, part: CorePart::all_set() }; + let record = RegionRecord { end: begin + length, owner }; + Regions::::insert(id, record); + Ok(()) + } } } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index ff8815f6f635d..ac6719bf389da 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -17,15 +17,13 @@ #![cfg(test)] -use frame_support::{ - parameter_types, - traits::{ConstU16, ConstU64, fungibles, fungible::ItemOf, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} -}; -use sp_core::{H256, Get, ConstU32, TypedGet}; +use frame_support::traits::fungible::ItemOf; +use sp_core::{H256, Get, ConstU64, ConstU16}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; +use crate::test_fungibles::TestFungibles; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -69,97 +67,6 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } -pub struct TestFungibles(core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance)>); - -use std::collections::HashMap; - -parameter_types! { - static TestAssetOf: HashMap<(u32, Vec), Vec> = Default::default(); - static TestBalanceOf: HashMap<(u32, Vec, Vec), Vec> = Default::default(); -} - -use codec::{Encode, Decode}; -impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, -> fungibles::Inspect for TestFungibles -where - MinimumBalance::Type: tokens::Balance, - -{ - type AssetId = AssetId; - type Balance = MinimumBalance::Type; - - fn total_issuance(asset: Self::AssetId) -> Self::Balance { - TestAssetOf::get().get(&(Instance::get(), asset.encode())) - .and_then(|data| Decode::decode(&mut &data[..]).ok()) - .unwrap_or_default() - } - - fn active_issuance(asset: Self::AssetId) -> Self::Balance { - Self::total_issuance(asset) - } - - /// The minimum balance any single account may have. - fn minimum_balance(asset: Self::AssetId) -> Self::Balance { - MinimumBalance::get() - } - - fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { - TestBalanceOf::get().get(&(Instance::get(), asset.encode(), who.encode())) - .and_then(|data| Decode::decode(&mut &data[..]).ok()) - .unwrap_or_default() - } - - fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { - Self::total_balance(asset, who) - } - - fn reducible_balance( - asset: Self::AssetId, - who: &AccountId, - _preservation: Preservation, - _force: Fortitude, - ) -> Self::Balance { - Self::total_balance(asset, who) - } - - fn can_deposit( - asset: Self::AssetId, - who: &AccountId, - amount: Self::Balance, - _provenance: Provenance, - ) -> DepositConsequence { - if !Self::asset_exists(asset) { - return DepositConsequence::UnknownAsset; - } - if amount + Self::balance(asset, who) < Self::minimum_balance(asset) { - return DepositConsequence::BelowMinimum; - } - DepositConsequence::Success - } - - fn can_withdraw( - asset: Self::AssetId, - who: &AccountId, - amount: Self::Balance, - ) -> WithdrawConsequence { - if Self::reducible_balance(asset, who, Preservation::Expendable, Fortitude::Polite) < amount { - return WithdrawConsequence::BalanceLow; - } - if Self::total_balance(asset, who) < Self::minimum_balance(asset) + amount { - return WithdrawConsequence::WouldDie; - } - WithdrawConsequence::Success - } - - fn asset_exists(asset: Self::AssetId) -> bool { - TestAssetOf::get().contains_key(&(Instance::get(), asset.encode())) - } -} - impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf>, (), u64>; diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 78679ae6fa9f0..af23adedb2c4a 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -22,10 +22,7 @@ use frame_support::{assert_noop, assert_ok}; #[test] fn bitvec_size() { - use bitvec::BitArr; - type CoreParts = BitArr!(for 80, in u8); new_test_ext().execute_with(|| { - println!("{}", core::mem::size_of::()); - panic!(); + }); } From fd58ded734fda211046d368e5390c16e61ff5b53 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 8 Jul 2023 18:56:10 +0200 Subject: [PATCH 003/131] Repotting and fleshing out --- frame/broker/src/test_fungibles.rs | 111 +++++++++++++++++++++++++++++ frame/broker/src/types.rs | 79 ++++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 frame/broker/src/test_fungibles.rs create mode 100644 frame/broker/src/types.rs diff --git a/frame/broker/src/test_fungibles.rs b/frame/broker/src/test_fungibles.rs new file mode 100644 index 0000000000000..c4347e083a73b --- /dev/null +++ b/frame/broker/src/test_fungibles.rs @@ -0,0 +1,111 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use frame_support::{ + parameter_types, + traits::{ConstU16, ConstU64, fungibles, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} +}; +use sp_std::collections::btree_map::BTreeMap; +use codec::{Encode, Decode}; +use sp_core::{ConstU32, TypedGet, Get}; + +parameter_types! { + static TestAssetOf: BTreeMap<(u32, Vec), Vec> = Default::default(); + static TestBalanceOf: BTreeMap<(u32, Vec, Vec), Vec> = Default::default(); +} + +pub struct TestFungibles(core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance)>); +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, +> fungibles::Inspect for TestFungibles +where + MinimumBalance::Type: tokens::Balance, + +{ + type AssetId = AssetId; + type Balance = MinimumBalance::Type; + + fn total_issuance(asset: Self::AssetId) -> Self::Balance { + TestAssetOf::get().get(&(Instance::get(), asset.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() + } + + fn active_issuance(asset: Self::AssetId) -> Self::Balance { + Self::total_issuance(asset) + } + + /// The minimum balance any single account may have. + fn minimum_balance(asset: Self::AssetId) -> Self::Balance { + MinimumBalance::get() + } + + fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + TestBalanceOf::get().get(&(Instance::get(), asset.encode(), who.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() + } + + fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + Self::total_balance(asset, who) + } + + fn reducible_balance( + asset: Self::AssetId, + who: &AccountId, + _preservation: Preservation, + _force: Fortitude, + ) -> Self::Balance { + Self::total_balance(asset, who) + } + + fn can_deposit( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + _provenance: Provenance, + ) -> DepositConsequence { + if !Self::asset_exists(asset) { + return DepositConsequence::UnknownAsset; + } + if amount + Self::balance(asset, who) < Self::minimum_balance(asset) { + return DepositConsequence::BelowMinimum; + } + DepositConsequence::Success + } + + fn can_withdraw( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> WithdrawConsequence { + if Self::reducible_balance(asset, who, Preservation::Expendable, Fortitude::Polite) < amount { + return WithdrawConsequence::BalanceLow; + } + if Self::total_balance(asset, who) < Self::minimum_balance(asset) + amount { + return WithdrawConsequence::WouldDie; + } + WithdrawConsequence::Success + } + + fn asset_exists(asset: Self::AssetId) -> bool { + TestAssetOf::get().contains_key(&(Instance::get(), asset.encode())) + } +} diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs new file mode 100644 index 0000000000000..284c9b45b9fdb --- /dev/null +++ b/frame/broker/src/types.rs @@ -0,0 +1,79 @@ +use codec::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_core::RuntimeDebug; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign}; + +// TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct CorePart([u8; 10]); +impl CorePart { + pub fn all_unset() -> Self { + return Self([0u8; 10]) + } + pub fn all_set() -> Self { + return Self([255u8; 10]) + } + pub fn is_complete(&self) -> bool { + return &self.0 == &[255u8; 10] + } + pub fn is_empty(&self) -> bool { + return &self.0 == &[0u8; 10] + } + pub fn count_zeros(&self) -> u32 { + self.0.iter().map(|i| i.count_zeros()).sum() + } + pub fn count_ones(&self) -> u32 { + self.0.iter().map(|i| i.count_ones()).sum() + } +} +impl BitAnd for CorePart { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitand(rhs.0[i]); + } + Self(result) + } +} +impl BitAndAssign for CorePart { + fn bitand_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitand_assign(rhs.0[i]); + } + } +} +impl BitOr for CorePart { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitor(rhs.0[i]); + } + Self(result) + } +} +impl BitOrAssign for CorePart { + fn bitor_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitor_assign(rhs.0[i]); + } + } +} +impl BitXor for CorePart { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitxor(rhs.0[i]); + } + Self(result) + } +} +impl BitXorAssign for CorePart { + fn bitxor_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitxor_assign(rhs.0[i]); + } + } +} From 4d085c1ed8d9260a437d5eed5d8164c8d6d48bd7 Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 00:23:54 +0200 Subject: [PATCH 004/131] more drafting --- Cargo.lock | 1 + frame/broker/Cargo.toml | 1 + frame/broker/src/lib.rs | 233 +++++++++++++++++++++++++++++++++++++- frame/broker/src/mock.rs | 10 +- frame/broker/src/types.rs | 30 +++-- 5 files changed, 257 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f94c214a88363..45fa1f1a56495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6417,6 +6417,7 @@ dependencies = [ "frame-system 4.0.0-dev (git+https://github.com/paritytech/substrate)", "parity-scale-codec", "scale-info", + "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index f0909ae5bbfc3..2ed280f24f094 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -16,6 +16,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } bitvec = "1" sp-std = { version = "8.0.0", git = "https://github.com/paritytech/substrate" } +sp-arithmetic = { version = "16.0.0", git = "https://github.com/paritytech/substrate" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate" } frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index cf8691d848355..90f3807ecac09 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -34,24 +34,82 @@ pub mod pallet { use super::*; use frame_support::{pallet_prelude::*, traits::fungible::{self, Inspect, Mutate, MutateHold}}; use frame_system::pallet_prelude::*; - use sp_runtime::AccountId32; + use sp_runtime::{AccountId32, traits::{ConvertBack, Convert}, DispatchError}; + use sp_arithmetic::traits::{AtLeast32BitUnsigned, SaturatedConversion, Saturating}; use types::CorePart; #[pallet::pallet] pub struct Pallet(_); + pub type PartsOf57600 = u16; + pub enum CoreAssignment { + InstantaneousPool, + Task(ParaId), + } + pub trait CoretimeInterface { + type AccountId: Parameter; + type Balance; + type BlockNumber: AtLeast32BitUnsigned + TypeInfo + Encode; + fn latest() -> Self::BlockNumber; + fn request_core_count(count: CoreIndex); + fn request_revenue_at(when: Self::BlockNumber); + fn credit_account(who: Self::AccountId, amount: Balance); + fn assign_core( + core: CoreIndex, + begin: Self::BlockNumber, + assignment: Vec<(CoreAssignment, PartsOf57600)>, + end_hint: Option, + ); + fn check_notify_core_count() -> Option; + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)>; + } + impl CoretimeInterface for () { + type AccountId = (); + type Balance = u64; + type BlockNumber = u32; + fn latest() -> Self::BlockNumber { 0 } + fn request_core_count(_count: CoreIndex) {} + fn request_revenue_at(_when: Self::BlockNumber) {} + fn credit_account(_who: Self::AccountId, _amount: Balance) {} + fn assign_core( + _core: CoreIndex, + _begin: Self::BlockNumber, + _assignment: Vec<(CoreAssignment, PartsOf57600)>, + _end_hint: Option, + ) {} + fn check_notify_core_count() -> Option { None } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } + } + #[pallet::config] pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type Currency: Inspect;//Mutate + MutateHold; + /// Number of Relay-chain blocks ahead of time which we fix and notify of core assignments. + #[pallet::constant] + type AdvanceNotice: Get>; + + /// Number of Relay-chain blocks per timeslice. + #[pallet::constant] + type TimeslicePeriod: Get>; + + /// Reversible conversion from local balance to Relay-chain balance. + type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; + + /// Relay chain's Coretime API + type Coretime: CoretimeInterface; + /// Weight information for all calls of this pallet. type WeightInfo: WeightInfo; } pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; + pub type RelayBalanceOf = <::Coretime as CoretimeInterface>::Balance; + pub type RelayBlockNumberOf = <::Coretime as CoretimeInterface>::BlockNumber; + // Relay-chain block number divided by 80. pub type Timeslice = u32; pub type CoreIndex = u16; pub type RelayAccountId = AccountId32; @@ -80,7 +138,7 @@ pub mod pallet { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum CoreTask { Off, - Assigned { target: ParaId }, + Assigned(ParaId), InstaPool, } @@ -103,7 +161,7 @@ pub mod pallet { begin: Timeslice, end: Timeslice, core: CoreIndex, - parts: CorePart, + part: CorePart, payee: Contributor, } pub type ContributionRecordOf = ContributionRecord<::AccountId>; @@ -146,13 +204,45 @@ pub mod pallet { region_id: RegionId, old_owner: T::AccountId, owner: T::AccountId, - } + }, + Partitioned { + region_id: RegionId, + pivot: Timeslice, + new_region_id: RegionId, + }, + Interlaced { + region_id: RegionId, + pivot: CorePart, + }, + Assigned { + region_id: RegionId, + task: ParaId, + }, + Dropped { + region_id: RegionId, + }, + Pooled { + region_id: RegionId, + }, } #[pallet::error] pub enum Error { UnknownRegion, NotOwner, + PivotTooEarly, + PivotTooLate, + ExteriorPivot, + NullPivot, + CompletePivot, + CorruptWorkplan, + } + + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_initialize(now: T::BlockNumber) -> Weight { + Weight::zero() + } } #[pallet::call(weight(::WeightInfo))] @@ -166,6 +256,15 @@ pub mod pallet { } impl Pallet { + pub(crate) fn next_timeslice() -> Timeslice { + let latest = T::Coretime::latest(); + let advance = T::AdvanceNotice::get(); + let timeslice_period = T::TimeslicePeriod::get(); + let last_scheduled = (latest + advance) / timeslice_period; + let mut next_scheduled: Timeslice = last_scheduled.saturated_into(); + next_scheduled.saturating_add(1) + } + pub(crate) fn do_transfer(region_id: RegionId, maybe_check_owner: Option, new_owner: T::AccountId) -> Result<(), Error> { let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; @@ -181,13 +280,137 @@ pub mod pallet { Ok(()) } + pub(crate) fn do_partition( + region_id: RegionId, + maybe_check_owner: Option, + pivot: Timeslice, + ) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + ensure!(pivot > region_id.begin, Error::::PivotTooEarly); + ensure!(pivot < region.end, Error::::PivotTooLate); + + let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; + let new_region = RegionRecord { end: pivot, ..region.clone() }; + + Regions::::insert(®ion_id, &new_region); + Regions::::insert(&new_region_id, ®ion); + Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); + + Ok(()) + } + + pub(crate) fn do_interlace( + mut region_id: RegionId, + maybe_check_owner: Option, + pivot: CorePart, + ) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); + ensure!(!pivot.is_void(), Error::::NullPivot); + ensure!(pivot != region_id.part, Error::::CompletePivot); + + let antipivot = region_id.part ^ pivot; + region_id.part = pivot; + Regions::::insert(®ion_id, ®ion); + region_id.part = antipivot; + Regions::::insert(®ion_id, ®ion); + + Self::deposit_event(Event::Interlaced { region_id, pivot }); + + Ok(()) + } + + pub(crate) fn utilize( + mut region_id: RegionId, + maybe_check_owner: Option, + ) -> Result)>, Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + let next_timeslice = Self::next_timeslice(); + if region_id.begin > next_timeslice { + region_id.begin = next_timeslice; + } + Regions::::remove(®ion_id); + + if region_id.begin < region.end { + Ok(Some((region_id, region))) + } else { + Self::deposit_event(Event::Dropped { region_id }); + Ok(None) + } + } + + pub(crate) fn do_assign( + region_id: RegionId, + maybe_check_owner: Option, + target: ParaId, + ) -> Result<(), Error> { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + task: CoreTask::Assigned(target), + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + } + Self::deposit_event(Event::Assigned { region_id, task: target }); + } + Ok(()) + } + + pub(crate) fn do_pool( + region_id: RegionId, + maybe_check_owner: Option, + payee: T::AccountId, + ) -> Result<(), Error> { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + task: CoreTask::InstaPool, + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + InstaPoolIo::::mutate(region_id.begin, |a| *a += region_id.part.count_ones() as i32); + InstaPoolIo::::mutate(region.end, |a| *a -= region_id.part.count_ones() as i32); + let contrib = ContributionRecord { + begin: region_id.begin, + end: region.end, + core: region_id.core, + part: region_id.part, + payee: Contributor::Private(payee), + }; + InstaPoolContribution::::insert(&contrib, ()); + } + Self::deposit_event(Event::Pooled { region_id }); + } + Ok(()) + } + pub(crate) fn issue( core: CoreIndex, begin: Timeslice, length: Timeslice, owner: T::AccountId, ) -> Result<(), Error> { - let id = RegionId { begin, core, part: CorePart::all_set() }; + let id = RegionId { begin, core, part: CorePart::complete() }; let record = RegionRecord { end: begin + length, owner }; Regions::::insert(id, record); Ok(()) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index ac6719bf389da..57453fc8a5cf0 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -17,11 +17,11 @@ #![cfg(test)] -use frame_support::traits::fungible::ItemOf; -use sp_core::{H256, Get, ConstU64, ConstU16}; +use frame_support::{traits::fungible::ItemOf}; +use sp_core::{H256, Get, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup}, + traits::{BlakeTwo256, IdentityLookup, Identity}, }; use crate::test_fungibles::TestFungibles; @@ -70,6 +70,10 @@ impl frame_system::Config for Test { impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf>, (), u64>; + type TimeslicePeriod = ConstU32<80>; + type AdvanceNotice = (); + type Coretime = (); + type ConvertBalance = Identity; type WeightInfo = (); } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 284c9b45b9fdb..f0efecbbdf917 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,23 +1,23 @@ use codec::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::RuntimeDebug; -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct CorePart([u8; 10]); impl CorePart { - pub fn all_unset() -> Self { - return Self([0u8; 10]) + pub fn void() -> Self { + Self([0u8; 10]) } - pub fn all_set() -> Self { - return Self([255u8; 10]) + pub fn complete() -> Self { + Self([255u8; 10]) } - pub fn is_complete(&self) -> bool { - return &self.0 == &[255u8; 10] + pub fn is_void(&self) -> bool { + &self.0 == &[0u8; 10] } - pub fn is_empty(&self) -> bool { - return &self.0 == &[0u8; 10] + pub fn is_complete(&self) -> bool { + &self.0 == &[255u8; 10] } pub fn count_zeros(&self) -> u32 { self.0.iter().map(|i| i.count_zeros()).sum() @@ -77,3 +77,13 @@ impl BitXorAssign for CorePart { } } } +impl Not for CorePart { + type Output = Self; + fn not(self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].not(); + } + Self(result) + } +} From 7a42089409643665ac886f6b1fab7d01c10594d6 Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 10:15:37 +0200 Subject: [PATCH 005/131] process timeslice --- frame/broker/src/lib.rs | 111 +++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 90f3807ecac09..916a0bb7deb5e 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -29,6 +29,13 @@ mod types; pub mod weights; pub use weights::WeightInfo; +/* TODO: +- Purchase and renewal +- Advance notice & on_initialize +- Initialization +- Pool rewards +*/ + #[frame_support::pallet] pub mod pallet { use super::*; @@ -42,22 +49,27 @@ pub mod pallet { pub struct Pallet(_); pub type PartsOf57600 = u16; + + #[derive(Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum CoreAssignment { - InstantaneousPool, + Idle, + Pool, Task(ParaId), } + pub type WholeCoreAssignment = Vec<(CoreAssignment, PartsOf57600)>; + pub trait CoretimeInterface { type AccountId: Parameter; type Balance; - type BlockNumber: AtLeast32BitUnsigned + TypeInfo + Encode; + type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode; fn latest() -> Self::BlockNumber; fn request_core_count(count: CoreIndex); - fn request_revenue_at(when: Self::BlockNumber); + fn request_revenue_info_at(when: Self::BlockNumber); fn credit_account(who: Self::AccountId, amount: Balance); fn assign_core( core: CoreIndex, begin: Self::BlockNumber, - assignment: Vec<(CoreAssignment, PartsOf57600)>, + assignment: WholeCoreAssignment, end_hint: Option, ); fn check_notify_core_count() -> Option; @@ -69,7 +81,7 @@ pub mod pallet { type BlockNumber = u32; fn latest() -> Self::BlockNumber { 0 } fn request_core_count(_count: CoreIndex) {} - fn request_revenue_at(_when: Self::BlockNumber) {} + fn request_revenue_info_at(_when: Self::BlockNumber) {} fn credit_account(_who: Self::AccountId, _amount: Balance) {} fn assign_core( _core: CoreIndex, @@ -134,18 +146,10 @@ pub mod pallet { } pub type RegionRecordOf = RegionRecord<::AccountId>; - // TODO: Use a more specialised 32-bit type which puts Off and InstaPool into unused 32-bit values. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub enum CoreTask { - Off, - Assigned(ParaId), - InstaPool, - } - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ScheduleItem { part: CorePart, - task: CoreTask, + assignment: CoreAssignment, } pub type Schedule = BoundedVec>; @@ -173,6 +177,13 @@ pub mod pallet { } pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct StatusRecord { + core_count: CoreIndex, + pool_size: PartCount, + last_timeslice: Timeslice, + } + #[pallet::storage] pub type Regions = StorageMap<_, Blake2_128Concat, RegionId, RegionRecordOf, OptionQuery>; @@ -182,10 +193,10 @@ pub mod pallet { /// The current workload of each core. This gets updated with workplan as timeslices pass. #[pallet::storage] - pub type Workload = StorageMap<_, Twox64Concat, CoreIndex, Schedule, OptionQuery>; + pub type Workload = StorageMap<_, Twox64Concat, CoreIndex, Schedule, ValueQuery>; #[pallet::storage] - pub type InstaPoolSize = StorageValue<_, PartCount, ValueQuery>; + pub type Status = StorageValue<_, StatusRecord, OptionQuery>; #[pallet::storage] pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, ContributionRecordOf, (), OptionQuery>; @@ -265,6 +276,70 @@ pub mod pallet { next_scheduled.saturating_add(1) } + pub(crate) fn process_timeslice(timeslice: Timeslice) { + let mut status = match Status::::get() { + Some(s) => s, + None => return, + }; + Self::process_pool(timeslice, &mut status); + let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); + for core in 0..status.core_count { + Self::process_core_schedule(timeslice, rc_begin, core, &mut status); + } + Status::::put(status); + } + + fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { + let pool_io = InstaPoolIo::::take(timeslice); + status.pool_size = (status.pool_size as i32).saturating_add(pool_io) as u32; + let record = InstaPoolHistoryRecord { + total_contributions: status.pool_size, + maybe_payout: None, + }; + InstaPoolHistory::::insert(timeslice, record); + } + + /// Schedule cores for the given `timeslice`. + fn process_core_schedule( + timeslice: Timeslice, + rc_begin: RelayBlockNumberOf, + core: CoreIndex, + status: &mut StatusRecord, + ) { + let mut workplan = match Workplan::::take((timeslice, core)) { + Some(w) => w, + None => return, + }; + let workload = Workload::::get(core); + let parts_used = workplan.iter().map(|i| i.part).fold(CorePart::void(), |a, i| a | i); + let mut workplan = workplan.into_inner(); + workplan.extend(workload.into_iter().filter(|i| (i.part & parts_used).is_void())); + let workplan = Schedule::truncate_from(workplan); + Workload::::insert(core, &workplan); + + let mut total_used = 0; + let mut intermediate = workplan + .into_iter() + .map(|i| (i.assignment, i.part.count_ones() as u16 * (57_600 / 80))) + .inspect(|i| total_used += i.1) + .collect::>(); + if total_used < 80 { + intermediate.push((CoreAssignment::Idle, 80 - total_used)); + } + intermediate.sort(); + let mut assignment: WholeCoreAssignment = Vec::with_capacity(intermediate.len()); + for i in intermediate.into_iter() { + if let Some(ref mut last) = assignment.last_mut() { + if last.0 == i.0 { + last.1 += i.1; + continue; + } + } + assignment.push(i); + } + T::Coretime::assign_core(core, rc_begin, assignment, None); + } + pub(crate) fn do_transfer(region_id: RegionId, maybe_check_owner: Option, new_owner: T::AccountId) -> Result<(), Error> { let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; @@ -365,7 +440,7 @@ pub mod pallet { .unwrap_or_default(); if workplan.try_push(ScheduleItem { part: region_id.part, - task: CoreTask::Assigned(target), + assignment: CoreAssignment::Task(target), }).is_ok() { Workplan::::insert(&workplan_key, &workplan); } @@ -385,7 +460,7 @@ pub mod pallet { .unwrap_or_default(); if workplan.try_push(ScheduleItem { part: region_id.part, - task: CoreTask::InstaPool, + assignment: CoreAssignment::Pool, }).is_ok() { Workplan::::insert(&workplan_key, &workplan); InstaPoolIo::::mutate(region_id.begin, |a| *a += region_id.part.count_ones() as i32); From c17ef175457b793fa887579e9d69a5c6d8bceb3a Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 12:02:22 +0200 Subject: [PATCH 006/131] Test Fungibles completed --- Cargo.lock | 3070 +++++++---------- frame/broker/Cargo.toml | 16 +- frame/broker/src/mock.rs | 2 +- frame/broker/src/test_fungibles.rs | 156 +- .../src/traits/tokens/fungible/hold.rs | 10 +- .../src/traits/tokens/fungibles/hold.rs | 12 +- 6 files changed, 1444 insertions(+), 1822 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45fa1f1a56495..7ecec4f4fdd1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -826,8 +826,8 @@ dependencies = [ "env_logger 0.9.3", "hash-db", "log", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", ] [[package]] @@ -1186,8 +1186,8 @@ dependencies = [ "rand 0.8.5", "sc-chain-spec", "sc-keystore", - "sp-core 21.0.0", - "sp-keystore 0.27.0", + "sp-core", + "sp-keystore", ] [[package]] @@ -2614,9 +2614,9 @@ name = "frame-benchmarking" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-support 4.0.0-dev", - "frame-support-procedural 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-support-procedural", + "frame-system", "linregress", "log", "parity-scale-codec", @@ -2624,40 +2624,15 @@ dependencies = [ "rusty-fork", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "static_assertions", -] - -[[package]] -name = "frame-benchmarking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "frame-support-procedural 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "frame-system 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "linregress", - "log", - "parity-scale-codec", - "paste", - "scale-info", - "serde", - "sp-api 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "sp-application-crypto 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-runtime-interface", + "sp-std", + "sp-storage", "static_assertions", ] @@ -2670,9 +2645,9 @@ dependencies = [ "chrono", "clap 4.3.2", "comfy-table", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "gethostname", "handlebars", "itertools", @@ -2691,19 +2666,19 @@ dependencies = [ "sc-sysinfo", "serde", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-database", - "sp-externalities 0.19.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-storage 13.0.0", - "sp-trie 22.0.0", - "sp-wasm-interface 14.0.0", + "sp-externalities", + "sp-inherents", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "sp-trie", + "sp-wasm-interface", "thiserror", "thousands", ] @@ -2712,14 +2687,14 @@ dependencies = [ name = "frame-benchmarking-pallet-pov" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -2727,13 +2702,13 @@ name = "frame-election-provider-solution-type" version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support 4.0.0-dev", + "frame-support", "parity-scale-codec", "proc-macro-crate", "proc-macro2", "quote", "scale-info", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "syn 2.0.18", "trybuild", ] @@ -2743,17 +2718,17 @@ name = "frame-election-provider-support" version = "4.0.0-dev" dependencies = [ "frame-election-provider-solution-type", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-runtime", + "sp-std", ] [[package]] @@ -2763,14 +2738,14 @@ dependencies = [ "clap 4.3.2", "frame-election-provider-solution-type", "frame-election-provider-support", - "frame-support 4.0.0-dev", + "frame-support", "honggfuzz", "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "sp-npos-elections", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] @@ -2778,20 +2753,20 @@ name = "frame-executive" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "frame-try-runtime", "pallet-balances", "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-version 22.0.0", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", + "sp-version", ] [[package]] @@ -2811,7 +2786,7 @@ name = "frame-remote-externalities" version = "0.10.0-dev" dependencies = [ "async-recursion", - "frame-support 4.0.0-dev", + "frame-support", "futures", "indicatif", "jsonrpsee", @@ -2819,9 +2794,9 @@ dependencies = [ "pallet-elections-phragmen", "parity-scale-codec", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", "spinners", "substrate-rpc-client", "tokio", @@ -2838,8 +2813,8 @@ dependencies = [ "bitflags", "environmental", "frame-metadata", - "frame-support-procedural 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support-procedural", + "frame-system", "impl-trait-for-tuples", "k256", "log", @@ -2851,53 +2826,19 @@ dependencies = [ "serde", "serde_json", "smallvec", - "sp-api 4.0.0-dev", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-core-hashing-proc-macro 9.0.0", - "sp-debug-derive 8.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-weights 20.0.0", - "tt-call", -] - -[[package]] -name = "frame-support" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "bitflags", - "environmental", - "frame-metadata", - "frame-support-procedural 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "impl-trait-for-tuples", - "k256", - "log", - "macro_magic", - "parity-scale-codec", - "paste", - "scale-info", - "serde", - "smallvec", - "sp-api 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core-hashing-proc-macro 9.0.0 (git+https://github.com/paritytech/substrate)", - "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-inherents 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-staking 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", - "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-core-hashing-proc-macro", + "sp-debug-derive", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-weights", "tt-call", ] @@ -2909,7 +2850,7 @@ dependencies = [ "cfg-expr", "derive-syn-parse", "expander", - "frame-support-procedural-tools 4.0.0-dev", + "frame-support-procedural-tools", "itertools", "macro_magic", "proc-macro-warning", @@ -2918,41 +2859,11 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "frame-support-procedural" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "Inflector", - "cfg-expr", - "derive-syn-parse", - "expander", - "frame-support-procedural-tools 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "itertools", - "macro_magic", - "proc-macro-warning", - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "frame-support-procedural-tools" -version = "4.0.0-dev" -dependencies = [ - "frame-support-procedural-tools-derive 3.0.0", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "frame-support-procedural-tools" version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ - "frame-support-procedural-tools-derive 3.0.0 (git+https://github.com/paritytech/substrate)", + "frame-support-procedural-tools-derive", "proc-macro-crate", "proc-macro2", "quote", @@ -2968,38 +2879,28 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "frame-support-procedural-tools-derive" -version = "3.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "frame-support-test" version = "3.0.0" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-executive", - "frame-support 4.0.0-dev", + "frame-support", "frame-support-test-pallet", - "frame-system 4.0.0-dev", + "frame-system", "parity-scale-codec", "pretty_assertions", "rustversion", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-version 22.0.0", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-std", + "sp-version", "static_assertions", "trybuild", ] @@ -3008,21 +2909,21 @@ dependencies = [ name = "frame-support-test-compile-pass" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-version 22.0.0", + "sp-core", + "sp-runtime", + "sp-version", ] [[package]] name = "frame-support-test-pallet" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", "serde", @@ -3034,55 +2935,36 @@ version = "4.0.0-dev" dependencies = [ "cfg-if", "criterion", - "frame-support 4.0.0-dev", + "frame-support", "log", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-version 22.0.0", - "sp-weights 20.0.0", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", + "sp-weights", "substrate-test-runtime-client", ] -[[package]] -name = "frame-system" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "cfg-if", - "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "log", - "parity-scale-codec", - "scale-info", - "serde", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-version 22.0.0 (git+https://github.com/paritytech/substrate)", - "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", -] - [[package]] name = "frame-system-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-version 22.0.0", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime", + "sp-std", + "sp-version", ] [[package]] @@ -3090,18 +2972,18 @@ name = "frame-system-rpc-runtime-api" version = "4.0.0-dev" dependencies = [ "parity-scale-codec", - "sp-api 4.0.0-dev", + "sp-api", ] [[package]] name = "frame-try-runtime" version = "0.10.0-dev" dependencies = [ - "frame-support 4.0.0-dev", + "frame-support", "parity-scale-codec", - "sp-api 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-runtime", + "sp-std", ] [[package]] @@ -3279,8 +3161,8 @@ version = "4.0.0-dev" dependencies = [ "chrono", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "num-format", "pallet-staking", ] @@ -4160,12 +4042,12 @@ dependencies = [ name = "kitchensink-runtime" version = "3.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-benchmarking-pallet-pov", "frame-election-provider-support", "frame-executive", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", @@ -4245,22 +4127,22 @@ dependencies = [ "parity-scale-codec", "primitive-types", "scale-info", - "sp-api 4.0.0-dev", + "sp-api", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", + "sp-core", + "sp-inherents", + "sp-io", "sp-offchain", - "sp-runtime 24.0.0", + "sp-runtime", "sp-session", - "sp-staking 4.0.0-dev", + "sp-staking", "sp-statement-store", - "sp-std 8.0.0", + "sp-std", "sp-transaction-pool", - "sp-version 22.0.0", + "sp-version", "static_assertions", "substrate-wasm-builder", ] @@ -5189,14 +5071,14 @@ dependencies = [ "sc-block-builder", "sc-client-api", "sc-offchain", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", - "sp-core 21.0.0", + "sp-core", "sp-mmr-primitives", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-tracing", "substrate-test-runtime-client", "tokio", ] @@ -5210,11 +5092,11 @@ dependencies = [ "parity-scale-codec", "serde", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-mmr-primitives", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] @@ -5492,13 +5374,13 @@ dependencies = [ "serde", "serde_json", "sp-consensus", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", "sp-timestamp", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", + "sp-tracing", + "sp-trie", "tempfile", ] @@ -5512,7 +5394,7 @@ dependencies = [ "clap_complete", "criterion", "frame-benchmarking-cli", - "frame-system 4.0.0-dev", + "frame-system", "frame-system-rpc-runtime-api", "futures", "jsonrpsee", @@ -5564,21 +5446,21 @@ dependencies = [ "serde", "serde_json", "soketto", - "sp-api 4.0.0-dev", + "sp-api", "sp-authority-discovery", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", + "sp-core", + "sp-inherents", + "sp-io", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-keystore", + "sp-runtime", "sp-statement-store", "sp-timestamp", - "sp-tracing 10.0.0", + "sp-tracing", "sp-transaction-storage-proof", "substrate-build-script-utils", "substrate-cli-test-utils", @@ -5596,9 +5478,9 @@ name = "node-executor" version = "3.0.0-dev" dependencies = [ "criterion", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "futures", "kitchensink-runtime", "node-primitives", @@ -5615,17 +5497,17 @@ dependencies = [ "parity-scale-codec", "sc-executor", "scale-info", - "sp-application-crypto 23.0.0", + "sp-application-crypto", "sp-consensus-babe", - "sp-core 21.0.0", - "sp-externalities 0.19.0", + "sp-core", + "sp-externalities", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-keystore", + "sp-runtime", + "sp-state-machine", "sp-statement-store", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", + "sp-tracing", + "sp-trie", "wat", ] @@ -5639,8 +5521,8 @@ dependencies = [ "sc-client-api", "sc-service", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -5648,8 +5530,8 @@ dependencies = [ name = "node-primitives" version = "2.0.0" dependencies = [ - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", ] [[package]] @@ -5671,13 +5553,13 @@ dependencies = [ "sc-rpc-spec-v2", "sc-sync-state-rpc", "sc-transaction-pool-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-keystore", + "sp-runtime", "sp-statement-store", "substrate-frame-rpc-system", "substrate-state-trie-migration-rpc", @@ -5697,9 +5579,9 @@ name = "node-template" version = "4.0.0-dev" dependencies = [ "clap 4.3.2", - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-benchmarking-cli", - "frame-system 4.0.0-dev", + "frame-system", "futures", "jsonrpsee", "node-template-runtime", @@ -5718,16 +5600,16 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", + "sp-core", + "sp-inherents", + "sp-io", "sp-keyring", - "sp-runtime 24.0.0", + "sp-runtime", "sp-timestamp", "substrate-build-script-utils", "substrate-frame-rpc-system", @@ -5752,10 +5634,10 @@ dependencies = [ name = "node-template-runtime" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-executive", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "frame-system-benchmarking", "frame-system-rpc-runtime-api", "frame-try-runtime", @@ -5769,18 +5651,18 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-consensus-aura", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", + "sp-core", + "sp-inherents", "sp-offchain", - "sp-runtime 24.0.0", + "sp-runtime", "sp-session", - "sp-std 8.0.0", + "sp-std", "sp-transaction-pool", - "sp-version 22.0.0", + "sp-version", "substrate-wasm-builder", ] @@ -5788,7 +5670,7 @@ dependencies = [ name = "node-testing" version = "3.0.0-dev" dependencies = [ - "frame-system 4.0.0-dev", + "frame-system", "fs_extra", "futures", "kitchensink-runtime", @@ -5806,15 +5688,15 @@ dependencies = [ "sc-consensus", "sc-executor", "sc-service", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", + "sp-core", + "sp-inherents", + "sp-io", "sp-keyring", - "sp-runtime 24.0.0", + "sp-runtime", "sp-timestamp", "substrate-test-client", "tempfile", @@ -6073,84 +5955,84 @@ name = "pallet-alliance" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-collective", "pallet-identity", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-core-hashing 9.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-core-hashing", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-asset-conversion" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-assets", "pallet-balances", "parity-scale-codec", "primitive-types", "scale-info", - "sp-api 4.0.0-dev", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-asset-conversion-tx-payment" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-transaction-payment", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", ] [[package]] name = "pallet-asset-rate" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-asset-tx-payment" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-assets", "pallet-authorship", "pallet-balances", @@ -6159,101 +6041,101 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", ] [[package]] name = "pallet-assets" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-atomic-swap" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-aura" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 23.0.0", + "sp-application-crypto", "sp-consensus-aura", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-authority-discovery" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto 23.0.0", + "sp-application-crypto", "sp-authority-discovery", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-authorship" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-babe" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-authorship", "pallet-balances", @@ -6264,33 +6146,33 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 23.0.0", + "sp-application-crypto", "sp-consensus-babe", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-bags-list" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", ] [[package]] @@ -6309,34 +6191,34 @@ version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", "frame-remote-externalities", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-bags-list", "pallet-staking", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-runtime", + "sp-std", + "sp-storage", + "sp-tracing", ] [[package]] name = "pallet-balances" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-transaction-payment", "parity-scale-codec", "paste", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6344,8 +6226,8 @@ name = "pallet-beefy" version = "4.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-authorship", "pallet-balances", "pallet-offences", @@ -6357,12 +6239,12 @@ dependencies = [ "scale-info", "serde", "sp-consensus-beefy", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-staking", + "sp-std", ] [[package]] @@ -6371,8 +6253,8 @@ version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", "binary-merkle-tree", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-beefy", "pallet-mmr", @@ -6380,31 +6262,31 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api 4.0.0-dev", + "sp-api", "sp-consensus-beefy", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-bounties" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6412,51 +6294,51 @@ name = "pallet-broker" version = "0.1.0" dependencies = [ "bitvec", - "frame-benchmarking 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "frame-support 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "frame-system 4.0.0-dev (git+https://github.com/paritytech/substrate)", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-child-bounties" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-bounties", "pallet-treasury", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-collective" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6468,9 +6350,9 @@ dependencies = [ "bitflags", "env_logger 0.9.3", "environmental", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "impl-trait-for-tuples", "log", "pallet-balances", @@ -6487,12 +6369,12 @@ dependencies = [ "scale-info", "serde", "smallvec", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-core", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-std", "wasm-instrument 0.4.0", "wasmi", "wasmparser-nostd", @@ -6506,9 +6388,9 @@ dependencies = [ "bitflags", "parity-scale-codec", "scale-info", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-weights 20.0.0", + "sp-runtime", + "sp-std", + "sp-weights", ] [[package]] @@ -6525,58 +6407,58 @@ name = "pallet-conviction-voting" version = "4.0.0-dev" dependencies = [ "assert_matches", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "pallet-scheduler", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-core-fellowship" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-default-config-example" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-democracy" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-preimage", @@ -6584,26 +6466,26 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-dev-mode" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6611,8 +6493,8 @@ name = "pallet-election-provider-e2e-test" version = "1.0.0" dependencies = [ "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-bags-list", "pallet-balances", @@ -6622,23 +6504,23 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", ] [[package]] name = "pallet-election-provider-multi-phase" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-election-provider-support-benchmarking", @@ -6646,13 +6528,13 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-std", + "sp-tracing", "strum", ] @@ -6660,31 +6542,31 @@ dependencies = [ name = "pallet-election-provider-support-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-system 4.0.0-dev", + "frame-system", "parity-scale-codec", "sp-npos-elections", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] name = "pallet-elections-phragmen" version = "5.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-std", + "sp-tracing", "substrate-test-utils", ] @@ -6692,66 +6574,66 @@ dependencies = [ name = "pallet-example-basic" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-example-kitchensink" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-example-offchain-worker" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "lite-json", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-example-split" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-std", ] [[package]] @@ -6771,10 +6653,10 @@ name = "pallet-fast-unstake" version = "4.0.0-dev" dependencies = [ "docify", - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-staking", @@ -6782,12 +6664,12 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", "substrate-test-utils", ] @@ -6796,17 +6678,17 @@ name = "pallet-glutton" version = "4.0.0-dev" dependencies = [ "blake2", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -6814,10 +6696,10 @@ name = "pallet-grandpa" version = "4.0.0-dev" dependencies = [ "finality-grandpa", - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-authorship", "pallet-balances", @@ -6828,15 +6710,15 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-application-crypto 23.0.0", + "sp-application-crypto", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-core", + "sp-io", "sp-keyring", - "sp-runtime 24.0.0", + "sp-runtime", "sp-session", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-staking", + "sp-std", ] [[package]] @@ -6844,123 +6726,123 @@ name = "pallet-identity" version = "4.0.0-dev" dependencies = [ "enumflags2", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-im-online" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-authorship", "pallet-session", "parity-scale-codec", "scale-info", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-indices" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-core", + "sp-io", "sp-keyring", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-insecure-randomness-collective-flip" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "parity-scale-codec", "safe-mix", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-lottery" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", + "frame-benchmarking", + "frame-support", "frame-support-test", - "frame-system 4.0.0-dev", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-membership" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-message-queue" version = "7.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "rand 0.8.5", "rand_distr", "scale-info", "serde", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-weights 20.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", + "sp-weights", ] [[package]] @@ -6969,53 +6851,53 @@ version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", "env_logger 0.9.3", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "itertools", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-core", + "sp-io", "sp-mmr-primitives", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-multisig" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-nft-fractionalization" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-assets", "pallet-balances", "pallet-nfts", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7023,103 +6905,103 @@ name = "pallet-nfts" version = "4.0.0-dev" dependencies = [ "enumflags2", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-keystore", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-nfts-runtime-api" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", + "frame-support", "pallet-nfts", "parity-scale-codec", - "sp-api 4.0.0-dev", + "sp-api", ] [[package]] name = "pallet-nicks" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-nis" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-node-authorization" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-nomination-pools" version = "1.0.0" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", ] [[package]] name = "pallet-nomination-pools-benchmarking" version = "1.0.0" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-bags-list", "pallet-balances", "pallet-nomination-pools", @@ -7128,27 +7010,27 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-nomination-pools-fuzzer" version = "2.0.0" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "honggfuzz", "log", "pallet-nomination-pools", "rand 0.8.5", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-io", + "sp-runtime", + "sp-tracing", ] [[package]] @@ -7157,8 +7039,8 @@ version = "1.0.0-dev" dependencies = [ "pallet-nomination-pools", "parity-scale-codec", - "sp-api 4.0.0-dev", - "sp-std 8.0.0", + "sp-api", + "sp-std", ] [[package]] @@ -7166,8 +7048,8 @@ name = "pallet-nomination-pools-test-staking" version = "1.0.0" dependencies = [ "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-bags-list", "pallet-balances", @@ -7177,40 +7059,40 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", ] [[package]] name = "pallet-offences" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-offences-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-babe", "pallet-balances", @@ -7223,78 +7105,78 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-preimage" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-proxy" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "pallet-utility", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-ranked-collective" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-recovery" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7302,9 +7184,9 @@ name = "pallet-referenda" version = "4.0.0-dev" dependencies = [ "assert_matches", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-preimage", @@ -7312,27 +7194,27 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-remark" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7340,8 +7222,8 @@ name = "pallet-root-offences" version = "1.0.0-dev" dependencies = [ "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "pallet-session", "pallet-staking", @@ -7349,60 +7231,60 @@ dependencies = [ "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] name = "pallet-root-testing" version = "1.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-salary" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-scheduler" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-preimage", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-weights 20.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-weights", "substrate-test-utils", ] @@ -7410,45 +7292,45 @@ dependencies = [ name = "pallet-scored-pool" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-session" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "impl-trait-for-tuples", "log", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-trie 22.0.0", + "sp-staking", + "sp-std", + "sp-trie", ] [[package]] name = "pallet-session-benchmarking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "pallet-session", "pallet-staking", @@ -7457,42 +7339,42 @@ dependencies = [ "parity-scale-codec", "rand 0.8.5", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", "sp-session", - "sp-std 8.0.0", + "sp-std", ] [[package]] name = "pallet-society" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", + "frame-benchmarking", + "frame-support", "frame-support-test", - "frame-system 4.0.0-dev", + "frame-system", "hex-literal", "log", "pallet-balances", "parity-scale-codec", "rand_chacha 0.2.2", "scale-info", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-staking" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-election-provider-support", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-authorship", "pallet-bags-list", @@ -7504,14 +7386,14 @@ dependencies = [ "rand_chacha 0.2.2", "scale-info", "serde", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", + "sp-application-crypto", + "sp-core", + "sp-io", "sp-npos-elections", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-staking", + "sp-std", + "sp-tracing", "substrate-test-utils", ] @@ -7522,7 +7404,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "sp-runtime 24.0.0", + "sp-runtime", "syn 2.0.18", ] @@ -7531,7 +7413,7 @@ name = "pallet-staking-reward-fn" version = "4.0.0-dev" dependencies = [ "log", - "sp-arithmetic 16.0.0", + "sp-arithmetic", ] [[package]] @@ -7539,28 +7421,28 @@ name = "pallet-staking-runtime-api" version = "4.0.0-dev" dependencies = [ "parity-scale-codec", - "sp-api 4.0.0-dev", + "sp-api", ] [[package]] name = "pallet-state-trie-migration" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", + "frame-benchmarking", "frame-remote-externalities", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "parking_lot 0.12.1", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-tracing", "substrate-state-trie-migration-rpc", "thousands", "tokio", @@ -7571,64 +7453,64 @@ dependencies = [ name = "pallet-statement" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-api", + "sp-core", + "sp-io", + "sp-runtime", "sp-statement-store", - "sp-std 8.0.0", + "sp-std", ] [[package]] name = "pallet-sudo" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-template" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-io", + "sp-runtime", ] [[package]] name = "pallet-timestamp" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -7636,37 +7518,37 @@ dependencies = [ name = "pallet-tips" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "pallet-treasury", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "sp-storage", ] [[package]] name = "pallet-transaction-payment" version = "4.0.0-dev" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "pallet-balances", "parity-scale-codec", "scale-info", "serde", "serde_json", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -7676,12 +7558,12 @@ dependencies = [ "jsonrpsee", "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-rpc", - "sp-runtime 24.0.0", - "sp-weights 20.0.0", + "sp-runtime", + "sp-weights", ] [[package]] @@ -7690,9 +7572,9 @@ version = "4.0.0-dev" dependencies = [ "pallet-transaction-payment", "parity-scale-codec", - "sp-api 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-weights 20.0.0", + "sp-api", + "sp-runtime", + "sp-weights", ] [[package]] @@ -7700,19 +7582,19 @@ name = "pallet-transaction-storage" version = "4.0.0-dev" dependencies = [ "array-bytes 4.2.0", - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-inherents", + "sp-io", + "sp-runtime", + "sp-std", "sp-transaction-storage-proof", ] @@ -7720,90 +7602,90 @@ dependencies = [ name = "pallet-treasury" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "impl-trait-for-tuples", "pallet-balances", "pallet-utility", "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-uniques" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-utility" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "pallet-collective", "pallet-root-testing", "pallet-timestamp", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-vesting" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "log", "pallet-balances", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] name = "pallet-whitelist" version = "4.0.0-dev" dependencies = [ - "frame-benchmarking 4.0.0-dev", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-benchmarking", + "frame-support", + "frame-system", "pallet-balances", "pallet-preimage", "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -9077,8 +8959,8 @@ name = "sc-allocator" version = "4.1.0-dev" dependencies = [ "log", - "sp-core 21.0.0", - "sp-wasm-interface 14.0.0", + "sp-core", + "sp-wasm-interface", "thiserror", ] @@ -9100,13 +8982,13 @@ dependencies = [ "rand 0.8.5", "sc-client-api", "sc-network", - "sp-api 4.0.0-dev", + "sp-api", "sp-authority-discovery", "sp-blockchain", - "sp-core 21.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9127,12 +9009,12 @@ dependencies = [ "sc-telemetry", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", + "sp-core", + "sp-inherents", + "sp-runtime", "substrate-prometheus-endpoint", "substrate-test-runtime-client", ] @@ -9143,13 +9025,13 @@ version = "0.10.0-dev" dependencies = [ "parity-scale-codec", "sc-client-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", "substrate-test-runtime-client", ] @@ -9166,9 +9048,9 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -9209,13 +9091,13 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.27.0", - "sp-panic-handler 8.0.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", - "sp-version 22.0.0", + "sp-keystore", + "sp-panic-handler", + "sp-runtime", + "sp-tracing", + "sp-version", "tempfile", "thiserror", "tiny-bip39", @@ -9234,17 +9116,17 @@ dependencies = [ "sc-executor", "sc-transaction-pool-api", "sc-utils", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", + "sp-core", "sp-database", - "sp-externalities 0.19.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-externalities", + "sp-keystore", + "sp-runtime", + "sp-state-machine", "sp-statement-store", - "sp-storage 13.0.0", + "sp-storage", "sp-test-primitives", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -9272,14 +9154,14 @@ dependencies = [ "sc-client-api", "sc-state-db", "schnellru", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-database", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", + "sp-runtime", + "sp-state-machine", + "sp-tracing", + "sp-trie", "substrate-test-runtime-client", "tempfile", ] @@ -9298,12 +9180,12 @@ dependencies = [ "sc-client-api", "sc-utils", "serde", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-runtime", + "sp-state-machine", "sp-test-primitives", "substrate-prometheus-endpoint", "thiserror", @@ -9326,20 +9208,20 @@ dependencies = [ "sc-network", "sc-network-test", "sc-telemetry", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-slots", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", + "sp-core", + "sp-inherents", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-keystore", + "sp-runtime", "sp-timestamp", - "sp-tracing 10.0.0", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -9370,20 +9252,20 @@ dependencies = [ "sc-network-test", "sc-telemetry", "scale-info", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-babe", "sp-consensus-slots", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", + "sp-core", + "sp-inherents", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-keystore", + "sp-runtime", "sp-timestamp", - "sp-tracing 10.0.0", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9403,15 +9285,15 @@ dependencies = [ "sc-rpc-api", "serde", "serde_json", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-blockchain", "sp-consensus", "sp-consensus-babe", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-keystore", + "sp-runtime", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9438,19 +9320,19 @@ dependencies = [ "sc-network-test", "sc-utils", "serde", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-arithmetic 16.0.0", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-beefy", "sp-consensus-grandpa", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.27.0", + "sp-keystore", "sp-mmr-primitives", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tempfile", @@ -9473,8 +9355,8 @@ dependencies = [ "serde", "serde_json", "sp-consensus-beefy", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9489,7 +9371,7 @@ dependencies = [ "sc-client-api", "sc-consensus", "sp-blockchain", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] @@ -9521,17 +9403,17 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-arithmetic 16.0.0", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-keystore", + "sp-runtime", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9554,9 +9436,9 @@ dependencies = [ "serde", "sp-blockchain", "sp-consensus-grandpa", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-runtime 24.0.0", + "sp-runtime", "substrate-test-runtime-client", "thiserror", "tokio", @@ -9582,16 +9464,16 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "serde", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-slots", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-inherents", + "sp-keystore", + "sp-runtime", "sp-timestamp", "substrate-prometheus-endpoint", "substrate-test-runtime-client", @@ -9612,14 +9494,14 @@ dependencies = [ "parking_lot 0.12.1", "sc-client-api", "sc-consensus", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", "sp-consensus", "sp-consensus-pow", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", + "sp-core", + "sp-inherents", + "sp-runtime", "substrate-prometheus-endpoint", "thiserror", ] @@ -9636,14 +9518,14 @@ dependencies = [ "sc-client-api", "sc-consensus", "sc-telemetry", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-slots", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", "substrate-test-runtime-client", ] @@ -9665,19 +9547,19 @@ dependencies = [ "sc-executor-wasmtime", "sc-runtime-test", "sc-tracing", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-io 23.0.0", + "sp-api", + "sp-core", + "sp-externalities", + "sp-io", "sp-maybe-compressed-blob", - "sp-panic-handler 8.0.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", - "sp-state-machine 0.28.0", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", - "sp-version 22.0.0", - "sp-wasm-interface 14.0.0", + "sp-panic-handler", + "sp-runtime", + "sp-runtime-interface", + "sp-state-machine", + "sp-tracing", + "sp-trie", + "sp-version", + "sp-wasm-interface", "substrate-test-runtime", "tempfile", "tracing", @@ -9691,7 +9573,7 @@ version = "0.10.0-dev" dependencies = [ "sc-allocator", "sp-maybe-compressed-blob", - "sp-wasm-interface 14.0.0", + "sp-wasm-interface", "thiserror", "wasm-instrument 0.3.0", ] @@ -9711,9 +9593,9 @@ dependencies = [ "sc-allocator", "sc-executor-common", "sc-runtime-test", - "sp-io 23.0.0", - "sp-runtime-interface 17.0.0", - "sp-wasm-interface 14.0.0", + "sp-io", + "sp-runtime-interface", + "sp-wasm-interface", "tempfile", "wasmtime", "wat", @@ -9731,7 +9613,7 @@ dependencies = [ "sc-network", "sc-network-common", "sp-blockchain", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] @@ -9741,9 +9623,9 @@ dependencies = [ "array-bytes 4.2.0", "parking_lot 0.12.1", "serde_json", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-keystore 0.27.0", + "sp-application-crypto", + "sp-core", + "sp-keystore", "tempfile", "thiserror", ] @@ -9781,12 +9663,12 @@ dependencies = [ "serde", "serde_json", "smallvec", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "sp-test-primitives", - "sp-tracing 10.0.0", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime", "substrate-test-runtime-client", @@ -9817,8 +9699,8 @@ dependencies = [ "sc-network", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "substrate-test-runtime", "substrate-test-runtime-client", "thiserror", @@ -9839,7 +9721,7 @@ dependencies = [ "sc-consensus", "sp-consensus", "sp-consensus-grandpa", - "sp-runtime 24.0.0", + "sp-runtime", "tempfile", ] @@ -9856,7 +9738,7 @@ dependencies = [ "quickcheck", "sc-network", "sc-network-common", - "sp-runtime 24.0.0", + "sp-runtime", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "tokio", @@ -9878,8 +9760,8 @@ dependencies = [ "sc-client-api", "sc-network", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -9925,14 +9807,14 @@ dependencies = [ "sc-network-common", "sc-utils", "smallvec", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "sp-blockchain", "sp-consensus", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "sp-test-primitives", - "sp-tracing 10.0.0", + "sp-tracing", "substrate-prometheus-endpoint", "substrate-test-runtime-client", "thiserror", @@ -9961,9 +9843,9 @@ dependencies = [ "sc-utils", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-runtime", + "sp-tracing", "substrate-test-runtime", "substrate-test-runtime-client", "tokio", @@ -9982,7 +9864,7 @@ dependencies = [ "sc-network-common", "sc-utils", "sp-consensus", - "sp-runtime 24.0.0", + "sp-runtime", "substrate-prometheus-endpoint", ] @@ -10011,12 +9893,12 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "sc-utils", - "sp-api 4.0.0-dev", + "sp-api", "sp-consensus", - "sp-core 21.0.0", + "sp-core", "sp-offchain", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-tracing", "substrate-test-runtime-client", "threadpool", "tokio", @@ -10053,18 +9935,18 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", + "sp-core", + "sp-io", + "sp-keystore", "sp-offchain", "sp-rpc", - "sp-runtime 24.0.0", + "sp-runtime", "sp-session", "sp-statement-store", - "sp-version 22.0.0", + "sp-version", "substrate-test-runtime-client", "tokio", ] @@ -10080,10 +9962,10 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-core 21.0.0", + "sp-core", "sp-rpc", - "sp-runtime 24.0.0", - "sp-version 22.0.0", + "sp-runtime", + "sp-version", "thiserror", ] @@ -10122,13 +10004,13 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", + "sp-core", "sp-maybe-compressed-blob", - "sp-runtime 24.0.0", - "sp-version 22.0.0", + "sp-runtime", + "sp-version", "substrate-test-runtime", "substrate-test-runtime-client", "thiserror", @@ -10140,11 +10022,11 @@ dependencies = [ name = "sc-runtime-test" version = "2.0.0" dependencies = [ - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-runtime-interface", + "sp-std", "substrate-wasm-builder", ] @@ -10189,20 +10071,20 @@ dependencies = [ "sc-utils", "serde", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime", "sp-session", - "sp-state-machine 0.28.0", - "sp-storage 13.0.0", + "sp-state-machine", + "sp-storage", "sp-transaction-pool", "sp-transaction-storage-proof", - "sp-trie 22.0.0", - "sp-version 22.0.0", + "sp-trie", + "sp-version", "static_init", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -10234,16 +10116,16 @@ dependencies = [ "sc-network-sync", "sc-service", "sc-transaction-pool-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-storage 13.0.0", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-state-machine", + "sp-storage", + "sp-tracing", + "sp-trie", "substrate-test-runtime", "substrate-test-runtime-client", "tempfile", @@ -10257,7 +10139,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot 0.12.1", - "sp-core 21.0.0", + "sp-core", ] [[package]] @@ -10269,10 +10151,10 @@ dependencies = [ "parity-db", "parking_lot 0.12.1", "sc-client-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "sp-statement-store", "substrate-prometheus-endpoint", "tempfile", @@ -10287,7 +10169,7 @@ dependencies = [ "fs4", "log", "sc-client-db", - "sp-core 21.0.0", + "sp-core", "thiserror", "tokio", ] @@ -10306,7 +10188,7 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-runtime 24.0.0", + "sp-runtime", "thiserror", ] @@ -10323,10 +10205,10 @@ dependencies = [ "sc-telemetry", "serde", "serde_json", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", ] [[package]] @@ -10364,12 +10246,12 @@ dependencies = [ "sc-client-api", "sc-tracing-proc-macro", "serde", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", - "sp-core 21.0.0", + "sp-core", "sp-rpc", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-runtime", + "sp-tracing", "thiserror", "tracing", "tracing-log", @@ -10405,12 +10287,12 @@ dependencies = [ "sc-transaction-pool-api", "sc-utils", "serde", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-runtime", + "sp-tracing", "sp-transaction-pool", "substrate-prometheus-endpoint", "substrate-test-runtime", @@ -10430,8 +10312,8 @@ dependencies = [ "serde", "serde_json", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "thiserror", ] @@ -10446,7 +10328,7 @@ dependencies = [ "log", "parking_lot 0.12.1", "prometheus", - "sp-arithmetic 16.0.0", + "sp-arithmetic", "tokio-test", ] @@ -10921,35 +10803,15 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "sp-api-proc-macro 4.0.0-dev", - "sp-core 21.0.0", - "sp-metadata-ir 0.1.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", + "sp-api-proc-macro", + "sp-core", + "sp-metadata-ir", + "sp-runtime", + "sp-state-machine", + "sp-std", "sp-test-primitives", - "sp-trie 22.0.0", - "sp-version 22.0.0", - "thiserror", -] - -[[package]] -name = "sp-api" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "hash-db", - "log", - "parity-scale-codec", - "scale-info", - "sp-api-proc-macro 4.0.0-dev (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-metadata-ir 0.1.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", - "sp-version 22.0.0 (git+https://github.com/paritytech/substrate)", + "sp-trie", + "sp-version", "thiserror", ] @@ -10967,20 +10829,6 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "sp-api-proc-macro" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "Inflector", - "blake2", - "expander", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "sp-api-test" version = "2.0.1" @@ -10992,13 +10840,13 @@ dependencies = [ "rustversion", "sc-block-builder", "scale-info", - "sp-api 4.0.0-dev", + "sp-api", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-tracing 10.0.0", - "sp-version 22.0.0", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-tracing", + "sp-version", "static_assertions", "substrate-test-runtime-client", "trybuild", @@ -11011,32 +10859,19 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-std 8.0.0", -] - -[[package]] -name = "sp-application-crypto" -version = "23.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-io", + "sp-std", ] [[package]] name = "sp-application-crypto-test" version = "2.0.0" dependencies = [ - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-keystore 0.27.0", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-keystore", "substrate-test-runtime-client", ] @@ -11052,22 +10887,8 @@ dependencies = [ "rand 0.8.5", "scale-info", "serde", - "sp-core 21.0.0", - "sp-std 8.0.0", - "static_assertions", -] - -[[package]] -name = "sp-arithmetic" -version = "16.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "integer-sqrt", - "num-traits", - "parity-scale-codec", - "scale-info", - "serde", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-std", "static_assertions", ] @@ -11079,7 +10900,7 @@ dependencies = [ "fraction", "honggfuzz", "num-bigint", - "sp-arithmetic 16.0.0", + "sp-arithmetic", ] [[package]] @@ -11182,20 +11003,20 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-application-crypto", + "sp-runtime", + "sp-std", ] [[package]] name = "sp-block-builder" version = "4.0.0-dev" dependencies = [ - "sp-api 4.0.0-dev", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-inherents", + "sp-runtime", + "sp-std", ] [[package]] @@ -11207,11 +11028,11 @@ dependencies = [ "lru", "parity-scale-codec", "parking_lot 0.12.1", - "sp-api 4.0.0-dev", + "sp-api", "sp-consensus", "sp-database", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-runtime", + "sp-state-machine", "thiserror", ] @@ -11222,10 +11043,10 @@ dependencies = [ "async-trait", "futures", "log", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-state-machine", "sp-test-primitives", "thiserror", ] @@ -11237,12 +11058,12 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-consensus-slots", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-inherents", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -11254,13 +11075,13 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-consensus-slots", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-std", "sp-timestamp", ] @@ -11273,14 +11094,14 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-keystore 0.27.0", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-io", + "sp-keystore", "sp-mmr-primitives", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-runtime", + "sp-std", "strum", ] @@ -11293,12 +11114,12 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-keystore", + "sp-runtime", + "sp-std", ] [[package]] @@ -11306,10 +11127,10 @@ name = "sp-consensus-pow" version = "0.10.0-dev" dependencies = [ "parity-scale-codec", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -11319,7 +11140,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-std 8.0.0", + "sp-std", "sp-timestamp", ] @@ -11356,13 +11177,13 @@ dependencies = [ "secrecy", "serde", "serde_json", - "sp-core-hashing 9.0.0", - "sp-core-hashing-proc-macro 9.0.0", - "sp-debug-derive 8.0.0", - "sp-externalities 0.19.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", + "sp-core-hashing", + "sp-core-hashing-proc-macro", + "sp-debug-derive", + "sp-externalities", + "sp-runtime-interface", + "sp-std", + "sp-storage", "ss58-registry", "substrate-bip39", "thiserror", @@ -11371,50 +11192,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "sp-core" -version = "21.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "array-bytes 6.1.0", - "bitflags", - "blake2", - "bounded-collections", - "bs58", - "dyn-clonable", - "ed25519-zebra", - "futures", - "hash-db", - "hash256-std-hasher", - "impl-serde", - "lazy_static", - "libsecp256k1", - "log", - "merlin", - "parity-scale-codec", - "parking_lot 0.12.1", - "paste", - "primitive-types", - "rand 0.8.5", - "regex", - "scale-info", - "schnorrkel", - "secp256k1", - "secrecy", - "serde", - "sp-core-hashing 9.0.0 (git+https://github.com/paritytech/substrate)", - "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", - "ss58-registry", - "substrate-bip39", - "thiserror", - "tiny-bip39", - "zeroize", -] - [[package]] name = "sp-core-hashing" version = "9.0.0" @@ -11427,35 +11204,12 @@ dependencies = [ "twox-hash", ] -[[package]] -name = "sp-core-hashing" -version = "9.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "blake2b_simd", - "byteorder", - "digest 0.10.7", - "sha2 0.10.6", - "sha3", - "twox-hash", -] - -[[package]] -name = "sp-core-hashing-proc-macro" -version = "9.0.0" -dependencies = [ - "quote", - "sp-core-hashing 9.0.0", - "syn 2.0.18", -] - [[package]] name = "sp-core-hashing-proc-macro" version = "9.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "quote", - "sp-core-hashing 9.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core-hashing", "syn 2.0.18", ] @@ -11481,9 +11235,9 @@ dependencies = [ "sp-ark-ed-on-bls12-377", "sp-ark-ed-on-bls12-381-bandersnatch", "sp-ark-models", - "sp-io 23.0.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", + "sp-io", + "sp-runtime-interface", + "sp-std", ] [[package]] @@ -11503,35 +11257,14 @@ dependencies = [ "syn 2.0.18", ] -[[package]] -name = "sp-debug-derive" -version = "8.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "sp-externalities" -version = "0.19.0" -dependencies = [ - "environmental", - "parity-scale-codec", - "sp-std 8.0.0", - "sp-storage 13.0.0", -] - [[package]] name = "sp-externalities" version = "0.19.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "environmental", "parity-scale-codec", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std", + "sp-storage", ] [[package]] @@ -11539,9 +11272,9 @@ name = "sp-genesis-builder" version = "0.1.0" dependencies = [ "serde_json", - "sp-api 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-runtime", + "sp-std", ] [[package]] @@ -11553,22 +11286,8 @@ dependencies = [ "impl-trait-for-tuples", "parity-scale-codec", "scale-info", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "thiserror", -] - -[[package]] -name = "sp-inherents" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "async-trait", - "impl-trait-for-tuples", - "parity-scale-codec", - "scale-info", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-runtime", + "sp-std", "thiserror", ] @@ -11584,39 +11303,14 @@ dependencies = [ "parity-scale-codec", "rustversion", "secp256k1", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-keystore 0.27.0", - "sp-runtime-interface 17.0.0", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-trie 22.0.0", - "tracing", - "tracing-core", -] - -[[package]] -name = "sp-io" -version = "23.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "bytes", - "ed25519", - "ed25519-dalek", - "libsecp256k1", - "log", - "parity-scale-codec", - "rustversion", - "secp256k1", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", - "sp-keystore 0.27.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime-interface 17.0.0 (git+https://github.com/paritytech/substrate)", - "sp-state-machine 0.28.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", - "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-externalities", + "sp-keystore", + "sp-runtime-interface", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-trie", "tracing", "tracing-core", ] @@ -11626,8 +11320,8 @@ name = "sp-keyring" version = "24.0.0" dependencies = [ "lazy_static", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "strum", ] @@ -11639,20 +11333,8 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.7.3", "rand_chacha 0.2.2", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "thiserror", -] - -[[package]] -name = "sp-keystore" -version = "0.27.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "parking_lot 0.12.1", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-externalities", "thiserror", ] @@ -11671,18 +11353,7 @@ dependencies = [ "frame-metadata", "parity-scale-codec", "scale-info", - "sp-std 8.0.0", -] - -[[package]] -name = "sp-metadata-ir" -version = "0.1.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "frame-metadata", - "parity-scale-codec", - "scale-info", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std", ] [[package]] @@ -11695,11 +11366,11 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-debug-derive 8.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-core", + "sp-debug-derive", + "sp-runtime", + "sp-std", "thiserror", ] @@ -11711,10 +11382,10 @@ dependencies = [ "rand 0.8.5", "scale-info", "serde", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", "substrate-test-utils", ] @@ -11726,31 +11397,21 @@ dependencies = [ "honggfuzz", "rand 0.8.5", "sp-npos-elections", - "sp-runtime 24.0.0", + "sp-runtime", ] [[package]] name = "sp-offchain" version = "4.0.0-dev" dependencies = [ - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-runtime 24.0.0", -] - -[[package]] -name = "sp-panic-handler" -version = "8.0.0" -dependencies = [ - "backtrace", - "lazy_static", - "regex", + "sp-api", + "sp-core", + "sp-runtime", ] [[package]] name = "sp-panic-handler" version = "8.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "backtrace", "lazy_static", @@ -11764,7 +11425,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "sp-core 21.0.0", + "sp-core", ] [[package]] @@ -11781,41 +11442,19 @@ dependencies = [ "scale-info", "serde", "serde_json", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", - "sp-weights 20.0.0", + "sp-api", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-state-machine", + "sp-std", + "sp-tracing", + "sp-weights", "substrate-test-runtime-client", "zstd 0.12.3+zstd.1.5.2", ] -[[package]] -name = "sp-runtime" -version = "24.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "either", - "hash256-std-hasher", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "paste", - "rand 0.8.5", - "scale-info", - "serde", - "sp-application-crypto 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-io 23.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-weights 20.0.0 (git+https://github.com/paritytech/substrate)", -] - [[package]] name = "sp-runtime-interface" version = "17.0.0" @@ -11825,53 +11464,23 @@ dependencies = [ "parity-scale-codec", "primitive-types", "rustversion", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-io 23.0.0", - "sp-runtime-interface-proc-macro 11.0.0", + "sp-core", + "sp-externalities", + "sp-io", + "sp-runtime-interface-proc-macro", "sp-runtime-interface-test-wasm", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-storage 13.0.0", - "sp-tracing 10.0.0", - "sp-wasm-interface 14.0.0", + "sp-state-machine", + "sp-std", + "sp-storage", + "sp-tracing", + "sp-wasm-interface", "static_assertions", "trybuild", ] -[[package]] -name = "sp-runtime-interface" -version = "17.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "bytes", - "impl-trait-for-tuples", - "parity-scale-codec", - "primitive-types", - "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime-interface-proc-macro 11.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-storage 13.0.0 (git+https://github.com/paritytech/substrate)", - "sp-tracing 10.0.0 (git+https://github.com/paritytech/substrate)", - "sp-wasm-interface 14.0.0 (git+https://github.com/paritytech/substrate)", - "static_assertions", -] - -[[package]] -name = "sp-runtime-interface-proc-macro" -version = "11.0.0" -dependencies = [ - "Inflector", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "sp-runtime-interface-proc-macro" version = "11.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "Inflector", "proc-macro-crate", @@ -11886,12 +11495,12 @@ version = "2.0.0" dependencies = [ "sc-executor", "sc-executor-common", - "sp-io 23.0.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", + "sp-io", + "sp-runtime", + "sp-runtime-interface", "sp-runtime-interface-test-wasm", "sp-runtime-interface-test-wasm-deprecated", - "sp-state-machine 0.28.0", + "sp-state-machine", "tracing", "tracing-core", ] @@ -11901,10 +11510,10 @@ name = "sp-runtime-interface-test-wasm" version = "2.0.0" dependencies = [ "bytes", - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-io", + "sp-runtime-interface", + "sp-std", "substrate-wasm-builder", ] @@ -11912,9 +11521,9 @@ dependencies = [ name = "sp-runtime-interface-test-wasm-deprecated" version = "2.0.0" dependencies = [ - "sp-core 21.0.0", - "sp-io 23.0.0", - "sp-runtime-interface 17.0.0", + "sp-core", + "sp-io", + "sp-runtime-interface", "substrate-wasm-builder", ] @@ -11924,11 +11533,11 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-staking 4.0.0-dev", - "sp-std 8.0.0", + "sp-api", + "sp-core", + "sp-runtime", + "sp-staking", + "sp-std", ] [[package]] @@ -11938,22 +11547,9 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", -] - -[[package]] -name = "sp-staking" -version = "4.0.0-dev" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -11969,33 +11565,12 @@ dependencies = [ "pretty_assertions", "rand 0.8.5", "smallvec", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-panic-handler 8.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-trie 22.0.0", - "thiserror", - "tracing", - "trie-db", -] - -[[package]] -name = "sp-state-machine" -version = "0.28.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "hash-db", - "log", - "parity-scale-codec", - "parking_lot 0.12.1", - "rand 0.8.5", - "smallvec", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-externalities 0.19.0 (git+https://github.com/paritytech/substrate)", - "sp-panic-handler 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-trie 22.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core", + "sp-externalities", + "sp-panic-handler", + "sp-runtime", + "sp-std", + "sp-trie", "thiserror", "tracing", "trie-db", @@ -12007,13 +11582,13 @@ version = "4.0.0-dev" dependencies = [ "parity-scale-codec", "scale-info", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-runtime 24.0.0", - "sp-runtime-interface 17.0.0", - "sp-std 8.0.0", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-externalities", + "sp-runtime", + "sp-runtime-interface", + "sp-std", "thiserror", ] @@ -12021,34 +11596,16 @@ dependencies = [ name = "sp-std" version = "8.0.0" -[[package]] -name = "sp-std" -version = "8.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" - -[[package]] -name = "sp-storage" -version = "13.0.0" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "ref-cast", - "serde", - "sp-debug-derive 8.0.0", - "sp-std 8.0.0", -] - [[package]] name = "sp-storage" version = "13.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "impl-serde", "parity-scale-codec", "ref-cast", "serde", - "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -12058,10 +11615,10 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "sp-application-crypto 23.0.0", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-application-crypto", + "sp-core", + "sp-runtime", + "sp-std", ] [[package]] @@ -12070,9 +11627,9 @@ version = "4.0.0-dev" dependencies = [ "async-trait", "parity-scale-codec", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-inherents", + "sp-runtime", + "sp-std", "thiserror", ] @@ -12081,19 +11638,7 @@ name = "sp-tracing" version = "10.0.0" dependencies = [ "parity-scale-codec", - "sp-std 8.0.0", - "tracing", - "tracing-core", - "tracing-subscriber 0.2.25", -] - -[[package]] -name = "sp-tracing" -version = "10.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std", "tracing", "tracing-core", "tracing-subscriber 0.2.25", @@ -12103,8 +11648,8 @@ dependencies = [ name = "sp-transaction-pool" version = "4.0.0-dev" dependencies = [ - "sp-api 4.0.0-dev", - "sp-runtime 24.0.0", + "sp-api", + "sp-runtime", ] [[package]] @@ -12114,11 +11659,11 @@ dependencies = [ "async-trait", "parity-scale-codec", "scale-info", - "sp-core 21.0.0", - "sp-inherents 4.0.0-dev", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-trie 22.0.0", + "sp-core", + "sp-inherents", + "sp-runtime", + "sp-std", + "sp-trie", ] [[package]] @@ -12137,9 +11682,9 @@ dependencies = [ "parking_lot 0.12.1", "scale-info", "schnellru", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", + "sp-core", + "sp-runtime", + "sp-std", "thiserror", "tracing", "trie-bench", @@ -12148,29 +11693,6 @@ dependencies = [ "trie-standardmap", ] -[[package]] -name = "sp-trie" -version = "22.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "ahash 0.8.3", - "hash-db", - "hashbrown 0.13.2", - "lazy_static", - "memory-db", - "nohash-hasher", - "parity-scale-codec", - "parking_lot 0.12.1", - "scale-info", - "schnellru", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "thiserror", - "tracing", - "trie-db", - "trie-root", -] - [[package]] name = "sp-version" version = "22.0.0" @@ -12180,27 +11702,10 @@ dependencies = [ "parity-wasm", "scale-info", "serde", - "sp-core-hashing-proc-macro 9.0.0", - "sp-runtime 24.0.0", - "sp-std 8.0.0", - "sp-version-proc-macro 8.0.0", - "thiserror", -] - -[[package]] -name = "sp-version" -version = "22.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "impl-serde", - "parity-scale-codec", - "parity-wasm", - "scale-info", - "serde", - "sp-core-hashing-proc-macro 9.0.0 (git+https://github.com/paritytech/substrate)", - "sp-runtime 24.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-version-proc-macro 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-core-hashing-proc-macro", + "sp-runtime", + "sp-std", + "sp-version-proc-macro", "thiserror", ] @@ -12211,43 +11716,19 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "sp-version 22.0.0", + "sp-version", "syn 2.0.18", ] -[[package]] -name = "sp-version-proc-macro" -version = "8.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "proc-macro2", - "quote", - "syn 2.0.18", -] - -[[package]] -name = "sp-wasm-interface" -version = "14.0.0" -dependencies = [ - "anyhow", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "sp-std 8.0.0", - "wasmtime", -] - [[package]] name = "sp-wasm-interface" version = "14.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" dependencies = [ "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-std", "wasmtime", ] @@ -12259,25 +11740,10 @@ dependencies = [ "scale-info", "serde", "smallvec", - "sp-arithmetic 16.0.0", - "sp-core 21.0.0", - "sp-debug-derive 8.0.0", - "sp-std 8.0.0", -] - -[[package]] -name = "sp-weights" -version = "20.0.0" -source = "git+https://github.com/paritytech/substrate#70c0547f40daa8b550ef1a849514d07c385f963e" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", - "smallvec", - "sp-arithmetic 16.0.0 (git+https://github.com/paritytech/substrate)", - "sp-core 21.0.0 (git+https://github.com/paritytech/substrate)", - "sp-debug-derive 8.0.0 (git+https://github.com/paritytech/substrate)", - "sp-std 8.0.0 (git+https://github.com/paritytech/substrate)", + "sp-arithmetic", + "sp-core", + "sp-debug-derive", + "sp-std", ] [[package]] @@ -12469,27 +11935,27 @@ name = "substrate-frame-cli" version = "4.0.0-dev" dependencies = [ "clap 4.3.2", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "sc-cli", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", ] [[package]] name = "substrate-frame-rpc-support" version = "3.0.0" dependencies = [ - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "jsonrpsee", "parity-scale-codec", "sc-rpc-api", "scale-info", "serde", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-storage 13.0.0", + "sp-core", + "sp-runtime", + "sp-storage", "tokio", ] @@ -12506,12 +11972,12 @@ dependencies = [ "sc-rpc-api", "sc-transaction-pool", "sc-transaction-pool-api", - "sp-api 4.0.0-dev", + "sp-api", "sp-block-builder", "sp-blockchain", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-tracing 10.0.0", + "sp-core", + "sp-runtime", + "sp-tracing", "substrate-test-runtime-client", "tokio", ] @@ -12536,8 +12002,8 @@ dependencies = [ "log", "sc-rpc-api", "serde", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "tokio", ] @@ -12551,10 +12017,10 @@ dependencies = [ "sc-rpc-api", "serde", "serde_json", - "sp-core 21.0.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", - "sp-trie 22.0.0", + "sp-core", + "sp-runtime", + "sp-state-machine", + "sp-trie", "trie-db", ] @@ -12576,11 +12042,11 @@ dependencies = [ "serde_json", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", + "sp-core", "sp-keyring", - "sp-keystore 0.27.0", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-keystore", + "sp-runtime", + "sp-state-machine", ] [[package]] @@ -12589,8 +12055,8 @@ version = "2.0.0" dependencies = [ "array-bytes 6.1.0", "frame-executive", - "frame-support 4.0.0-dev", - "frame-system 4.0.0-dev", + "frame-support", + "frame-system", "frame-system-rpc-runtime-api", "futures", "log", @@ -12602,27 +12068,27 @@ dependencies = [ "sc-executor", "sc-service", "scale-info", - "sp-api 4.0.0-dev", - "sp-application-crypto 23.0.0", + "sp-api", + "sp-application-crypto", "sp-block-builder", "sp-consensus", "sp-consensus-aura", "sp-consensus-babe", "sp-consensus-grandpa", - "sp-core 21.0.0", - "sp-externalities 0.19.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", + "sp-core", + "sp-externalities", + "sp-inherents", + "sp-io", "sp-keyring", "sp-offchain", - "sp-runtime 24.0.0", + "sp-runtime", "sp-session", - "sp-state-machine 0.28.0", - "sp-std 8.0.0", - "sp-tracing 10.0.0", + "sp-state-machine", + "sp-std", + "sp-tracing", "sp-transaction-pool", - "sp-trie 22.0.0", - "sp-version 22.0.0", + "sp-trie", + "sp-version", "substrate-test-runtime-client", "substrate-wasm-builder", "trie-db", @@ -12636,11 +12102,11 @@ dependencies = [ "sc-block-builder", "sc-client-api", "sc-consensus", - "sp-api 4.0.0-dev", + "sp-api", "sp-blockchain", "sp-consensus", - "sp-core 21.0.0", - "sp-runtime 24.0.0", + "sp-core", + "sp-runtime", "substrate-test-client", "substrate-test-runtime", ] @@ -12655,7 +12121,7 @@ dependencies = [ "sc-transaction-pool", "sc-transaction-pool-api", "sp-blockchain", - "sp-runtime 24.0.0", + "sp-runtime", "substrate-test-runtime-client", "thiserror", ] @@ -13390,22 +12856,22 @@ dependencies = [ "sc-executor", "serde", "serde_json", - "sp-api 4.0.0-dev", + "sp-api", "sp-consensus-aura", "sp-consensus-babe", - "sp-core 21.0.0", - "sp-debug-derive 8.0.0", - "sp-externalities 0.19.0", - "sp-inherents 4.0.0-dev", - "sp-io 23.0.0", - "sp-keystore 0.27.0", + "sp-core", + "sp-debug-derive", + "sp-externalities", + "sp-inherents", + "sp-io", + "sp-keystore", "sp-rpc", - "sp-runtime 24.0.0", - "sp-state-machine 0.28.0", + "sp-runtime", + "sp-state-machine", "sp-timestamp", "sp-transaction-storage-proof", - "sp-version 22.0.0", - "sp-weights 20.0.0", + "sp-version", + "sp-weights", "substrate-cli-test-utils", "substrate-rpc-client", "tempfile", diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index 2ed280f24f094..8a79e9064e67a 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -15,16 +15,16 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive"] } scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } bitvec = "1" -sp-std = { version = "8.0.0", git = "https://github.com/paritytech/substrate" } -sp-arithmetic = { version = "16.0.0", git = "https://github.com/paritytech/substrate" } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate" } +sp-std = { version = "8.0.0", path = "../../primitives/std" } +sp-arithmetic = { version = "16.0.0", path = "../../primitives/arithmetic" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" } +frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } +frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "21.0.0", git = "https://github.com/paritytech/substrate" } -sp-io = { version = "23.0.0", git = "https://github.com/paritytech/substrate" } -sp-runtime = { version = "24.0.0", git = "https://github.com/paritytech/substrate" } +sp-core = { version = "21.0.0", path = "../../primitives/core" } +sp-io = { version = "23.0.0", path = "../../primitives/io" } +sp-runtime = { version = "24.0.0", path = "../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 57453fc8a5cf0..05171f9708eb7 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -69,7 +69,7 @@ impl frame_system::Config for Test { impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; - type Currency = ItemOf>, (), u64>; + type Currency = ItemOf, ()>, (), u64>; type TimeslicePeriod = ConstU32<80>; type AdvanceNotice = (); type Coretime = (); diff --git a/frame/broker/src/test_fungibles.rs b/frame/broker/src/test_fungibles.rs index c4347e083a73b..2c65d82566446 100644 --- a/frame/broker/src/test_fungibles.rs +++ b/frame/broker/src/test_fungibles.rs @@ -17,8 +17,11 @@ use frame_support::{ parameter_types, - traits::{ConstU16, ConstU64, fungibles, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} + traits::{ConstU16, ConstU64, fungibles::{self, Dust}, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} }; +use scale_info::TypeInfo; +use sp_arithmetic::traits::Zero; +use sp_runtime::{DispatchError, DispatchResult}; use sp_std::collections::btree_map::BTreeMap; use codec::{Encode, Decode}; use sp_core::{ConstU32, TypedGet, Get}; @@ -26,18 +29,21 @@ use sp_core::{ConstU32, TypedGet, Get}; parameter_types! { static TestAssetOf: BTreeMap<(u32, Vec), Vec> = Default::default(); static TestBalanceOf: BTreeMap<(u32, Vec, Vec), Vec> = Default::default(); + static TestHoldOf: BTreeMap<(u32, Vec, Vec, Vec), Vec> = Default::default(); } -pub struct TestFungibles(core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance)>); +pub struct TestFungibles( + core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance, HoldReason)> +); impl< Instance: Get, AccountId: Encode, AssetId: tokens::AssetId + Copy, MinimumBalance: TypedGet, -> fungibles::Inspect for TestFungibles + HoldReason, +> fungibles::Inspect for TestFungibles where MinimumBalance::Type: tokens::Balance, - { type AssetId = AssetId; type Balance = MinimumBalance::Type; @@ -109,3 +115,145 @@ where TestAssetOf::get().contains_key(&(Instance::get(), asset.encode())) } } + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, +> fungibles::Unbalanced for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{ + fn handle_dust(_dust: Dust) {} + + fn write_balance( + asset: Self::AssetId, + who: &AccountId, + amount: Self::Balance, + ) -> Result, DispatchError> { + let mut tb = TestBalanceOf::get(); + let maybe_dust = if amount < MinimumBalance::get() { + tb.remove(&(Instance::get(), asset.encode(), who.encode())); + if amount.is_zero() { + None + } else { + Some(amount) + } + } else { + tb.insert((Instance::get(), asset.encode(), who.encode()), amount.encode()); + None + }; + TestBalanceOf::set(tb); + Ok(maybe_dust) + } + + fn set_total_issuance(asset: Self::AssetId, amount: Self::Balance) { + let mut ta = TestAssetOf::get(); + ta.insert((Instance::get(), asset.encode()), amount.encode()); + TestAssetOf::set(ta); + } +} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, +> fungibles::Mutate for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, +> fungibles::Balanced for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{ + type OnDropCredit = fungibles::DecreaseIssuance; + type OnDropDebt = fungibles::IncreaseIssuance; +} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, +> fungibles::InspectHold for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{ + type Reason = HoldReason; + + fn total_balance_on_hold(asset: Self::AssetId, who: &AccountId) -> Self::Balance { + let asset = asset.encode(); + let who = who.encode(); + TestHoldOf::get().iter() + .filter(|(k, _)| k.0 == Instance::get() && k.1 == asset && k.2 == who) + .filter_map(|(_, b)| Self::Balance::decode(&mut &b[..]).ok()) + .fold(Zero::zero(), |a, i| a + i) + } + + fn balance_on_hold( + asset: Self::AssetId, + reason: &Self::Reason, + who: &AccountId, + ) -> Self::Balance { + TestHoldOf::get().get(&(Instance::get(), asset.encode(), who.encode(), reason.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() + } +} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, +> fungibles::UnbalancedHold for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{ + fn set_balance_on_hold( + asset: Self::AssetId, + reason: &Self::Reason, + who: &AccountId, + amount: Self::Balance, + ) -> DispatchResult { + let mut th = TestHoldOf::get(); + th.insert((Instance::get(), asset.encode(), who.encode(), reason.encode()), amount.encode()); + TestHoldOf::set(th); + Ok(()) + } +} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, +> fungibles::MutateHold for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{} + +impl< + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, +> fungibles::BalancedHold for TestFungibles +where + MinimumBalance::Type: tokens::Balance, +{} \ No newline at end of file diff --git a/frame/support/src/traits/tokens/fungible/hold.rs b/frame/support/src/traits/tokens/fungible/hold.rs index ddcb8c6ac1da8..b4f0a98642d75 100644 --- a/frame/support/src/traits/tokens/fungible/hold.rs +++ b/frame/support/src/traits/tokens/fungible/hold.rs @@ -52,8 +52,10 @@ pub trait Inspect: super::Inspect { /// restrictions on the minimum amount of the account. Note: This cannot bring the account into /// an inconsistent state with regards any required existential deposit. /// - /// Always less than `total_balance_on_hold()`. - fn reducible_total_balance_on_hold(who: &AccountId, force: Fortitude) -> Self::Balance; + /// Never more than `total_balance_on_hold()`. + fn reducible_total_balance_on_hold(who: &AccountId, _force: Fortitude) -> Self::Balance { + Self::total_balance_on_hold(who) + } /// Amount of funds on hold (for the given reason) of `who`. fn balance_on_hold(reason: &Self::Reason, who: &AccountId) -> Self::Balance; @@ -65,7 +67,9 @@ pub trait Inspect: super::Inspect { /// NOTE: This does not take into account changes which could be made to the account of `who` /// (such as removing a provider reference) after this call is made. Any usage of this should /// therefore ensure the account is already in the appropriate state prior to calling it. - fn hold_available(reason: &Self::Reason, who: &AccountId) -> bool; + fn hold_available(_reason: &Self::Reason, _who: &AccountId) -> bool { + true + } /// Check to see if some `amount` of funds of `who` may be placed on hold with the given /// `reason`. Reasons why this may not be true: diff --git a/frame/support/src/traits/tokens/fungibles/hold.rs b/frame/support/src/traits/tokens/fungibles/hold.rs index 8fc038c57be3d..6ca6e6519ec70 100644 --- a/frame/support/src/traits/tokens/fungibles/hold.rs +++ b/frame/support/src/traits/tokens/fungibles/hold.rs @@ -52,12 +52,14 @@ pub trait Inspect: super::Inspect { /// restrictions on the minimum amount of the account. Note: This cannot bring the account into /// an inconsistent state with regards any required existential deposit. /// - /// Always less than `total_balance_on_hold()`. + /// Never more than `total_balance_on_hold()`. fn reducible_total_balance_on_hold( asset: Self::AssetId, who: &AccountId, - force: Fortitude, - ) -> Self::Balance; + _force: Fortitude, + ) -> Self::Balance { + Self::total_balance_on_hold(asset, who) + } /// Amount of funds on hold (for the given reason) of `who`. fn balance_on_hold( @@ -73,7 +75,9 @@ pub trait Inspect: super::Inspect { /// NOTE: This does not take into account changes which could be made to the account of `who` /// (such as removing a provider reference) after this call is made. Any usage of this should /// therefore ensure the account is already in the appropriate state prior to calling it. - fn hold_available(asset: Self::AssetId, reason: &Self::Reason, who: &AccountId) -> bool; + fn hold_available(_asset: Self::AssetId, _reason: &Self::Reason, _who: &AccountId) -> bool { + true + } /// Check to see if some `amount` of funds of `who` may be placed on hold with the given /// `reason`. Reasons why this may not be true: From 797f70dd58e5753f75bd7f7696e4e7ffc3b920b4 Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 17:12:39 +0200 Subject: [PATCH 007/131] Auctions --- frame/broker/src/lib.rs | 297 ++++++++++++++++++++++++++++++++++++--- frame/broker/src/mock.rs | 6 +- 2 files changed, 281 insertions(+), 22 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 916a0bb7deb5e..51396be749ed2 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -39,10 +39,16 @@ pub use weights::WeightInfo; #[frame_support::pallet] pub mod pallet { use super::*; - use frame_support::{pallet_prelude::*, traits::fungible::{self, Inspect, Mutate, MutateHold}}; + use frame_support::{ + pallet_prelude::{*, DispatchResult}, + traits::{ + tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, + fungible::{self, Credit, Inspect, Balanced, HandleImbalanceDrop}, OnUnbalanced + } + }; use frame_system::pallet_prelude::*; use sp_runtime::{AccountId32, traits::{ConvertBack, Convert}, DispatchError}; - use sp_arithmetic::traits::{AtLeast32BitUnsigned, SaturatedConversion, Saturating}; + use sp_arithmetic::{traits::{Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill}; use types::CorePart; #[pallet::pallet] @@ -56,7 +62,7 @@ pub mod pallet { Pool, Task(ParaId), } - pub type WholeCoreAssignment = Vec<(CoreAssignment, PartsOf57600)>; + pub type WholeCoreAssignment = BoundedVec<(CoreAssignment, PartsOf57600), ConstU32<80>>; pub trait CoretimeInterface { type AccountId: Parameter; @@ -69,7 +75,7 @@ pub mod pallet { fn assign_core( core: CoreIndex, begin: Self::BlockNumber, - assignment: WholeCoreAssignment, + assignment: Vec<(CoreAssignment, PartsOf57600)>, end_hint: Option, ); fn check_notify_core_count() -> Option; @@ -97,7 +103,9 @@ pub mod pallet { pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; - type Currency: Inspect;//Mutate + MutateHold; + type Currency: Balanced; + + type OnRevenue: OnUnbalanced>; /// Number of Relay-chain blocks ahead of time which we fix and notify of core assignments. #[pallet::constant] @@ -107,6 +115,18 @@ pub mod pallet { #[pallet::constant] type TimeslicePeriod: Get>; + /// Period, in timeslices, of the Bulk Coretime placed for sale. + #[pallet::constant] + type BulkPeriod: Get; + + /// Maximum number of legacy leases. + #[pallet::constant] + type MaxLeasedCores: Get; + + /// Maximum number of system cores. + #[pallet::constant] + type MaxReservedCores: Get; + /// Reversible conversion from local balance to Relay-chain balance. type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; @@ -140,11 +160,12 @@ pub mod pallet { } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct RegionRecord { + pub struct RegionRecord { end: Timeslice, owner: AccountId, + paid: Option, } - pub type RegionRecordOf = RegionRecord<::AccountId>; + pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf>; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ScheduleItem { @@ -177,6 +198,14 @@ pub mod pallet { } pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct AllowedRenewalRecord { + begin: Timeslice, + price: Balance, + workload: Schedule, + } + pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct StatusRecord { core_count: CoreIndex, @@ -184,6 +213,72 @@ pub mod pallet { last_timeslice: Timeslice, } + /* + SALE: + 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 + -------------------------------------------------------- + < renewals > + < sale > + ... of which ... > + < auction >< fixed-price > + | <-------\ + price fixed, unsold assigned to instapool, system cores reserved -/ + */ + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct SaleStatusRecord { + sale_start: BlockNumber, + auction_length: BlockNumber, + start_price: Balance, + reserve_price: Balance, + region_begin: Timeslice, + region_length: Timeslice, + first_core: CoreIndex, + /// The number of cores we want to sell, ideally. Selling this amount would result in no + /// change to the reserve_price for the next sale. + ideal_cores_sold: CoreIndex, + /// Number of cores which are/have been offered for sale. + cores_offered: CoreIndex, + /// Number of cores which have been sold; never more than cores_offered. + cores_sold: CoreIndex, + } + pub type SaleStatusRecordOf = SaleStatusRecord< + BalanceOf, + ::BlockNumber, + >; + + pub type ReservationsRecord = BoundedVec; + pub type ReservationsRecordOf = ReservationsRecord<::MaxReservedCores>; + pub type LeasesRecord = BoundedVec<(Timeslice, ParaId), Max>; + pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; + + #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + pub struct SaleConfigRecord { + presale_length: BlockNumber, + auction_length: BlockNumber, + ideal_cores_sold: CoreIndex, + cores_offered: CoreIndex, + } + pub type SaleConfigRecordOf = SaleConfigRecord< + ::BlockNumber, + >; + + #[pallet::storage] + pub type Reservations = StorageValue<_, ReservationsRecordOf, ValueQuery>; + + #[pallet::storage] + pub type Leases = StorageValue<_, LeasesRecordOf, ValueQuery>; + + #[pallet::storage] + pub type AllowedRenewals = StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; + + #[pallet::storage] + pub type SaleConfig = StorageValue<_, SaleConfigRecordOf, OptionQuery>; + + #[pallet::storage] + pub type SaleStatus = StorageValue<_, SaleStatusRecordOf, OptionQuery>; + #[pallet::storage] pub type Regions = StorageMap<_, Blake2_128Concat, RegionId, RegionRecordOf, OptionQuery>; @@ -247,6 +342,15 @@ pub mod pallet { NullPivot, CompletePivot, CorruptWorkplan, + NoSales, + IndeterminablePrice, + Overpriced, + Unavailable, + SoldOut, + WrongTime, + NotAllowed, + Uninitialized, + TooEarly, } #[pallet::hooks] @@ -266,7 +370,82 @@ pub mod pallet { } } + fn lerp, S: TryInto + TryFrom + Bounded>(v: T, a: T, d: T, x: S, y: S) -> Option { + use sp_arithmetic::{Rounding::NearestPrefUp, helpers_128bit::multiply_by_rational_with_rounding}; + let v: u128 = v.try_into().ok()?; + let a: u128 = a.try_into().ok()?; + let d: u128 = d.try_into().ok()?; + let r: u128 = x.try_into().ok()?; + let s: u128 = y.try_into().ok()?; + let rsd = r.max(s) - r.min(s); + let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; + if r < s { r + td } else { r - td }.try_into().ok() + } + impl Pallet { + /// Begin selling for the next sale period. + /// + /// Triggered by Relay-chain block number/timeslice. + pub(crate) fn rotate_sale(reserve_price: BalanceOf) -> Option<()> { + let config = SaleConfig::::get()?; + let old_sale = SaleStatus::::get()?; + + let now = frame_system::Pallet::::block_number(); + + // Calculate the start price for the sale after. + let start_price = old_sale.start_price; + let reserve_price = old_sale.reserve_price; + + // Set workload for the reserved (system, probably) workloads. + let region_begin = old_sale.region_begin + old_sale.region_length; + let region_length = old_sale.region_length; + + let mut first_core = 0; + for schedule in Reservations::::get().into_iter() { + Workplan::::insert((region_begin, first_core), schedule); + first_core.saturating_inc(); + } + + let mut leases = Leases::::get(); + // can morph to a renewable as long as it's > begin and < end. + leases.retain(|&(until, para)| { + let part = CorePart::complete(); + let assignment = CoreAssignment::Task(para); + let schedule = BoundedVec::truncate_from(vec![ScheduleItem { part, assignment }]); + Workplan::::insert((region_begin, first_core), &schedule); + let expiring = until >= region_begin; + if expiring { + // last time for this one - make it renewable. + let record = AllowedRenewalRecord { + begin: region_begin + region_length, + price: reserve_price, + workload: schedule, + }; + AllowedRenewals::::insert(first_core, record); + } + first_core.saturating_inc(); + !expiring + }); + Leases::::put(&leases); + + // Update SaleStatus + let new_sale = SaleStatusRecord { + sale_start: now.saturating_add(config.presale_length), + auction_length: config.auction_length, + start_price, + reserve_price, + region_begin, + region_length, + first_core, + ideal_cores_sold: config.ideal_cores_sold, + cores_offered: config.cores_offered, + cores_sold: 0, + }; + SaleStatus::::put(&new_sale); + + Some(()) + } + pub(crate) fn next_timeslice() -> Timeslice { let latest = T::Coretime::latest(); let advance = T::AdvanceNotice::get(); @@ -327,7 +506,7 @@ pub mod pallet { intermediate.push((CoreAssignment::Idle, 80 - total_used)); } intermediate.sort(); - let mut assignment: WholeCoreAssignment = Vec::with_capacity(intermediate.len()); + let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = Vec::with_capacity(intermediate.len()); for i in intermediate.into_iter() { if let Some(ref mut last) = assignment.last_mut() { if last.0 == i.0 { @@ -340,7 +519,78 @@ pub mod pallet { T::Coretime::assign_core(core, rc_begin, assignment, None); } - pub(crate) fn do_transfer(region_id: RegionId, maybe_check_owner: Option, new_owner: T::AccountId) -> Result<(), Error> { + fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + T::OnRevenue::on_unbalanced(T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?); + Ok(()) + } + + /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the + /// current sale status's `region_end`. + pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> DispatchResult { + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; + let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; + + ensure!(record.begin == sale.region_begin, Error::::WrongTime); + ensure!(sale.first_core < status.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + + Self::charge(who, record.price)?; + + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + + Workplan::::insert((record.begin, core), &record.workload); + + let begin = sale.region_begin + sale.region_length; + let price = record.price + record.price / 100u32.into() * 2u32.into(); + let new_record = AllowedRenewalRecord { begin, price, .. record }; + AllowedRenewals::::insert(core, new_record); + SaleStatus::::put(&sale); + Ok(()) + } + + pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; + ensure!(sale.first_core < status.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + let now = frame_system::Pallet::::block_number(); + ensure!(now > sale.sale_start, Error::::TooEarly); + let current_price = lerp( + now, + sale.sale_start, + sale.auction_length, + sale.start_price, + sale.reserve_price, + ).ok_or(Error::::IndeterminablePrice)?; + ensure!(price_limit >= current_price, Error::::Overpriced); + + Self::charge(&who, current_price)?; + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + SaleStatus::::put(&sale); + Self::issue(core, sale.region_begin, sale.region_length, who, Some(current_price)); + Ok(()) + } + + pub(crate) fn issue( + core: CoreIndex, + begin: Timeslice, + length: Timeslice, + owner: T::AccountId, + paid: Option>, + ) { + let id = RegionId { begin, core, part: CorePart::complete() }; + let record = RegionRecord { end: begin + length, owner, paid }; + Regions::::insert(id, record); + } + + pub(crate) fn do_transfer( + region_id: RegionId, + maybe_check_owner: Option, + new_owner: T::AccountId, + ) -> Result<(), Error> { let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; if let Some(check_owner) = maybe_check_owner { @@ -369,6 +619,7 @@ pub mod pallet { ensure!(pivot > region_id.begin, Error::::PivotTooEarly); ensure!(pivot < region.end, Error::::PivotTooLate); + region.paid = None; let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; let new_region = RegionRecord { end: pivot, ..region.clone() }; @@ -444,6 +695,22 @@ pub mod pallet { }).is_ok() { Workplan::::insert(&workplan_key, &workplan); } + if region.end.saturating_sub(region_id.begin) == T::BulkPeriod::get() { + if workplan.iter() + .filter(|i| matches!(i.assignment, CoreAssignment::Task(..))) + .fold(CorePart::void(), |a, i| a | i.part) + .is_complete() + { + if let Some(price) = region.paid { + let record = AllowedRenewalRecord { + begin: region.end, + price, + workload: workplan, + }; + AllowedRenewals::::insert(region_id.core, &record); + } + } + } Self::deposit_event(Event::Assigned { region_id, task: target }); } Ok(()) @@ -478,17 +745,5 @@ pub mod pallet { } Ok(()) } - - pub(crate) fn issue( - core: CoreIndex, - begin: Timeslice, - length: Timeslice, - owner: T::AccountId, - ) -> Result<(), Error> { - let id = RegionId { begin, core, part: CorePart::complete() }; - let record = RegionRecord { end: begin + length, owner }; - Regions::::insert(id, record); - Ok(()) - } } } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 05171f9708eb7..2d78860d00a42 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -17,7 +17,7 @@ #![cfg(test)] -use frame_support::{traits::fungible::ItemOf}; +use frame_support::{traits::fungible::{ItemOf, DecreaseIssuance}}; use sp_core::{H256, Get, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ testing::Header, @@ -70,7 +70,11 @@ impl frame_system::Config for Test { impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; + type OnRevenue = (); type TimeslicePeriod = ConstU32<80>; + type BulkPeriod = ConstU32<100>; + type MaxLeasedCores = ConstU32<5>; + type MaxReservedCores = ConstU32<5>; type AdvanceNotice = (); type Coretime = (); type ConvertBalance = Identity; From 055ac7e09416cdc092f7ac1cd97d7a3f50dcafee Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 17:38:13 +0200 Subject: [PATCH 008/131] Price morphing --- frame/broker/src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 51396be749ed2..65eeba25d9ff5 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -30,7 +30,6 @@ pub mod weights; pub use weights::WeightInfo; /* TODO: -- Purchase and renewal - Advance notice & on_initialize - Initialization - Pool rewards @@ -48,7 +47,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; use sp_runtime::{AccountId32, traits::{ConvertBack, Convert}, DispatchError}; - use sp_arithmetic::{traits::{Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill}; + use sp_arithmetic::{traits::{Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill, PerThing}; use types::CorePart; #[pallet::pallet] @@ -383,18 +382,57 @@ pub mod pallet { } impl Pallet { + pub(crate) fn initialize( + reserve_price: BalanceOf, + ) { + } + + fn next_price( + offered: CoreIndex, + ideal: CoreIndex, + sold: CoreIndex, + old: BalanceOf, + ) -> BalanceOf { + if sold > ideal { + let extra = if offered > ideal { + Perbill::from_rational((sold - ideal) as u32, (offered - ideal) as u32) + } else { + Perbill::zero() + }; + old + extra * old + } else { + let extra = if ideal > 0 { + Perbill::from_rational(sold as u32, ideal as u32).left_from_one() + } else { + Perbill::zero() + }; + old - extra * old + } + } + /// Begin selling for the next sale period. /// /// Triggered by Relay-chain block number/timeslice. - pub(crate) fn rotate_sale(reserve_price: BalanceOf) -> Option<()> { + pub(crate) fn rotate_sale() -> Option<()> { + let status = Status::::get()?; let config = SaleConfig::::get()?; let old_sale = SaleStatus::::get()?; let now = frame_system::Pallet::::block_number(); // Calculate the start price for the sale after. - let start_price = old_sale.start_price; - let reserve_price = old_sale.reserve_price; + let reserve_price = { + let core_count = status.core_count; + let max_retail = core_count.saturating_sub(old_sale.first_core); + let offered = old_sale.cores_offered.min(max_retail); + let ideal = old_sale.ideal_cores_sold.min(max_retail); + let sold = old_sale.cores_sold; + let old_price = old_sale.reserve_price; + Self::next_price(offered, ideal, sold, old_price) + }; + let start_price = reserve_price * 2u32.into(); + + // TODO: commission system InstaPool cores. // Set workload for the reserved (system, probably) workloads. let region_begin = old_sale.region_begin + old_sale.region_length; From 194977483eac1a3cfe52fcb3a52b337113add3bb Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 9 Jul 2023 19:50:07 +0200 Subject: [PATCH 009/131] First tests --- frame/broker/src/lib.rs | 141 +++++++++++++++++++++++++++----------- frame/broker/src/mock.rs | 46 +++++++++++-- frame/broker/src/tests.rs | 49 +++++++++++-- 3 files changed, 186 insertions(+), 50 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 65eeba25d9ff5..82797eb752b7d 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -47,7 +47,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; use sp_runtime::{AccountId32, traits::{ConvertBack, Convert}, DispatchError}; - use sp_arithmetic::{traits::{Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill, PerThing}; + use sp_arithmetic::{traits::{Zero, Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill, PerThing}; use types::CorePart; #[pallet::pallet] @@ -106,18 +106,10 @@ pub mod pallet { type OnRevenue: OnUnbalanced>; - /// Number of Relay-chain blocks ahead of time which we fix and notify of core assignments. - #[pallet::constant] - type AdvanceNotice: Get>; - /// Number of Relay-chain blocks per timeslice. #[pallet::constant] type TimeslicePeriod: Get>; - /// Period, in timeslices, of the Bulk Coretime placed for sale. - #[pallet::constant] - type BulkPeriod: Get; - /// Maximum number of legacy leases. #[pallet::constant] type MaxLeasedCores: Get; @@ -153,9 +145,9 @@ pub mod pallet { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct RegionId { - begin: Timeslice, - core: CoreIndex, - part: CorePart, + pub begin: Timeslice, + pub core: CoreIndex, + pub part: CorePart, } #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -168,8 +160,8 @@ pub mod pallet { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ScheduleItem { - part: CorePart, - assignment: CoreAssignment, + pub part: CorePart, + pub assignment: CoreAssignment, } pub type Schedule = BoundedVec>; @@ -209,6 +201,7 @@ pub mod pallet { pub struct StatusRecord { core_count: CoreIndex, pool_size: PartCount, + advance_notice: Timeslice, last_timeslice: Timeslice, } @@ -254,10 +247,11 @@ pub mod pallet { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct SaleConfigRecord { - presale_length: BlockNumber, - auction_length: BlockNumber, - ideal_cores_sold: CoreIndex, - cores_offered: CoreIndex, + pub presale_length: BlockNumber, + pub auction_length: BlockNumber, + pub ideal_cores_sold: CoreIndex, + pub cores_offered: CoreIndex, + pub region_length: Timeslice, } pub type SaleConfigRecordOf = SaleConfigRecord< ::BlockNumber, @@ -350,11 +344,14 @@ pub mod pallet { NotAllowed, Uninitialized, TooEarly, + NothingToDo, + TooManyReservations, } #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(now: T::BlockNumber) -> Weight { + Self::do_tick(); Weight::zero() } } @@ -382,12 +379,64 @@ pub mod pallet { } impl Pallet { - pub(crate) fn initialize( + pub(crate) fn do_configure(config: SaleConfigRecordOf) -> DispatchResult { + SaleConfig::::put(config); + Ok(()) + } + + /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is + /// less than `Self::last_timeslice`. + pub(crate) fn do_tick() -> DispatchResult { + let mut status = Status::::get().ok_or(Error::::Uninitialized)?; + + let processable_until = Self::current_schedulable_timeslice(); + ensure!(status.last_timeslice < processable_until, Error::::NothingToDo); + status.last_timeslice.saturating_inc(); + Self::process_timeslice(status.last_timeslice, &mut status); + + if let Some(sale) = SaleStatus::::get() { + if status.last_timeslice >= sale.region_begin { + // Sale can be rotated. + Self::rotate_sale(status.last_timeslice, sale, &status); + } + } + + Status::::put(&status); + Ok(()) + } + + pub(crate) fn do_start_sales( + core_count: CoreIndex, reserve_price: BalanceOf, - ) { + advance_notice: Timeslice, + ) -> DispatchResult { + let config = SaleConfig::::get().ok_or(Error::::Uninitialized)?; + let current_schedulable_timeslice = Self::current_schedulable_timeslice(); + let mut status = StatusRecord { + core_count, + pool_size: 0, + advance_notice, + last_timeslice: current_schedulable_timeslice, + }; + let now = frame_system::Pallet::::block_number(); + let dummy_sale = SaleStatusRecord { + sale_start: now, + auction_length: Zero::zero(), + start_price: Zero::zero(), + reserve_price, + region_begin: current_schedulable_timeslice, + region_length: config.region_length, + first_core: 0, + ideal_cores_sold: 0, + cores_offered: 0, + cores_sold: 0, + }; + Self::rotate_sale(current_schedulable_timeslice, dummy_sale, &status); + Status::::put(status); + Ok(()) } - fn next_price( + fn bump_price( offered: CoreIndex, ideal: CoreIndex, sold: CoreIndex, @@ -413,10 +462,8 @@ pub mod pallet { /// Begin selling for the next sale period. /// /// Triggered by Relay-chain block number/timeslice. - pub(crate) fn rotate_sale() -> Option<()> { - let status = Status::::get()?; + pub(crate) fn rotate_sale(timeslice: Timeslice, old_sale: SaleStatusRecordOf, status: &StatusRecord) -> Option<()> { let config = SaleConfig::::get()?; - let old_sale = SaleStatus::::get()?; let now = frame_system::Pallet::::block_number(); @@ -428,7 +475,11 @@ pub mod pallet { let ideal = old_sale.ideal_cores_sold.min(max_retail); let sold = old_sale.cores_sold; let old_price = old_sale.reserve_price; - Self::next_price(offered, ideal, sold, old_price) + if offered > 0 { + Self::bump_price(offered, ideal, sold, old_price) + } else { + old_price + } }; let start_price = reserve_price * 2u32.into(); @@ -436,7 +487,7 @@ pub mod pallet { // Set workload for the reserved (system, probably) workloads. let region_begin = old_sale.region_begin + old_sale.region_length; - let region_length = old_sale.region_length; + let region_length = config.region_length; let mut first_core = 0; for schedule in Reservations::::get().into_iter() { @@ -484,26 +535,33 @@ pub mod pallet { Some(()) } - pub(crate) fn next_timeslice() -> Timeslice { + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { + let mut r = Reservations::::get(); + r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; + Reservations::::put(r); + Ok(()) + } + + pub(crate) fn current_timeslice() -> Timeslice { let latest = T::Coretime::latest(); - let advance = T::AdvanceNotice::get(); let timeslice_period = T::TimeslicePeriod::get(); - let last_scheduled = (latest + advance) / timeslice_period; - let mut next_scheduled: Timeslice = last_scheduled.saturated_into(); - next_scheduled.saturating_add(1) + (latest / timeslice_period).saturated_into() } - pub(crate) fn process_timeslice(timeslice: Timeslice) { - let mut status = match Status::::get() { - Some(s) => s, - None => return, - }; - Self::process_pool(timeslice, &mut status); + pub(crate) fn current_schedulable_timeslice() -> Timeslice { + Self::current_timeslice() + Status::::get().map_or(0, |x| x.advance_notice) + } + + pub(crate) fn next_schedulable_timeslice() -> Timeslice { + Self::current_schedulable_timeslice().saturating_add(1) + } + + pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord) { + Self::process_pool(timeslice, status); let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); for core in 0..status.core_count { - Self::process_core_schedule(timeslice, rc_begin, core, &mut status); + Self::process_core_schedule(timeslice, rc_begin, core, status); } - Status::::put(status); } fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { @@ -704,7 +762,7 @@ pub mod pallet { ensure!(check_owner == region.owner, Error::::NotOwner); } - let next_timeslice = Self::next_timeslice(); + let next_timeslice = Self::next_schedulable_timeslice(); if region_id.begin > next_timeslice { region_id.begin = next_timeslice; } @@ -723,6 +781,7 @@ pub mod pallet { maybe_check_owner: Option, target: ParaId, ) -> Result<(), Error> { + let config = SaleConfig::::get().ok_or(Error::::Uninitialized)?; if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) @@ -733,7 +792,7 @@ pub mod pallet { }).is_ok() { Workplan::::insert(&workplan_key, &workplan); } - if region.end.saturating_sub(region_id.begin) == T::BulkPeriod::get() { + if region.end.saturating_sub(region_id.begin) == config.region_length { if workplan.iter() .filter(|i| matches!(i.assignment, CoreAssignment::Task(..))) .fold(CorePart::void(), |a, i| a | i.part) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 2d78860d00a42..08f6fa4bf6af6 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -17,7 +17,8 @@ #![cfg(test)] -use frame_support::{traits::fungible::{ItemOf, DecreaseIssuance}}; +use crate::*; +use frame_support::{parameter_types, traits::fungible::{ItemOf, DecreaseIssuance}}; use sp_core::{H256, Get, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ testing::Header, @@ -67,16 +68,51 @@ impl frame_system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum CoretimeTraceItem { + AssignCore { + core: CoreIndex, + begin: u32, + assignment: Vec<(CoreAssignment, PartsOf57600)>, + end_hint: Option, + }, +} +use CoretimeTraceItem::*; + +parameter_types!{ + pub static CoretimeTrace: Vec<(u32, CoretimeTraceItem)> = Default::default(); +} + +impl CoretimeInterface for CoretimeTrace { + type AccountId = (); + type Balance = u64; + type BlockNumber = u32; + fn latest() -> Self::BlockNumber { System::block_number() as u32 } + fn request_core_count(_count: CoreIndex) {} + fn request_revenue_info_at(_when: Self::BlockNumber) {} + fn credit_account(_who: Self::AccountId, _amount: Balance) {} + fn assign_core( + core: CoreIndex, + begin: Self::BlockNumber, + assignment: Vec<(CoreAssignment, PartsOf57600)>, + end_hint: Option, + ) { + let mut v = CoretimeTrace::get(); + v.push((Self::latest(), AssignCore { core, begin, assignment, end_hint })); + CoretimeTrace::set(v); + } + fn check_notify_core_count() -> Option { None } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } +} + impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; type OnRevenue = (); - type TimeslicePeriod = ConstU32<80>; - type BulkPeriod = ConstU32<100>; + type TimeslicePeriod = ConstU32<2>; type MaxLeasedCores = ConstU32<5>; type MaxReservedCores = ConstU32<5>; - type AdvanceNotice = (); - type Coretime = (); + type Coretime = CoretimeTrace; type ConvertBalance = Identity; type WeightInfo = (); } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index af23adedb2c4a..478379c390b0c 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,12 +17,53 @@ #![cfg(test)] -use crate::{mock::*, Error}; -use frame_support::{assert_noop, assert_ok}; +use crate::{*, mock::*, types::*, Error, SaleConfigRecord}; +use frame_support::{assert_noop, assert_ok, traits::Hooks}; +use CoreAssignment::*; +use CoretimeTraceItem::*; + +fn advance_to(b: u64) { + while System::block_number() < b { + System::set_block_number(System::block_number() + 1); + Broker::on_initialize(System::block_number()); + } +} + +#[test] +fn basic_initialize_works() { + new_test_ext().execute_with(|| { + assert_ok!(Broker::do_configure(SaleConfigRecord { + presale_length: 1, + auction_length: 3, + ideal_cores_sold: 0, + cores_offered: 0, + region_length: 10, + })); + assert_ok!(Broker::do_start_sales(10, 100, 1)); + assert_eq!(CoretimeTrace::get(), vec![]); + }); +} #[test] -fn bitvec_size() { +fn initialize_with_system_paras_works() { new_test_ext().execute_with(|| { - + assert_ok!(Broker::do_configure(SaleConfigRecord { + presale_length: 1, + auction_length: 3, + ideal_cores_sold: 0, + cores_offered: 0, + region_length: 5, + })); + + let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; + assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); + + assert_ok!(Broker::do_start_sales(10, 100, 0)); + assert_eq!(CoretimeTrace::get(), vec![]); + + advance_to(10); + assert_eq!(CoretimeTrace::get(), vec![ + (10, AssignCore { core: 0, begin: 10, assignment: vec![(Task(1), 57600)], end_hint: None }) + ]); }); } From afa138db3ac1585fa27b6731b868168459e6fe43 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 13:46:30 +0200 Subject: [PATCH 010/131] Tidying up config/status --- frame/broker/src/lib.rs | 102 ++++++++++++++++++++------------------ frame/broker/src/tests.rs | 35 +++++++------ 2 files changed, 75 insertions(+), 62 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 82797eb752b7d..5d869782ca9d3 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -197,11 +197,10 @@ pub mod pallet { } pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; + /// General status of the system. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct StatusRecord { - core_count: CoreIndex, pool_size: PartCount, - advance_notice: Timeslice, last_timeslice: Timeslice, } @@ -221,11 +220,11 @@ pub mod pallet { #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct SaleStatusRecord { sale_start: BlockNumber, - auction_length: BlockNumber, + leadin_length: BlockNumber, start_price: Balance, reserve_price: Balance, region_begin: Timeslice, - region_length: Timeslice, + region_end: Timeslice, first_core: CoreIndex, /// The number of cores we want to sell, ideally. Selling this amount would result in no /// change to the reserve_price for the next sale. @@ -246,14 +245,16 @@ pub mod pallet { pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct SaleConfigRecord { - pub presale_length: BlockNumber, - pub auction_length: BlockNumber, - pub ideal_cores_sold: CoreIndex, - pub cores_offered: CoreIndex, + pub struct ConfigRecord { + pub core_count: CoreIndex, + pub advance_notice: Timeslice, + pub interlude_length: BlockNumber, + pub leadin_length: BlockNumber, + pub ideal_bulk_proportion: Perbill, + pub limit_cores_offered: Option, pub region_length: Timeslice, } - pub type SaleConfigRecordOf = SaleConfigRecord< + pub type ConfigRecordOf = ConfigRecord< ::BlockNumber, >; @@ -267,7 +268,7 @@ pub mod pallet { pub type AllowedRenewals = StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; #[pallet::storage] - pub type SaleConfig = StorageValue<_, SaleConfigRecordOf, OptionQuery>; + pub type Configuration = StorageValue<_, ConfigRecordOf, OptionQuery>; #[pallet::storage] pub type SaleStatus = StorageValue<_, SaleStatusRecordOf, OptionQuery>; @@ -379,25 +380,26 @@ pub mod pallet { } impl Pallet { - pub(crate) fn do_configure(config: SaleConfigRecordOf) -> DispatchResult { - SaleConfig::::put(config); + pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { + Configuration::::put(config); Ok(()) } /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is /// less than `Self::last_timeslice`. pub(crate) fn do_tick() -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let mut status = Status::::get().ok_or(Error::::Uninitialized)?; let processable_until = Self::current_schedulable_timeslice(); ensure!(status.last_timeslice < processable_until, Error::::NothingToDo); status.last_timeslice.saturating_inc(); - Self::process_timeslice(status.last_timeslice, &mut status); + Self::process_timeslice(status.last_timeslice, &mut status, &config); if let Some(sale) = SaleStatus::::get() { if status.last_timeslice >= sale.region_begin { // Sale can be rotated. - Self::rotate_sale(status.last_timeslice, sale, &status); + Self::rotate_sale(status.last_timeslice, sale, &status, &config); } } @@ -406,33 +408,29 @@ pub mod pallet { } pub(crate) fn do_start_sales( - core_count: CoreIndex, reserve_price: BalanceOf, - advance_notice: Timeslice, ) -> DispatchResult { - let config = SaleConfig::::get().ok_or(Error::::Uninitialized)?; + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let current_schedulable_timeslice = Self::current_schedulable_timeslice(); - let mut status = StatusRecord { - core_count, + let status = StatusRecord { pool_size: 0, - advance_notice, last_timeslice: current_schedulable_timeslice, }; + Status::::put(&status); let now = frame_system::Pallet::::block_number(); let dummy_sale = SaleStatusRecord { sale_start: now, - auction_length: Zero::zero(), + leadin_length: Zero::zero(), start_price: Zero::zero(), reserve_price, region_begin: current_schedulable_timeslice, - region_length: config.region_length, + region_end: current_schedulable_timeslice + config.region_length, first_core: 0, ideal_cores_sold: 0, cores_offered: 0, cores_sold: 0, }; - Self::rotate_sale(current_schedulable_timeslice, dummy_sale, &status); - Status::::put(status); + Self::rotate_sale(current_schedulable_timeslice, dummy_sale, &status, &config); Ok(()) } @@ -462,14 +460,17 @@ pub mod pallet { /// Begin selling for the next sale period. /// /// Triggered by Relay-chain block number/timeslice. - pub(crate) fn rotate_sale(timeslice: Timeslice, old_sale: SaleStatusRecordOf, status: &StatusRecord) -> Option<()> { - let config = SaleConfig::::get()?; - + pub(crate) fn rotate_sale( + timeslice: Timeslice, + old_sale: SaleStatusRecordOf, + status: &StatusRecord, + config: &ConfigRecordOf, + ) -> Option<()> { let now = frame_system::Pallet::::block_number(); // Calculate the start price for the sale after. let reserve_price = { - let core_count = status.core_count; + let core_count = config.core_count; let max_retail = core_count.saturating_sub(old_sale.first_core); let offered = old_sale.cores_offered.min(max_retail); let ideal = old_sale.ideal_cores_sold.min(max_retail); @@ -486,8 +487,8 @@ pub mod pallet { // TODO: commission system InstaPool cores. // Set workload for the reserved (system, probably) workloads. - let region_begin = old_sale.region_begin + old_sale.region_length; - let region_length = config.region_length; + let region_begin = old_sale.region_end; + let region_end = region_begin + config.region_length; let mut first_core = 0; for schedule in Reservations::::get().into_iter() { @@ -506,7 +507,7 @@ pub mod pallet { if expiring { // last time for this one - make it renewable. let record = AllowedRenewalRecord { - begin: region_begin + region_length, + begin: region_end, price: reserve_price, workload: schedule, }; @@ -517,17 +518,20 @@ pub mod pallet { }); Leases::::put(&leases); + let max_possible_sales = config.core_count.saturating_sub(first_core); + let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); + let cores_offered = limit_cores_offered.min(max_possible_sales); // Update SaleStatus let new_sale = SaleStatusRecord { - sale_start: now.saturating_add(config.presale_length), - auction_length: config.auction_length, + sale_start: now.saturating_add(config.interlude_length), + leadin_length: config.leadin_length, start_price, reserve_price, region_begin, - region_length, + region_end, first_core, - ideal_cores_sold: config.ideal_cores_sold, - cores_offered: config.cores_offered, + ideal_cores_sold: (config.ideal_bulk_proportion * cores_offered as u32) as u16, + cores_offered, cores_sold: 0, }; SaleStatus::::put(&new_sale); @@ -549,17 +553,17 @@ pub mod pallet { } pub(crate) fn current_schedulable_timeslice() -> Timeslice { - Self::current_timeslice() + Status::::get().map_or(0, |x| x.advance_notice) + Self::current_timeslice() + Configuration::::get().map_or(0, |x| x.advance_notice) } pub(crate) fn next_schedulable_timeslice() -> Timeslice { Self::current_schedulable_timeslice().saturating_add(1) } - pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord) { + pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, config: &ConfigRecordOf) { Self::process_pool(timeslice, status); let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); - for core in 0..status.core_count { + for core in 0..config.core_count { Self::process_core_schedule(timeslice, rc_begin, core, status); } } @@ -623,12 +627,13 @@ pub mod pallet { /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the /// current sale status's `region_end`. pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); - ensure!(sale.first_core < status.core_count, Error::::Unavailable); + ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); Self::charge(who, record.price)?; @@ -638,7 +643,7 @@ pub mod pallet { Workplan::::insert((record.begin, core), &record.workload); - let begin = sale.region_begin + sale.region_length; + let begin = sale.region_end; let price = record.price + record.price / 100u32.into() * 2u32.into(); let new_record = AllowedRenewalRecord { begin, price, .. record }; AllowedRenewals::::insert(core, new_record); @@ -647,16 +652,17 @@ pub mod pallet { } pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < status.core_count, Error::::Unavailable); + ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let now = frame_system::Pallet::::block_number(); ensure!(now > sale.sale_start, Error::::TooEarly); let current_price = lerp( now, sale.sale_start, - sale.auction_length, + sale.leadin_length, sale.start_price, sale.reserve_price, ).ok_or(Error::::IndeterminablePrice)?; @@ -666,19 +672,19 @@ pub mod pallet { let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); SaleStatus::::put(&sale); - Self::issue(core, sale.region_begin, sale.region_length, who, Some(current_price)); + Self::issue(core, sale.region_begin, sale.region_end, who, Some(current_price)); Ok(()) } pub(crate) fn issue( core: CoreIndex, begin: Timeslice, - length: Timeslice, + end: Timeslice, owner: T::AccountId, paid: Option>, ) { let id = RegionId { begin, core, part: CorePart::complete() }; - let record = RegionRecord { end: begin + length, owner, paid }; + let record = RegionRecord { end, owner, paid }; Regions::::insert(id, record); } @@ -781,7 +787,7 @@ pub mod pallet { maybe_check_owner: Option, target: ParaId, ) -> Result<(), Error> { - let config = SaleConfig::::get().ok_or(Error::::Uninitialized)?; + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 478379c390b0c..597fdd72bf7ea 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,10 +17,11 @@ #![cfg(test)] -use crate::{*, mock::*, types::*, Error, SaleConfigRecord}; +use crate::{*, mock::*, types::*, Error, ConfigRecord}; use frame_support::{assert_noop, assert_ok, traits::Hooks}; use CoreAssignment::*; use CoretimeTraceItem::*; +use sp_arithmetic::Perbill; fn advance_to(b: u64) { while System::block_number() < b { @@ -32,14 +33,16 @@ fn advance_to(b: u64) { #[test] fn basic_initialize_works() { new_test_ext().execute_with(|| { - assert_ok!(Broker::do_configure(SaleConfigRecord { - presale_length: 1, - auction_length: 3, - ideal_cores_sold: 0, - cores_offered: 0, + assert_ok!(Broker::do_configure(ConfigRecord { + core_count: 10, + advance_notice: 1, + interlude_length: 1, + leadin_length: 3, + ideal_bulk_proportion: Perbill::zero(), + limit_cores_offered: None, region_length: 10, })); - assert_ok!(Broker::do_start_sales(10, 100, 1)); + assert_ok!(Broker::do_start_sales(100)); assert_eq!(CoretimeTrace::get(), vec![]); }); } @@ -47,23 +50,27 @@ fn basic_initialize_works() { #[test] fn initialize_with_system_paras_works() { new_test_ext().execute_with(|| { - assert_ok!(Broker::do_configure(SaleConfigRecord { - presale_length: 1, - auction_length: 3, - ideal_cores_sold: 0, - cores_offered: 0, + assert_ok!(Broker::do_configure(ConfigRecord { + core_count: 10, + advance_notice: 1, + interlude_length: 1, + leadin_length: 3, + ideal_bulk_proportion: Perbill::zero(), + limit_cores_offered: None, region_length: 5, })); let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); - assert_ok!(Broker::do_start_sales(10, 100, 0)); + assert_eq!(Broker::current_schedulable_timeslice(), 1); + + assert_ok!(Broker::do_start_sales(100)); assert_eq!(CoretimeTrace::get(), vec![]); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ - (10, AssignCore { core: 0, begin: 10, assignment: vec![(Task(1), 57600)], end_hint: None }) + (10, AssignCore { core: 0, begin: 12, assignment: vec![(Task(1), 57600)], end_hint: None }) ]); }); } From 3caa44b14793343c3b41f6ee849982efb58777e1 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 14:34:22 +0200 Subject: [PATCH 011/131] Docs --- frame/broker/README.md | 33 ++++++-- frame/broker/src/lib.rs | 172 +++++++++++++++++++++++++++------------- 2 files changed, 142 insertions(+), 63 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index 0a4337903c42f..c386138f7ca94 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -1,15 +1,24 @@ # Pallet Broker -Brokerage tool for managing Polkadot Core scheduling -(TODO add more). +Brokerage tool for managing Polkadot Core scheduling. -# Design Goals +Properly described in RFC-0001 Agile Coretime. -1. TODO +# Implemnentation Specifics -# Design +## The Sale -TODO +``` + 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 +0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 +-------------------------------------------------------- +< interlude > + < sale > + ... of which ... > + < descending-price >< fixed-price > + | <-------\ +price fixed, unsold assigned to instapool, system cores reserved -/ +``` # Examples @@ -21,6 +30,17 @@ fn main() { } ``` +# TODO + +- System Pooling & revenue +- Pool rewards +- Dispatchables + +- Benchmarks +- Weights +- Final docs +- Tests + # License Apache-2.0 @@ -28,3 +48,4 @@ Apache-2.0 # References This crate was auto generated by FRAMY CLI . Please report bugs and build failures at . + diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 5d869782ca9d3..f7c6a8163dff6 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -29,12 +29,6 @@ mod types; pub mod weights; pub use weights::WeightInfo; -/* TODO: -- Advance notice & on_initialize -- Initialization -- Pool rewards -*/ - #[frame_support::pallet] pub mod pallet { use super::*; @@ -59,7 +53,7 @@ pub mod pallet { pub enum CoreAssignment { Idle, Pool, - Task(ParaId), + Task(TaskId), } pub type WholeCoreAssignment = BoundedVec<(CoreAssignment, PartsOf57600), ConstU32<80>>; @@ -102,10 +96,23 @@ pub mod pallet { pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// Weight information for all calls of this pallet. + type WeightInfo: WeightInfo; + + /// Currency used to pay for Coretime. type Currency: Balanced; + /// What to do with any revenues collected from the sale of Coretime. type OnRevenue: OnUnbalanced>; + /// Relay chain's Coretime API used to interact with and instruct the low-level scheduling + /// system. + type Coretime: CoretimeInterface; + + /// Reversible conversion from local balance to Relay-chain balance. This will typically be + /// the `Identity`, but provided just in case the chains use different representations. + type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; + /// Number of Relay-chain blocks per timeslice. #[pallet::constant] type TimeslicePeriod: Get>; @@ -117,82 +124,107 @@ pub mod pallet { /// Maximum number of system cores. #[pallet::constant] type MaxReservedCores: Get; - - /// Reversible conversion from local balance to Relay-chain balance. - type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; - - /// Relay chain's Coretime API - type Coretime: CoretimeInterface; - - /// Weight information for all calls of this pallet. - type WeightInfo: WeightInfo; } pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; pub type RelayBalanceOf = <::Coretime as CoretimeInterface>::Balance; pub type RelayBlockNumberOf = <::Coretime as CoretimeInterface>::BlockNumber; - // Relay-chain block number divided by 80. + /// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. pub type Timeslice = u32; + /// Index of a Polkadot Core. pub type CoreIndex = u16; - pub type RelayAccountId = AccountId32; - pub type Balance = u128; - pub type ParaId = u32; - /// Counter for the total CoreParts which could be dedicated to a pool. `u32` so we don't ever - /// get an overflow. + /// A Task Id. In general this is called a ParachainId. + pub type TaskId = u32; + /// Counter for the total number of set bits over every core's `CorePart`. `u32` so we don't + /// ever get an overflow. pub type PartCount = u32; + /// The same as `PartCount` but signed. pub type SignedPartCount = i32; + /// Self-describing identity for a Region of Bulk Coretime. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct RegionId { + /// The timeslice at which this Region begins. pub begin: Timeslice, + /// The index of the Polakdot Core on which this Region will be scheduled. pub core: CoreIndex, + /// The regularity parts in which this Region will be scheduled. pub part: CorePart, } + /// The rest of the information describing a Region. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct RegionRecord { + /// The end of the Region. end: Timeslice, + /// The owner of the Region. owner: AccountId, + /// The amount paid to Polkadot for this Region. paid: Option, } pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf>; + /// An distinct item which can be scheduled on a Polkadot Core. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ScheduleItem { + /// The regularity parts in which this Item will be scheduled on the Core. pub part: CorePart, + /// The job that the Core should be doing. pub assignment: CoreAssignment, } pub type Schedule = BoundedVec>; + /// Identity of a contributor to the Instantaneous Coretime Pool. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum Contributor { + /// The Polkadot system; revenue collected on its behalf goes to the `Config::OnRevenue` + /// handler. System, + /// A private Bulk Coretime holder; revenue collected may be paid out to them. Private(AccountId), } pub type ContributorOf = Contributor<::AccountId>; + /// The record of a Region which was contributed to the Instantaneous Coretime Pool. This helps + /// with making pro rata payments to contributors. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ContributionRecord { + /// The beginning of the Region contributed. begin: Timeslice, + /// The end of the Region contributed. end: Timeslice, + /// The index of the Polkadot Core contributed. core: CoreIndex, + /// The regularity parts of the Polkadot Core contributed. part: CorePart, + /// The identity of the contributor. payee: Contributor, } pub type ContributionRecordOf = ContributionRecord<::AccountId>; + /// A per-timeslice bookkeeping record for tracking Instantaneous Coretime Pool activity and + /// making proper payments to contributors. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct InstaPoolHistoryRecord { + /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block + /// of a Polkadot Core) contributed over a timeslice minus any contributions which have + /// already been paid out. total_contributions: PartCount, + /// The payout remaining for the `total_contributions`, or `None` if the revenue is not yet + /// known. maybe_payout: Option, } pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; + /// A record of an allowed renewal. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct AllowedRenewalRecord { + /// The timeslice denoting the beginning of the Region for which a renewal can secure. begin: Timeslice, + /// The price for which the next renewal can be made. price: Balance, + /// The workload which will be scheduled on the Core in the case a renewal is made. workload: Schedule, } pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; @@ -200,31 +232,33 @@ pub mod pallet { /// General status of the system. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct StatusRecord { + /// The current size of the Instantaneous Coretime Pool, measured in (measured in + /// Regularity Parts or 1/80th of a single block of a Polkadot Core). pool_size: PartCount, + /// The last (Relay-chain) timeslice which we processed for (this processing is generally + /// done some number of timeslices in advance of actual Relay-chain execution to make up + /// for latencies and any needed Relay-side preparations). last_timeslice: Timeslice, } - /* - SALE: - 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 - -------------------------------------------------------- - < renewals > - < sale > - ... of which ... > - < auction >< fixed-price > - | <-------\ - price fixed, unsold assigned to instapool, system cores reserved -/ - */ - + /// The status of a Bulk Coretime Sale. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct SaleStatusRecord { + pub struct SaleInfoRecord { + /// The local block number at which the sale will/did start. sale_start: BlockNumber, + /// The length in blocks of the Leadin Period (where the price is decreasing). leadin_length: BlockNumber, + /// The price of Bulk Coretime at the beginning of the Leadin Period. start_price: Balance, + /// The price of Bulk Coretime by the end of the Leadin Period. reserve_price: Balance, + /// The first timeslice of the Regions which are being sold in this sale. region_begin: Timeslice, + /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One + /// after the last timeslice which the Regions control.) region_end: Timeslice, + /// The index of the first core which is for sale. Core of Regions which are sold have + /// incrementing indices from this. first_core: CoreIndex, /// The number of cores we want to sell, ideally. Selling this amount would result in no /// change to the reserve_price for the next sale. @@ -234,45 +268,70 @@ pub mod pallet { /// Number of cores which have been sold; never more than cores_offered. cores_sold: CoreIndex, } - pub type SaleStatusRecordOf = SaleStatusRecord< + pub type SaleInfoRecordOf = SaleInfoRecord< BalanceOf, ::BlockNumber, >; + /// Record for Polkadot Core reservations (generally tasked with the maintenance of System + /// Chains). pub type ReservationsRecord = BoundedVec; pub type ReservationsRecordOf = ReservationsRecord<::MaxReservedCores>; - pub type LeasesRecord = BoundedVec<(Timeslice, ParaId), Max>; + /// Record for Polkadot Core legacy leases. + pub type LeasesRecord = BoundedVec<(Timeslice, TaskId), Max>; pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; + /// Configuration of this pallet. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ConfigRecord { + /// The total number of cores which can be assigned (one plus the maximum index which can + /// be used in `Coretime::assign`). pub core_count: CoreIndex, + /// The number of timeslices in advance which scheduling should be fixed and the + /// `Coretime::assign` API used to inform the Relay-chain. pub advance_notice: Timeslice, + /// The length in blocks of the Interlude Period for forthcoming sales. pub interlude_length: BlockNumber, + /// The length in blocks of the Leadin Period for forthcoming sales. pub leadin_length: BlockNumber, + /// The length in timeslices of Regions which are up for sale in forthcoming sales. + pub region_length: Timeslice, + /// The proportion of cores available for sale which should be sold in order for the price + /// to remain the same in the next sale. pub ideal_bulk_proportion: Perbill, + /// An artificial limit to the number of cores which are allowed to be sold. If `Some` then + /// no more cores will be sold than this. pub limit_cores_offered: Option, - pub region_length: Timeslice, } pub type ConfigRecordOf = ConfigRecord< ::BlockNumber, >; + /// The current configuration of this pallet. + #[pallet::storage] + pub type Configuration = StorageValue<_, ConfigRecordOf, OptionQuery>; + + /// The Polkadot Core reservations (generally tasked with the maintenance of System Chains). #[pallet::storage] pub type Reservations = StorageValue<_, ReservationsRecordOf, ValueQuery>; + /// The Polkadot Core legacy leases. #[pallet::storage] pub type Leases = StorageValue<_, LeasesRecordOf, ValueQuery>; + /// The current status of miscellaneous subsystems of this pallet. #[pallet::storage] - pub type AllowedRenewals = StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; + pub type Status = StorageValue<_, StatusRecord, OptionQuery>; + /// The details of the current sale, including its properties and status. #[pallet::storage] - pub type Configuration = StorageValue<_, ConfigRecordOf, OptionQuery>; + pub type SaleInfo = StorageValue<_, SaleInfoRecordOf, OptionQuery>; + /// Records of allowed renewals. #[pallet::storage] - pub type SaleStatus = StorageValue<_, SaleStatusRecordOf, OptionQuery>; + pub type AllowedRenewals = StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; + /// The current (unassigned) Regions. #[pallet::storage] pub type Regions = StorageMap<_, Blake2_128Concat, RegionId, RegionRecordOf, OptionQuery>; @@ -284,12 +343,11 @@ pub mod pallet { #[pallet::storage] pub type Workload = StorageMap<_, Twox64Concat, CoreIndex, Schedule, ValueQuery>; - #[pallet::storage] - pub type Status = StorageValue<_, StatusRecord, OptionQuery>; - + /// Record of a single contribution to the Instantaneous Coretime Pool. #[pallet::storage] pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, ContributionRecordOf, (), OptionQuery>; + /// Record of Coretime entering or leaving the Instantaneous Coretime Pool. #[pallet::storage] pub type InstaPoolIo = StorageMap<_, Blake2_128Concat, Timeslice, SignedPartCount, ValueQuery>; @@ -316,7 +374,7 @@ pub mod pallet { }, Assigned { region_id: RegionId, - task: ParaId, + task: TaskId, }, Dropped { region_id: RegionId, @@ -396,7 +454,7 @@ pub mod pallet { status.last_timeslice.saturating_inc(); Self::process_timeslice(status.last_timeslice, &mut status, &config); - if let Some(sale) = SaleStatus::::get() { + if let Some(sale) = SaleInfo::::get() { if status.last_timeslice >= sale.region_begin { // Sale can be rotated. Self::rotate_sale(status.last_timeslice, sale, &status, &config); @@ -418,7 +476,7 @@ pub mod pallet { }; Status::::put(&status); let now = frame_system::Pallet::::block_number(); - let dummy_sale = SaleStatusRecord { + let dummy_sale = SaleInfoRecord { sale_start: now, leadin_length: Zero::zero(), start_price: Zero::zero(), @@ -462,7 +520,7 @@ pub mod pallet { /// Triggered by Relay-chain block number/timeslice. pub(crate) fn rotate_sale( timeslice: Timeslice, - old_sale: SaleStatusRecordOf, + old_sale: SaleInfoRecordOf, status: &StatusRecord, config: &ConfigRecordOf, ) -> Option<()> { @@ -521,8 +579,8 @@ pub mod pallet { let max_possible_sales = config.core_count.saturating_sub(first_core); let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); let cores_offered = limit_cores_offered.min(max_possible_sales); - // Update SaleStatus - let new_sale = SaleStatusRecord { + // Update SaleInfo + let new_sale = SaleInfoRecord { sale_start: now.saturating_add(config.interlude_length), leadin_length: config.leadin_length, start_price, @@ -534,7 +592,7 @@ pub mod pallet { cores_offered, cores_sold: 0, }; - SaleStatus::::put(&new_sale); + SaleInfo::::put(&new_sale); Some(()) } @@ -630,7 +688,7 @@ pub mod pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; - let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); ensure!(sale.first_core < config.core_count, Error::::Unavailable); @@ -647,14 +705,14 @@ pub mod pallet { let price = record.price + record.price / 100u32.into() * 2u32.into(); let new_record = AllowedRenewalRecord { begin, price, .. record }; AllowedRenewals::::insert(core, new_record); - SaleStatus::::put(&sale); + SaleInfo::::put(&sale); Ok(()) } pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; - let mut sale = SaleStatus::::get().ok_or(Error::::NoSales)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let now = frame_system::Pallet::::block_number(); @@ -671,7 +729,7 @@ pub mod pallet { Self::charge(&who, current_price)?; let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); - SaleStatus::::put(&sale); + SaleInfo::::put(&sale); Self::issue(core, sale.region_begin, sale.region_end, who, Some(current_price)); Ok(()) } @@ -785,7 +843,7 @@ pub mod pallet { pub(crate) fn do_assign( region_id: RegionId, maybe_check_owner: Option, - target: ParaId, + target: TaskId, ) -> Result<(), Error> { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { From 60fb79266a6967ade968ffc38625e535d802634a Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 14:43:51 +0200 Subject: [PATCH 012/131] Timeslice todying --- frame/broker/src/lib.rs | 21 +++++++++++---------- frame/broker/src/mock.rs | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index f7c6a8163dff6..b67058aae1ac5 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -64,7 +64,7 @@ pub mod pallet { fn latest() -> Self::BlockNumber; fn request_core_count(count: CoreIndex); fn request_revenue_info_at(when: Self::BlockNumber); - fn credit_account(who: Self::AccountId, amount: Balance); + fn credit_account(who: Self::AccountId, amount: Self::Balance); fn assign_core( core: CoreIndex, begin: Self::BlockNumber, @@ -81,7 +81,7 @@ pub mod pallet { fn latest() -> Self::BlockNumber { 0 } fn request_core_count(_count: CoreIndex) {} fn request_revenue_info_at(_when: Self::BlockNumber) {} - fn credit_account(_who: Self::AccountId, _amount: Balance) {} + fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} fn assign_core( _core: CoreIndex, _begin: Self::BlockNumber, @@ -446,18 +446,19 @@ pub mod pallet { /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is /// less than `Self::last_timeslice`. pub(crate) fn do_tick() -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let mut status = Status::::get().ok_or(Error::::Uninitialized)?; - - let processable_until = Self::current_schedulable_timeslice(); - ensure!(status.last_timeslice < processable_until, Error::::NothingToDo); + let current_timeslice = Self::current_timeslice(); + ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); status.last_timeslice.saturating_inc(); - Self::process_timeslice(status.last_timeslice, &mut status, &config); + + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let commit_timeslice = status.last_timeslice + config.advance_notice; + Self::process_timeslice(commit_timeslice, &mut status, &config); if let Some(sale) = SaleInfo::::get() { - if status.last_timeslice >= sale.region_begin { + if commit_timeslice >= sale.region_begin { // Sale can be rotated. - Self::rotate_sale(status.last_timeslice, sale, &status, &config); + Self::rotate_sale(commit_timeslice, sale, &status, &config); } } @@ -519,7 +520,7 @@ pub mod pallet { /// /// Triggered by Relay-chain block number/timeslice. pub(crate) fn rotate_sale( - timeslice: Timeslice, + commit_timeslice: Timeslice, old_sale: SaleInfoRecordOf, status: &StatusRecord, config: &ConfigRecordOf, diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 08f6fa4bf6af6..9340951950967 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -90,7 +90,7 @@ impl CoretimeInterface for CoretimeTrace { fn latest() -> Self::BlockNumber { System::block_number() as u32 } fn request_core_count(_count: CoreIndex) {} fn request_revenue_info_at(_when: Self::BlockNumber) {} - fn credit_account(_who: Self::AccountId, _amount: Balance) {} + fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} fn assign_core( core: CoreIndex, begin: Self::BlockNumber, From 036dd961d1695f905da90e534db1810a110ec03f Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 14:49:44 +0200 Subject: [PATCH 013/131] More Timeslice tidying --- frame/broker/src/lib.rs | 27 +++++++++++---------------- frame/broker/src/tests.rs | 2 +- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index b67058aae1ac5..c9d510684e557 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -470,26 +470,26 @@ pub mod pallet { reserve_price: BalanceOf, ) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let current_schedulable_timeslice = Self::current_schedulable_timeslice(); let status = StatusRecord { pool_size: 0, - last_timeslice: current_schedulable_timeslice, + last_timeslice: Self::current_timeslice(), }; Status::::put(&status); + let commit_timeslice = status.last_timeslice + config.advance_notice; let now = frame_system::Pallet::::block_number(); let dummy_sale = SaleInfoRecord { sale_start: now, leadin_length: Zero::zero(), start_price: Zero::zero(), reserve_price, - region_begin: current_schedulable_timeslice, - region_end: current_schedulable_timeslice + config.region_length, + region_begin: commit_timeslice, + region_end: commit_timeslice + config.region_length, first_core: 0, ideal_cores_sold: 0, cores_offered: 0, cores_sold: 0, }; - Self::rotate_sale(current_schedulable_timeslice, dummy_sale, &status, &config); + Self::rotate_sale(commit_timeslice, dummy_sale, &status, &config); Ok(()) } @@ -611,14 +611,6 @@ pub mod pallet { (latest / timeslice_period).saturated_into() } - pub(crate) fn current_schedulable_timeslice() -> Timeslice { - Self::current_timeslice() + Configuration::::get().map_or(0, |x| x.advance_notice) - } - - pub(crate) fn next_schedulable_timeslice() -> Timeslice { - Self::current_schedulable_timeslice().saturating_add(1) - } - pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, config: &ConfigRecordOf) { Self::process_pool(timeslice, status); let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); @@ -821,15 +813,18 @@ pub mod pallet { mut region_id: RegionId, maybe_check_owner: Option, ) -> Result)>, Error> { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; if let Some(check_owner) = maybe_check_owner { ensure!(check_owner == region.owner, Error::::NotOwner); } - let next_timeslice = Self::next_schedulable_timeslice(); - if region_id.begin > next_timeslice { - region_id.begin = next_timeslice; + let last_commit_timeslice = status.last_timeslice + config.advance_notice; + if region_id.begin <= last_commit_timeslice { + region_id.begin = last_commit_timeslice + 1; } Regions::::remove(®ion_id); diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 597fdd72bf7ea..3c4836c1f96b5 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -63,7 +63,7 @@ fn initialize_with_system_paras_works() { let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); - assert_eq!(Broker::current_schedulable_timeslice(), 1); + assert_eq!(Broker::current_timeslice(), 0); assert_ok!(Broker::do_start_sales(100)); assert_eq!(CoretimeTrace::get(), vec![]); From 8d299cab9b3b8ab88d0b260b726c778e09ef37ad Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 15:30:21 +0200 Subject: [PATCH 014/131] Tests] --- frame/broker/src/tests.rs | 17 ++++++++-- frame/broker/src/types.rs | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 3c4836c1f96b5..e27343e3f1f83 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -51,7 +51,7 @@ fn basic_initialize_works() { fn initialize_with_system_paras_works() { new_test_ext().execute_with(|| { assert_ok!(Broker::do_configure(ConfigRecord { - core_count: 10, + core_count: 3, advance_notice: 1, interlude_length: 1, leadin_length: 3, @@ -62,6 +62,12 @@ fn initialize_with_system_paras_works() { let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); + let items = vec![ + ScheduleItem { assignment: Task(2u32), part: 0xfffff_fffff_00000_00000.into() }, + ScheduleItem { assignment: Task(3u32), part: 0x00000_00000_fffff_00000.into() }, + ScheduleItem { assignment: Task(4u32), part: 0x00000_00000_00000_fffff.into() }, + ]; + assert_ok!(Broker::do_reserve(Schedule::truncate_from(items))); assert_eq!(Broker::current_timeslice(), 0); @@ -70,7 +76,14 @@ fn initialize_with_system_paras_works() { advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ - (10, AssignCore { core: 0, begin: 12, assignment: vec![(Task(1), 57600)], end_hint: None }) + (10, AssignCore { core: 0, begin: 12, assignment: vec![ + (Task(1), 57600), + ], end_hint: None }), + (10, AssignCore { core: 1, begin: 12, assignment: vec![ + (Task(2), 28800), + (Task(3), 14400), + (Task(4), 14400), + ], end_hint: None }), ]); }); } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index f0efecbbdf917..9c75d40229af4 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -19,12 +19,40 @@ impl CorePart { pub fn is_complete(&self) -> bool { &self.0 == &[255u8; 10] } + pub fn set(&mut self, i: u32) -> Self { + if i < 80 { + self.0[(i / 8) as usize] |= (128 >> (i % 8)); + } + *self + } + pub fn clear(&mut self, i: u32) -> Self { + if i < 80 { + self.0[(i / 8) as usize] &= !(128 >> (i % 8)); + } + *self + } pub fn count_zeros(&self) -> u32 { self.0.iter().map(|i| i.count_zeros()).sum() } pub fn count_ones(&self) -> u32 { self.0.iter().map(|i| i.count_ones()).sum() } + pub fn from_chunk(from: u32, to: u32) -> Self { + let mut v = [0u8; 10]; + for i in (from.min(80) as usize)..(to.min(80) as usize) { + v[i / 8] |= (128 >> (i % 8)); + } + Self(v) + } +} +impl From for CorePart { + fn from(x: u128) -> Self { + let mut v = [0u8; 10]; + for i in 0..10 { + v[i] = (x >> (72 - 8 * i)) as u8; + } + Self(v) + } } impl BitAnd for CorePart { type Output = Self; @@ -87,3 +115,43 @@ impl Not for CorePart { Self(result) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn complete_works() { + assert_eq!(CorePart::complete(), CorePart([0xff; 10])); + assert!(CorePart([0xff; 10]).is_complete()); + for i in 0..80 { + assert!(!CorePart([0xff; 10]).clear(i).is_complete()); + } + } + + #[test] + fn void_works() { + assert_eq!(CorePart::void(), CorePart([0; 10])); + assert!(CorePart([0; 10]).is_void()); + for i in 0..80 { + assert!(!(CorePart([0; 10]).set(i).is_void())); + } + } + + #[test] + fn from_works() { + assert!(CorePart::from(0xfffff_fffff_fffff_fffff).is_complete()); + assert_eq!( + CorePart::from(0x12345_67890_abcde_f0123), + CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]), + ); + } + + #[test] + fn chunk_works() { + assert_eq!( + CorePart::from_chunk(40, 60), + CorePart::from(0x00000_00000_fffff_00000), + ); + } +} \ No newline at end of file From 99de31faf0cfa5a647c85ad5d0716d24bf8483e4 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 16:01:34 +0200 Subject: [PATCH 015/131] Repotting. --- frame/broker/Cargo.toml | 4 +- frame/broker/src/core_part.rs | 157 ++++++ frame/broker/src/coretime_interface.rs | 60 ++ frame/broker/src/implementation.rs | 470 ++++++++++++++++ frame/broker/src/lib.rs | 727 +------------------------ frame/broker/src/mock.rs | 4 +- frame/broker/src/test_fungibles.rs | 6 +- frame/broker/src/tests.rs | 2 +- frame/broker/src/types.rs | 314 ++++++----- frame/broker/src/utils.rs | 14 + 10 files changed, 893 insertions(+), 865 deletions(-) create mode 100644 frame/broker/src/core_part.rs create mode 100644 frame/broker/src/coretime_interface.rs create mode 100644 frame/broker/src/implementation.rs create mode 100644 frame/broker/src/utils.rs diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index 8a79e9064e67a..af05d2d65a450 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -17,14 +17,14 @@ scale-info = { version = "2.0.0", default-features = false, features = ["derive" bitvec = "1" sp-std = { version = "8.0.0", path = "../../primitives/std" } sp-arithmetic = { version = "16.0.0", path = "../../primitives/arithmetic" } +sp-core = { version = "21.0.0", path = "../../primitives/core" } +sp-runtime = { version = "24.0.0", path = "../../primitives/runtime" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } [dev-dependencies] -sp-core = { version = "21.0.0", path = "../../primitives/core" } sp-io = { version = "23.0.0", path = "../../primitives/io" } -sp-runtime = { version = "24.0.0", path = "../../primitives/runtime" } [features] default = ["std"] diff --git a/frame/broker/src/core_part.rs b/frame/broker/src/core_part.rs new file mode 100644 index 0000000000000..2c15512294db7 --- /dev/null +++ b/frame/broker/src/core_part.rs @@ -0,0 +1,157 @@ +use codec::{Encode, Decode, MaxEncodedLen}; +use scale_info::TypeInfo; +use sp_core::RuntimeDebug; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; + +// TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. +#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct CorePart([u8; 10]); +impl CorePart { + pub fn void() -> Self { + Self([0u8; 10]) + } + pub fn complete() -> Self { + Self([255u8; 10]) + } + pub fn is_void(&self) -> bool { + &self.0 == &[0u8; 10] + } + pub fn is_complete(&self) -> bool { + &self.0 == &[255u8; 10] + } + pub fn set(&mut self, i: u32) -> Self { + if i < 80 { + self.0[(i / 8) as usize] |= 128 >> (i % 8); + } + *self + } + pub fn clear(&mut self, i: u32) -> Self { + if i < 80 { + self.0[(i / 8) as usize] &= !(128 >> (i % 8)); + } + *self + } + pub fn count_zeros(&self) -> u32 { + self.0.iter().map(|i| i.count_zeros()).sum() + } + pub fn count_ones(&self) -> u32 { + self.0.iter().map(|i| i.count_ones()).sum() + } + pub fn from_chunk(from: u32, to: u32) -> Self { + let mut v = [0u8; 10]; + for i in (from.min(80) as usize)..(to.min(80) as usize) { + v[i / 8] |= 128 >> (i % 8); + } + Self(v) + } +} +impl From for CorePart { + fn from(x: u128) -> Self { + let mut v = [0u8; 10]; + for i in 0..10 { + v[i] = (x >> (72 - 8 * i)) as u8; + } + Self(v) + } +} +impl BitAnd for CorePart { + type Output = Self; + fn bitand(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitand(rhs.0[i]); + } + Self(result) + } +} +impl BitAndAssign for CorePart { + fn bitand_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitand_assign(rhs.0[i]); + } + } +} +impl BitOr for CorePart { + type Output = Self; + fn bitor(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitor(rhs.0[i]); + } + Self(result) + } +} +impl BitOrAssign for CorePart { + fn bitor_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitor_assign(rhs.0[i]); + } + } +} +impl BitXor for CorePart { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].bitxor(rhs.0[i]); + } + Self(result) + } +} +impl BitXorAssign for CorePart { + fn bitxor_assign(&mut self, rhs: Self) { + for i in 0..10 { + self.0[i].bitxor_assign(rhs.0[i]); + } + } +} +impl Not for CorePart { + type Output = Self; + fn not(self) -> Self { + let mut result = [0u8; 10]; + for i in 0..10 { + result[i] = self.0[i].not(); + } + Self(result) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn complete_works() { + assert_eq!(CorePart::complete(), CorePart([0xff; 10])); + assert!(CorePart([0xff; 10]).is_complete()); + for i in 0..80 { + assert!(!CorePart([0xff; 10]).clear(i).is_complete()); + } + } + + #[test] + fn void_works() { + assert_eq!(CorePart::void(), CorePart([0; 10])); + assert!(CorePart([0; 10]).is_void()); + for i in 0..80 { + assert!(!(CorePart([0; 10]).set(i).is_void())); + } + } + + #[test] + fn from_works() { + assert!(CorePart::from(0xfffff_fffff_fffff_fffff).is_complete()); + assert_eq!( + CorePart::from(0x12345_67890_abcde_f0123), + CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]), + ); + } + + #[test] + fn chunk_works() { + assert_eq!( + CorePart::from_chunk(40, 60), + CorePart::from(0x00000_00000_fffff_00000), + ); + } +} \ No newline at end of file diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs new file mode 100644 index 0000000000000..96a379e86ca08 --- /dev/null +++ b/frame/broker/src/coretime_interface.rs @@ -0,0 +1,60 @@ +use codec::{Encode, MaxEncodedLen, Decode}; +use frame_support::Parameter; +use scale_info::TypeInfo; +use sp_arithmetic::traits::AtLeast32BitUnsigned; +use sp_core::RuntimeDebug; + +/// Index of a Polkadot Core. +pub type CoreIndex = u16; + +/// A Task Id. In general this is called a ParachainId. +pub type TaskId = u32; + +/// Fraction expressed as a nominator with an assumed denominator of 57,600. +pub type PartsOf57600 = u16; + +/// An element to which a core can be assigned. +#[derive(Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum CoreAssignment { + /// Core need not be used for anything. + Idle, + /// Core should be used for the Instantaneous Coretime Pool. + Pool, + /// Core should be used to process the given task. + Task(TaskId), +} + +pub trait CoretimeInterface { + type AccountId: Parameter; + type Balance; + type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode; + fn latest() -> Self::BlockNumber; + fn request_core_count(count: CoreIndex); + fn request_revenue_info_at(when: Self::BlockNumber); + fn credit_account(who: Self::AccountId, amount: Self::Balance); + fn assign_core( + core: CoreIndex, + begin: Self::BlockNumber, + assignment: Vec<(CoreAssignment, PartsOf57600)>, + end_hint: Option, + ); + fn check_notify_core_count() -> Option; + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)>; +} +impl CoretimeInterface for () { + type AccountId = (); + type Balance = u64; + type BlockNumber = u32; + fn latest() -> Self::BlockNumber { 0 } + fn request_core_count(_count: CoreIndex) {} + fn request_revenue_info_at(_when: Self::BlockNumber) {} + fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} + fn assign_core( + _core: CoreIndex, + _begin: Self::BlockNumber, + _assignment: Vec<(CoreAssignment, PartsOf57600)>, + _end_hint: Option, + ) {} + fn check_notify_core_count() -> Option { None } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } +} diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs new file mode 100644 index 0000000000000..e8a4b189fd107 --- /dev/null +++ b/frame/broker/src/implementation.rs @@ -0,0 +1,470 @@ +use super::*; +use frame_support::{ + pallet_prelude::{*, DispatchResult}, + traits::{ + tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, + fungible::Balanced, OnUnbalanced + } +}; +use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; + +impl Pallet { + pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { + Configuration::::put(config); + Ok(()) + } + + /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is + /// less than `Self::last_timeslice`. + pub(crate) fn do_tick() -> DispatchResult { + let mut status = Status::::get().ok_or(Error::::Uninitialized)?; + let current_timeslice = Self::current_timeslice(); + ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); + status.last_timeslice.saturating_inc(); + + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let commit_timeslice = status.last_timeslice + config.advance_notice; + Self::process_timeslice(commit_timeslice, &mut status, &config); + + if let Some(sale) = SaleInfo::::get() { + if commit_timeslice >= sale.region_begin { + // Sale can be rotated. + Self::rotate_sale(sale, &config); + } + } + + Status::::put(&status); + Ok(()) + } + + pub(crate) fn do_start_sales( + reserve_price: BalanceOf, + ) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = StatusRecord { + pool_size: 0, + last_timeslice: Self::current_timeslice(), + }; + Status::::put(&status); + let commit_timeslice = status.last_timeslice + config.advance_notice; + let now = frame_system::Pallet::::block_number(); + let dummy_sale = SaleInfoRecord { + sale_start: now, + leadin_length: Zero::zero(), + start_price: Zero::zero(), + reserve_price, + region_begin: commit_timeslice, + region_end: commit_timeslice + config.region_length, + first_core: 0, + ideal_cores_sold: 0, + cores_offered: 0, + cores_sold: 0, + }; + Self::rotate_sale(dummy_sale, &config); + Ok(()) + } + + fn bump_price( + offered: CoreIndex, + ideal: CoreIndex, + sold: CoreIndex, + old: BalanceOf, + ) -> BalanceOf { + if sold > ideal { + let extra = if offered > ideal { + Perbill::from_rational((sold - ideal) as u32, (offered - ideal) as u32) + } else { + Perbill::zero() + }; + old + extra * old + } else { + let extra = if ideal > 0 { + Perbill::from_rational(sold as u32, ideal as u32).left_from_one() + } else { + Perbill::zero() + }; + old - extra * old + } + } + + /// Begin selling for the next sale period. + /// + /// Triggered by Relay-chain block number/timeslice. + pub(crate) fn rotate_sale( + old_sale: SaleInfoRecordOf, + config: &ConfigRecordOf, + ) -> Option<()> { + let now = frame_system::Pallet::::block_number(); + + // Calculate the start price for the sale after. + let reserve_price = { + let core_count = config.core_count; + let max_retail = core_count.saturating_sub(old_sale.first_core); + let offered = old_sale.cores_offered.min(max_retail); + let ideal = old_sale.ideal_cores_sold.min(max_retail); + let sold = old_sale.cores_sold; + let old_price = old_sale.reserve_price; + if offered > 0 { + Self::bump_price(offered, ideal, sold, old_price) + } else { + old_price + } + }; + let start_price = reserve_price * 2u32.into(); + + // TODO: commission system InstaPool cores. + + // Set workload for the reserved (system, probably) workloads. + let region_begin = old_sale.region_end; + let region_end = region_begin + config.region_length; + + let mut first_core = 0; + for schedule in Reservations::::get().into_iter() { + Workplan::::insert((region_begin, first_core), schedule); + first_core.saturating_inc(); + } + + let mut leases = Leases::::get(); + // can morph to a renewable as long as it's > begin and < end. + leases.retain(|&(until, para)| { + let part = CorePart::complete(); + let assignment = CoreAssignment::Task(para); + let schedule = BoundedVec::truncate_from(vec![ScheduleItem { part, assignment }]); + Workplan::::insert((region_begin, first_core), &schedule); + let expiring = until >= region_begin; + if expiring { + // last time for this one - make it renewable. + let record = AllowedRenewalRecord { + begin: region_end, + price: reserve_price, + workload: schedule, + }; + AllowedRenewals::::insert(first_core, record); + } + first_core.saturating_inc(); + !expiring + }); + Leases::::put(&leases); + + let max_possible_sales = config.core_count.saturating_sub(first_core); + let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); + let cores_offered = limit_cores_offered.min(max_possible_sales); + // Update SaleInfo + let new_sale = SaleInfoRecord { + sale_start: now.saturating_add(config.interlude_length), + leadin_length: config.leadin_length, + start_price, + reserve_price, + region_begin, + region_end, + first_core, + ideal_cores_sold: (config.ideal_bulk_proportion * cores_offered as u32) as u16, + cores_offered, + cores_sold: 0, + }; + SaleInfo::::put(&new_sale); + + Some(()) + } + + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { + let mut r = Reservations::::get(); + r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; + Reservations::::put(r); + Ok(()) + } + + pub(crate) fn current_timeslice() -> Timeslice { + let latest = T::Coretime::latest(); + let timeslice_period = T::TimeslicePeriod::get(); + (latest / timeslice_period).saturated_into() + } + + pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, config: &ConfigRecordOf) { + Self::process_pool(timeslice, status); + let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); + for core in 0..config.core_count { + Self::process_core_schedule(timeslice, rc_begin, core); + } + } + + fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { + let pool_io = InstaPoolIo::::take(timeslice); + status.pool_size = (status.pool_size as i32).saturating_add(pool_io) as u32; + let record = InstaPoolHistoryRecord { + total_contributions: status.pool_size, + maybe_payout: None, + }; + InstaPoolHistory::::insert(timeslice, record); + } + + /// Schedule cores for the given `timeslice`. + fn process_core_schedule( + timeslice: Timeslice, + rc_begin: RelayBlockNumberOf, + core: CoreIndex, + ) { + let workplan = match Workplan::::take((timeslice, core)) { + Some(w) => w, + None => return, + }; + let workload = Workload::::get(core); + let parts_used = workplan.iter().map(|i| i.part).fold(CorePart::void(), |a, i| a | i); + let mut workplan = workplan.into_inner(); + workplan.extend(workload.into_iter().filter(|i| (i.part & parts_used).is_void())); + let workplan = Schedule::truncate_from(workplan); + Workload::::insert(core, &workplan); + + let mut total_used = 0; + let mut intermediate = workplan + .into_iter() + .map(|i| (i.assignment, i.part.count_ones() as u16 * (57_600 / 80))) + .inspect(|i| total_used += i.1) + .collect::>(); + if total_used < 80 { + intermediate.push((CoreAssignment::Idle, 80 - total_used)); + } + intermediate.sort(); + let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = Vec::with_capacity(intermediate.len()); + for i in intermediate.into_iter() { + if let Some(ref mut last) = assignment.last_mut() { + if last.0 == i.0 { + last.1 += i.1; + continue; + } + } + assignment.push(i); + } + T::Coretime::assign_core(core, rc_begin, assignment, None); + } + + fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + T::OnRevenue::on_unbalanced(T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?); + Ok(()) + } + + /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the + /// current sale status's `region_end`. + pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + + ensure!(record.begin == sale.region_begin, Error::::WrongTime); + ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + + Self::charge(who, record.price)?; + + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + + Workplan::::insert((record.begin, core), &record.workload); + + let begin = sale.region_end; + let price = record.price + record.price / 100u32.into() * 2u32.into(); + let new_record = AllowedRenewalRecord { begin, price, .. record }; + AllowedRenewals::::insert(core, new_record); + SaleInfo::::put(&sale); + Ok(()) + } + + pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + let now = frame_system::Pallet::::block_number(); + ensure!(now > sale.sale_start, Error::::TooEarly); + let current_price = lerp( + now, + sale.sale_start, + sale.leadin_length, + sale.start_price, + sale.reserve_price, + ).ok_or(Error::::IndeterminablePrice)?; + ensure!(price_limit >= current_price, Error::::Overpriced); + + Self::charge(&who, current_price)?; + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + SaleInfo::::put(&sale); + Self::issue(core, sale.region_begin, sale.region_end, who, Some(current_price)); + Ok(()) + } + + pub(crate) fn issue( + core: CoreIndex, + begin: Timeslice, + end: Timeslice, + owner: T::AccountId, + paid: Option>, + ) { + let id = RegionId { begin, core, part: CorePart::complete() }; + let record = RegionRecord { end, owner, paid }; + Regions::::insert(id, record); + } + + pub(crate) fn do_transfer( + region_id: RegionId, + maybe_check_owner: Option, + new_owner: T::AccountId, + ) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + let old_owner = region.owner; + region.owner = new_owner; + Regions::::insert(®ion_id, ®ion); + Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); + + Ok(()) + } + + pub(crate) fn do_partition( + region_id: RegionId, + maybe_check_owner: Option, + pivot: Timeslice, + ) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + ensure!(pivot > region_id.begin, Error::::PivotTooEarly); + ensure!(pivot < region.end, Error::::PivotTooLate); + + region.paid = None; + let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; + let new_region = RegionRecord { end: pivot, ..region.clone() }; + + Regions::::insert(®ion_id, &new_region); + Regions::::insert(&new_region_id, ®ion); + Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); + + Ok(()) + } + + pub(crate) fn do_interlace( + mut region_id: RegionId, + maybe_check_owner: Option, + pivot: CorePart, + ) -> Result<(), Error> { + let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); + ensure!(!pivot.is_void(), Error::::NullPivot); + ensure!(pivot != region_id.part, Error::::CompletePivot); + + let antipivot = region_id.part ^ pivot; + region_id.part = pivot; + Regions::::insert(®ion_id, ®ion); + region_id.part = antipivot; + Regions::::insert(®ion_id, ®ion); + + Self::deposit_event(Event::Interlaced { region_id, pivot }); + + Ok(()) + } + + pub(crate) fn utilize( + mut region_id: RegionId, + maybe_check_owner: Option, + ) -> Result)>, Error> { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + let last_commit_timeslice = status.last_timeslice + config.advance_notice; + if region_id.begin <= last_commit_timeslice { + region_id.begin = last_commit_timeslice + 1; + } + Regions::::remove(®ion_id); + + if region_id.begin < region.end { + Ok(Some((region_id, region))) + } else { + Self::deposit_event(Event::Dropped { region_id }); + Ok(None) + } + } + + pub(crate) fn do_assign( + region_id: RegionId, + maybe_check_owner: Option, + target: TaskId, + ) -> Result<(), Error> { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + assignment: CoreAssignment::Task(target), + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + } + if region.end.saturating_sub(region_id.begin) == config.region_length { + if workplan.iter() + .filter(|i| matches!(i.assignment, CoreAssignment::Task(..))) + .fold(CorePart::void(), |a, i| a | i.part) + .is_complete() + { + if let Some(price) = region.paid { + let record = AllowedRenewalRecord { + begin: region.end, + price, + workload: workplan, + }; + AllowedRenewals::::insert(region_id.core, &record); + } + } + } + Self::deposit_event(Event::Assigned { region_id, task: target }); + } + Ok(()) + } + + pub(crate) fn do_pool( + region_id: RegionId, + maybe_check_owner: Option, + payee: T::AccountId, + ) -> Result<(), Error> { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + assignment: CoreAssignment::Pool, + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + InstaPoolIo::::mutate(region_id.begin, |a| *a += region_id.part.count_ones() as i32); + InstaPoolIo::::mutate(region.end, |a| *a -= region_id.part.count_ones() as i32); + let contrib = ContributionRecord { + begin: region_id.begin, + end: region.end, + core: region_id.core, + part: region_id.part, + payee: Contributor::Private(payee), + }; + InstaPoolContribution::::insert(&contrib, ()); + } + Self::deposit_event(Event::Pooled { region_id }); + } + Ok(()) + } +} \ No newline at end of file diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index c9d510684e557..0e4def2453c4a 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -24,74 +24,33 @@ mod mock; mod tests; mod benchmarking; mod test_fungibles; +mod core_part; mod types; +mod coretime_interface; +mod utils; +mod implementation; pub mod weights; pub use weights::WeightInfo; +pub use types::*; +pub use core_part::*; +pub use coretime_interface::*; +pub use utils::*; + #[frame_support::pallet] pub mod pallet { use super::*; use frame_support::{ pallet_prelude::{*, DispatchResult}, - traits::{ - tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, - fungible::{self, Credit, Inspect, Balanced, HandleImbalanceDrop}, OnUnbalanced - } + traits::{fungible::{Credit, Balanced}, OnUnbalanced}, }; use frame_system::pallet_prelude::*; - use sp_runtime::{AccountId32, traits::{ConvertBack, Convert}, DispatchError}; - use sp_arithmetic::{traits::{Zero, Bounded, AtLeast32BitUnsigned, SaturatedConversion, Saturating, BaseArithmetic}, Perbill, PerThing}; - use types::CorePart; + use sp_runtime::traits::{ConvertBack, Convert}; #[pallet::pallet] pub struct Pallet(_); - pub type PartsOf57600 = u16; - - #[derive(Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub enum CoreAssignment { - Idle, - Pool, - Task(TaskId), - } - pub type WholeCoreAssignment = BoundedVec<(CoreAssignment, PartsOf57600), ConstU32<80>>; - - pub trait CoretimeInterface { - type AccountId: Parameter; - type Balance; - type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode; - fn latest() -> Self::BlockNumber; - fn request_core_count(count: CoreIndex); - fn request_revenue_info_at(when: Self::BlockNumber); - fn credit_account(who: Self::AccountId, amount: Self::Balance); - fn assign_core( - core: CoreIndex, - begin: Self::BlockNumber, - assignment: Vec<(CoreAssignment, PartsOf57600)>, - end_hint: Option, - ); - fn check_notify_core_count() -> Option; - fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)>; - } - impl CoretimeInterface for () { - type AccountId = (); - type Balance = u64; - type BlockNumber = u32; - fn latest() -> Self::BlockNumber { 0 } - fn request_core_count(_count: CoreIndex) {} - fn request_revenue_info_at(_when: Self::BlockNumber) {} - fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} - fn assign_core( - _core: CoreIndex, - _begin: Self::BlockNumber, - _assignment: Vec<(CoreAssignment, PartsOf57600)>, - _end_hint: Option, - ) {} - fn check_notify_core_count() -> Option { None } - fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } - } - #[pallet::config] pub trait Config: frame_system::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; @@ -126,187 +85,6 @@ pub mod pallet { type MaxReservedCores: Get; } - pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; - pub type RelayBalanceOf = <::Coretime as CoretimeInterface>::Balance; - pub type RelayBlockNumberOf = <::Coretime as CoretimeInterface>::BlockNumber; - - /// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. - pub type Timeslice = u32; - /// Index of a Polkadot Core. - pub type CoreIndex = u16; - /// A Task Id. In general this is called a ParachainId. - pub type TaskId = u32; - /// Counter for the total number of set bits over every core's `CorePart`. `u32` so we don't - /// ever get an overflow. - pub type PartCount = u32; - /// The same as `PartCount` but signed. - pub type SignedPartCount = i32; - - /// Self-describing identity for a Region of Bulk Coretime. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct RegionId { - /// The timeslice at which this Region begins. - pub begin: Timeslice, - /// The index of the Polakdot Core on which this Region will be scheduled. - pub core: CoreIndex, - /// The regularity parts in which this Region will be scheduled. - pub part: CorePart, - } - - /// The rest of the information describing a Region. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct RegionRecord { - /// The end of the Region. - end: Timeslice, - /// The owner of the Region. - owner: AccountId, - /// The amount paid to Polkadot for this Region. - paid: Option, - } - pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf>; - - /// An distinct item which can be scheduled on a Polkadot Core. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct ScheduleItem { - /// The regularity parts in which this Item will be scheduled on the Core. - pub part: CorePart, - /// The job that the Core should be doing. - pub assignment: CoreAssignment, - } - pub type Schedule = BoundedVec>; - - /// Identity of a contributor to the Instantaneous Coretime Pool. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub enum Contributor { - /// The Polkadot system; revenue collected on its behalf goes to the `Config::OnRevenue` - /// handler. - System, - /// A private Bulk Coretime holder; revenue collected may be paid out to them. - Private(AccountId), - } - pub type ContributorOf = Contributor<::AccountId>; - - /// The record of a Region which was contributed to the Instantaneous Coretime Pool. This helps - /// with making pro rata payments to contributors. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct ContributionRecord { - /// The beginning of the Region contributed. - begin: Timeslice, - /// The end of the Region contributed. - end: Timeslice, - /// The index of the Polkadot Core contributed. - core: CoreIndex, - /// The regularity parts of the Polkadot Core contributed. - part: CorePart, - /// The identity of the contributor. - payee: Contributor, - } - pub type ContributionRecordOf = ContributionRecord<::AccountId>; - - /// A per-timeslice bookkeeping record for tracking Instantaneous Coretime Pool activity and - /// making proper payments to contributors. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct InstaPoolHistoryRecord { - /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block - /// of a Polkadot Core) contributed over a timeslice minus any contributions which have - /// already been paid out. - total_contributions: PartCount, - /// The payout remaining for the `total_contributions`, or `None` if the revenue is not yet - /// known. - maybe_payout: Option, - } - pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; - - /// A record of an allowed renewal. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct AllowedRenewalRecord { - /// The timeslice denoting the beginning of the Region for which a renewal can secure. - begin: Timeslice, - /// The price for which the next renewal can be made. - price: Balance, - /// The workload which will be scheduled on the Core in the case a renewal is made. - workload: Schedule, - } - pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; - - /// General status of the system. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct StatusRecord { - /// The current size of the Instantaneous Coretime Pool, measured in (measured in - /// Regularity Parts or 1/80th of a single block of a Polkadot Core). - pool_size: PartCount, - /// The last (Relay-chain) timeslice which we processed for (this processing is generally - /// done some number of timeslices in advance of actual Relay-chain execution to make up - /// for latencies and any needed Relay-side preparations). - last_timeslice: Timeslice, - } - - /// The status of a Bulk Coretime Sale. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct SaleInfoRecord { - /// The local block number at which the sale will/did start. - sale_start: BlockNumber, - /// The length in blocks of the Leadin Period (where the price is decreasing). - leadin_length: BlockNumber, - /// The price of Bulk Coretime at the beginning of the Leadin Period. - start_price: Balance, - /// The price of Bulk Coretime by the end of the Leadin Period. - reserve_price: Balance, - /// The first timeslice of the Regions which are being sold in this sale. - region_begin: Timeslice, - /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One - /// after the last timeslice which the Regions control.) - region_end: Timeslice, - /// The index of the first core which is for sale. Core of Regions which are sold have - /// incrementing indices from this. - first_core: CoreIndex, - /// The number of cores we want to sell, ideally. Selling this amount would result in no - /// change to the reserve_price for the next sale. - ideal_cores_sold: CoreIndex, - /// Number of cores which are/have been offered for sale. - cores_offered: CoreIndex, - /// Number of cores which have been sold; never more than cores_offered. - cores_sold: CoreIndex, - } - pub type SaleInfoRecordOf = SaleInfoRecord< - BalanceOf, - ::BlockNumber, - >; - - /// Record for Polkadot Core reservations (generally tasked with the maintenance of System - /// Chains). - pub type ReservationsRecord = BoundedVec; - pub type ReservationsRecordOf = ReservationsRecord<::MaxReservedCores>; - /// Record for Polkadot Core legacy leases. - pub type LeasesRecord = BoundedVec<(Timeslice, TaskId), Max>; - pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; - - /// Configuration of this pallet. - #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - pub struct ConfigRecord { - /// The total number of cores which can be assigned (one plus the maximum index which can - /// be used in `Coretime::assign`). - pub core_count: CoreIndex, - /// The number of timeslices in advance which scheduling should be fixed and the - /// `Coretime::assign` API used to inform the Relay-chain. - pub advance_notice: Timeslice, - /// The length in blocks of the Interlude Period for forthcoming sales. - pub interlude_length: BlockNumber, - /// The length in blocks of the Leadin Period for forthcoming sales. - pub leadin_length: BlockNumber, - /// The length in timeslices of Regions which are up for sale in forthcoming sales. - pub region_length: Timeslice, - /// The proportion of cores available for sale which should be sold in order for the price - /// to remain the same in the next sale. - pub ideal_bulk_proportion: Perbill, - /// An artificial limit to the number of cores which are allowed to be sold. If `Some` then - /// no more cores will be sold than this. - pub limit_cores_offered: Option, - } - pub type ConfigRecordOf = ConfigRecord< - ::BlockNumber, - >; - /// The current configuration of this pallet. #[pallet::storage] pub type Configuration = StorageValue<_, ConfigRecordOf, OptionQuery>; @@ -409,8 +187,8 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { - fn on_initialize(now: T::BlockNumber) -> Weight { - Self::do_tick(); + fn on_initialize(_now: T::BlockNumber) -> Weight { + let _ = Self::do_tick(); Weight::zero() } } @@ -424,483 +202,4 @@ pub mod pallet { Ok(()) } } - - fn lerp, S: TryInto + TryFrom + Bounded>(v: T, a: T, d: T, x: S, y: S) -> Option { - use sp_arithmetic::{Rounding::NearestPrefUp, helpers_128bit::multiply_by_rational_with_rounding}; - let v: u128 = v.try_into().ok()?; - let a: u128 = a.try_into().ok()?; - let d: u128 = d.try_into().ok()?; - let r: u128 = x.try_into().ok()?; - let s: u128 = y.try_into().ok()?; - let rsd = r.max(s) - r.min(s); - let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; - if r < s { r + td } else { r - td }.try_into().ok() - } - - impl Pallet { - pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { - Configuration::::put(config); - Ok(()) - } - - /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is - /// less than `Self::last_timeslice`. - pub(crate) fn do_tick() -> DispatchResult { - let mut status = Status::::get().ok_or(Error::::Uninitialized)?; - let current_timeslice = Self::current_timeslice(); - ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); - status.last_timeslice.saturating_inc(); - - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let commit_timeslice = status.last_timeslice + config.advance_notice; - Self::process_timeslice(commit_timeslice, &mut status, &config); - - if let Some(sale) = SaleInfo::::get() { - if commit_timeslice >= sale.region_begin { - // Sale can be rotated. - Self::rotate_sale(commit_timeslice, sale, &status, &config); - } - } - - Status::::put(&status); - Ok(()) - } - - pub(crate) fn do_start_sales( - reserve_price: BalanceOf, - ) -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let status = StatusRecord { - pool_size: 0, - last_timeslice: Self::current_timeslice(), - }; - Status::::put(&status); - let commit_timeslice = status.last_timeslice + config.advance_notice; - let now = frame_system::Pallet::::block_number(); - let dummy_sale = SaleInfoRecord { - sale_start: now, - leadin_length: Zero::zero(), - start_price: Zero::zero(), - reserve_price, - region_begin: commit_timeslice, - region_end: commit_timeslice + config.region_length, - first_core: 0, - ideal_cores_sold: 0, - cores_offered: 0, - cores_sold: 0, - }; - Self::rotate_sale(commit_timeslice, dummy_sale, &status, &config); - Ok(()) - } - - fn bump_price( - offered: CoreIndex, - ideal: CoreIndex, - sold: CoreIndex, - old: BalanceOf, - ) -> BalanceOf { - if sold > ideal { - let extra = if offered > ideal { - Perbill::from_rational((sold - ideal) as u32, (offered - ideal) as u32) - } else { - Perbill::zero() - }; - old + extra * old - } else { - let extra = if ideal > 0 { - Perbill::from_rational(sold as u32, ideal as u32).left_from_one() - } else { - Perbill::zero() - }; - old - extra * old - } - } - - /// Begin selling for the next sale period. - /// - /// Triggered by Relay-chain block number/timeslice. - pub(crate) fn rotate_sale( - commit_timeslice: Timeslice, - old_sale: SaleInfoRecordOf, - status: &StatusRecord, - config: &ConfigRecordOf, - ) -> Option<()> { - let now = frame_system::Pallet::::block_number(); - - // Calculate the start price for the sale after. - let reserve_price = { - let core_count = config.core_count; - let max_retail = core_count.saturating_sub(old_sale.first_core); - let offered = old_sale.cores_offered.min(max_retail); - let ideal = old_sale.ideal_cores_sold.min(max_retail); - let sold = old_sale.cores_sold; - let old_price = old_sale.reserve_price; - if offered > 0 { - Self::bump_price(offered, ideal, sold, old_price) - } else { - old_price - } - }; - let start_price = reserve_price * 2u32.into(); - - // TODO: commission system InstaPool cores. - - // Set workload for the reserved (system, probably) workloads. - let region_begin = old_sale.region_end; - let region_end = region_begin + config.region_length; - - let mut first_core = 0; - for schedule in Reservations::::get().into_iter() { - Workplan::::insert((region_begin, first_core), schedule); - first_core.saturating_inc(); - } - - let mut leases = Leases::::get(); - // can morph to a renewable as long as it's > begin and < end. - leases.retain(|&(until, para)| { - let part = CorePart::complete(); - let assignment = CoreAssignment::Task(para); - let schedule = BoundedVec::truncate_from(vec![ScheduleItem { part, assignment }]); - Workplan::::insert((region_begin, first_core), &schedule); - let expiring = until >= region_begin; - if expiring { - // last time for this one - make it renewable. - let record = AllowedRenewalRecord { - begin: region_end, - price: reserve_price, - workload: schedule, - }; - AllowedRenewals::::insert(first_core, record); - } - first_core.saturating_inc(); - !expiring - }); - Leases::::put(&leases); - - let max_possible_sales = config.core_count.saturating_sub(first_core); - let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); - let cores_offered = limit_cores_offered.min(max_possible_sales); - // Update SaleInfo - let new_sale = SaleInfoRecord { - sale_start: now.saturating_add(config.interlude_length), - leadin_length: config.leadin_length, - start_price, - reserve_price, - region_begin, - region_end, - first_core, - ideal_cores_sold: (config.ideal_bulk_proportion * cores_offered as u32) as u16, - cores_offered, - cores_sold: 0, - }; - SaleInfo::::put(&new_sale); - - Some(()) - } - - pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { - let mut r = Reservations::::get(); - r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; - Reservations::::put(r); - Ok(()) - } - - pub(crate) fn current_timeslice() -> Timeslice { - let latest = T::Coretime::latest(); - let timeslice_period = T::TimeslicePeriod::get(); - (latest / timeslice_period).saturated_into() - } - - pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, config: &ConfigRecordOf) { - Self::process_pool(timeslice, status); - let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); - for core in 0..config.core_count { - Self::process_core_schedule(timeslice, rc_begin, core, status); - } - } - - fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { - let pool_io = InstaPoolIo::::take(timeslice); - status.pool_size = (status.pool_size as i32).saturating_add(pool_io) as u32; - let record = InstaPoolHistoryRecord { - total_contributions: status.pool_size, - maybe_payout: None, - }; - InstaPoolHistory::::insert(timeslice, record); - } - - /// Schedule cores for the given `timeslice`. - fn process_core_schedule( - timeslice: Timeslice, - rc_begin: RelayBlockNumberOf, - core: CoreIndex, - status: &mut StatusRecord, - ) { - let mut workplan = match Workplan::::take((timeslice, core)) { - Some(w) => w, - None => return, - }; - let workload = Workload::::get(core); - let parts_used = workplan.iter().map(|i| i.part).fold(CorePart::void(), |a, i| a | i); - let mut workplan = workplan.into_inner(); - workplan.extend(workload.into_iter().filter(|i| (i.part & parts_used).is_void())); - let workplan = Schedule::truncate_from(workplan); - Workload::::insert(core, &workplan); - - let mut total_used = 0; - let mut intermediate = workplan - .into_iter() - .map(|i| (i.assignment, i.part.count_ones() as u16 * (57_600 / 80))) - .inspect(|i| total_used += i.1) - .collect::>(); - if total_used < 80 { - intermediate.push((CoreAssignment::Idle, 80 - total_used)); - } - intermediate.sort(); - let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = Vec::with_capacity(intermediate.len()); - for i in intermediate.into_iter() { - if let Some(ref mut last) = assignment.last_mut() { - if last.0 == i.0 { - last.1 += i.1; - continue; - } - } - assignment.push(i); - } - T::Coretime::assign_core(core, rc_begin, assignment, None); - } - - fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { - T::OnRevenue::on_unbalanced(T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?); - Ok(()) - } - - /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the - /// current sale status's `region_end`. - pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let status = Status::::get().ok_or(Error::::Uninitialized)?; - let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; - let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - - ensure!(record.begin == sale.region_begin, Error::::WrongTime); - ensure!(sale.first_core < config.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); - - Self::charge(who, record.price)?; - - let core = sale.first_core + sale.cores_sold; - sale.cores_sold.saturating_inc(); - - Workplan::::insert((record.begin, core), &record.workload); - - let begin = sale.region_end; - let price = record.price + record.price / 100u32.into() * 2u32.into(); - let new_record = AllowedRenewalRecord { begin, price, .. record }; - AllowedRenewals::::insert(core, new_record); - SaleInfo::::put(&sale); - Ok(()) - } - - pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let status = Status::::get().ok_or(Error::::Uninitialized)?; - let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < config.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); - let now = frame_system::Pallet::::block_number(); - ensure!(now > sale.sale_start, Error::::TooEarly); - let current_price = lerp( - now, - sale.sale_start, - sale.leadin_length, - sale.start_price, - sale.reserve_price, - ).ok_or(Error::::IndeterminablePrice)?; - ensure!(price_limit >= current_price, Error::::Overpriced); - - Self::charge(&who, current_price)?; - let core = sale.first_core + sale.cores_sold; - sale.cores_sold.saturating_inc(); - SaleInfo::::put(&sale); - Self::issue(core, sale.region_begin, sale.region_end, who, Some(current_price)); - Ok(()) - } - - pub(crate) fn issue( - core: CoreIndex, - begin: Timeslice, - end: Timeslice, - owner: T::AccountId, - paid: Option>, - ) { - let id = RegionId { begin, core, part: CorePart::complete() }; - let record = RegionRecord { end, owner, paid }; - Regions::::insert(id, record); - } - - pub(crate) fn do_transfer( - region_id: RegionId, - maybe_check_owner: Option, - new_owner: T::AccountId, - ) -> Result<(), Error> { - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - let old_owner = region.owner; - region.owner = new_owner; - Regions::::insert(®ion_id, ®ion); - Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); - - Ok(()) - } - - pub(crate) fn do_partition( - region_id: RegionId, - maybe_check_owner: Option, - pivot: Timeslice, - ) -> Result<(), Error> { - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - ensure!(pivot > region_id.begin, Error::::PivotTooEarly); - ensure!(pivot < region.end, Error::::PivotTooLate); - - region.paid = None; - let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; - let new_region = RegionRecord { end: pivot, ..region.clone() }; - - Regions::::insert(®ion_id, &new_region); - Regions::::insert(&new_region_id, ®ion); - Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); - - Ok(()) - } - - pub(crate) fn do_interlace( - mut region_id: RegionId, - maybe_check_owner: Option, - pivot: CorePart, - ) -> Result<(), Error> { - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); - ensure!(!pivot.is_void(), Error::::NullPivot); - ensure!(pivot != region_id.part, Error::::CompletePivot); - - let antipivot = region_id.part ^ pivot; - region_id.part = pivot; - Regions::::insert(®ion_id, ®ion); - region_id.part = antipivot; - Regions::::insert(®ion_id, ®ion); - - Self::deposit_event(Event::Interlaced { region_id, pivot }); - - Ok(()) - } - - pub(crate) fn utilize( - mut region_id: RegionId, - maybe_check_owner: Option, - ) -> Result)>, Error> { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let status = Status::::get().ok_or(Error::::Uninitialized)?; - - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - let last_commit_timeslice = status.last_timeslice + config.advance_notice; - if region_id.begin <= last_commit_timeslice { - region_id.begin = last_commit_timeslice + 1; - } - Regions::::remove(®ion_id); - - if region_id.begin < region.end { - Ok(Some((region_id, region))) - } else { - Self::deposit_event(Event::Dropped { region_id }); - Ok(None) - } - } - - pub(crate) fn do_assign( - region_id: RegionId, - maybe_check_owner: Option, - target: TaskId, - ) -> Result<(), Error> { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { - let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Task(target), - }).is_ok() { - Workplan::::insert(&workplan_key, &workplan); - } - if region.end.saturating_sub(region_id.begin) == config.region_length { - if workplan.iter() - .filter(|i| matches!(i.assignment, CoreAssignment::Task(..))) - .fold(CorePart::void(), |a, i| a | i.part) - .is_complete() - { - if let Some(price) = region.paid { - let record = AllowedRenewalRecord { - begin: region.end, - price, - workload: workplan, - }; - AllowedRenewals::::insert(region_id.core, &record); - } - } - } - Self::deposit_event(Event::Assigned { region_id, task: target }); - } - Ok(()) - } - - pub(crate) fn do_pool( - region_id: RegionId, - maybe_check_owner: Option, - payee: T::AccountId, - ) -> Result<(), Error> { - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { - let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Pool, - }).is_ok() { - Workplan::::insert(&workplan_key, &workplan); - InstaPoolIo::::mutate(region_id.begin, |a| *a += region_id.part.count_ones() as i32); - InstaPoolIo::::mutate(region.end, |a| *a -= region_id.part.count_ones() as i32); - let contrib = ContributionRecord { - begin: region_id.begin, - end: region.end, - core: region_id.core, - part: region_id.part, - payee: Contributor::Private(payee), - }; - InstaPoolContribution::::insert(&contrib, ()); - } - Self::deposit_event(Event::Pooled { region_id }); - } - Ok(()) - } - } } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 9340951950967..5bdc12994f3e1 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -18,8 +18,8 @@ #![cfg(test)] use crate::*; -use frame_support::{parameter_types, traits::fungible::{ItemOf, DecreaseIssuance}}; -use sp_core::{H256, Get, ConstU64, ConstU16, ConstU32}; +use frame_support::{parameter_types, traits::fungible::ItemOf}; +use sp_core::{H256, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup, Identity}, diff --git a/frame/broker/src/test_fungibles.rs b/frame/broker/src/test_fungibles.rs index 2c65d82566446..84c149b99d971 100644 --- a/frame/broker/src/test_fungibles.rs +++ b/frame/broker/src/test_fungibles.rs @@ -17,14 +17,14 @@ use frame_support::{ parameter_types, - traits::{ConstU16, ConstU64, fungibles::{self, Dust}, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} + traits::{fungibles::{self, Dust}, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} }; use scale_info::TypeInfo; use sp_arithmetic::traits::Zero; use sp_runtime::{DispatchError, DispatchResult}; use sp_std::collections::btree_map::BTreeMap; use codec::{Encode, Decode}; -use sp_core::{ConstU32, TypedGet, Get}; +use sp_core::{TypedGet, Get}; parameter_types! { static TestAssetOf: BTreeMap<(u32, Vec), Vec> = Default::default(); @@ -59,7 +59,7 @@ where } /// The minimum balance any single account may have. - fn minimum_balance(asset: Self::AssetId) -> Self::Balance { + fn minimum_balance(_asset: Self::AssetId) -> Self::Balance { MinimumBalance::get() } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index e27343e3f1f83..089e1a684b9ba 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,7 +17,7 @@ #![cfg(test)] -use crate::{*, mock::*, types::*, Error, ConfigRecord}; +use crate::{*, mock::*, core_part::*, ConfigRecord}; use frame_support::{assert_noop, assert_ok, traits::Hooks}; use CoreAssignment::*; use CoretimeTraceItem::*; diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 9c75d40229af4..a1b0902a271db 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,157 +1,185 @@ +use crate::{Config, CoretimeInterface, CoreIndex, CorePart, CoreAssignment, TaskId}; use codec::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_core::RuntimeDebug; -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; +use frame_support::traits::fungible::Inspect; +use frame_system::Config as SConfig; +use sp_arithmetic::Perbill; +use sp_core::{ConstU32, RuntimeDebug}; +use sp_runtime::BoundedVec; -// TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct CorePart([u8; 10]); -impl CorePart { - pub fn void() -> Self { - Self([0u8; 10]) - } - pub fn complete() -> Self { - Self([255u8; 10]) - } - pub fn is_void(&self) -> bool { - &self.0 == &[0u8; 10] - } - pub fn is_complete(&self) -> bool { - &self.0 == &[255u8; 10] - } - pub fn set(&mut self, i: u32) -> Self { - if i < 80 { - self.0[(i / 8) as usize] |= (128 >> (i % 8)); - } - *self - } - pub fn clear(&mut self, i: u32) -> Self { - if i < 80 { - self.0[(i / 8) as usize] &= !(128 >> (i % 8)); - } - *self - } - pub fn count_zeros(&self) -> u32 { - self.0.iter().map(|i| i.count_zeros()).sum() - } - pub fn count_ones(&self) -> u32 { - self.0.iter().map(|i| i.count_ones()).sum() - } - pub fn from_chunk(from: u32, to: u32) -> Self { - let mut v = [0u8; 10]; - for i in (from.min(80) as usize)..(to.min(80) as usize) { - v[i / 8] |= (128 >> (i % 8)); - } - Self(v) - } -} -impl From for CorePart { - fn from(x: u128) -> Self { - let mut v = [0u8; 10]; - for i in 0..10 { - v[i] = (x >> (72 - 8 * i)) as u8; - } - Self(v) - } -} -impl BitAnd for CorePart { - type Output = Self; - fn bitand(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitand(rhs.0[i]); - } - Self(result) - } -} -impl BitAndAssign for CorePart { - fn bitand_assign(&mut self, rhs: Self) { - for i in 0..10 { - self.0[i].bitand_assign(rhs.0[i]); - } - } +pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; +pub type RelayBalanceOf = <::Coretime as CoretimeInterface>::Balance; +pub type RelayBlockNumberOf = <::Coretime as CoretimeInterface>::BlockNumber; + +/// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. +pub type Timeslice = u32; +/// Counter for the total number of set bits over every core's `CorePart`. `u32` so we don't +/// ever get an overflow. +pub type PartCount = u32; +/// The same as `PartCount` but signed. +pub type SignedPartCount = i32; + +/// Self-describing identity for a Region of Bulk Coretime. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct RegionId { + /// The timeslice at which this Region begins. + pub begin: Timeslice, + /// The index of the Polakdot Core on which this Region will be scheduled. + pub core: CoreIndex, + /// The regularity parts in which this Region will be scheduled. + pub part: CorePart, } -impl BitOr for CorePart { - type Output = Self; - fn bitor(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitor(rhs.0[i]); - } - Self(result) - } + +/// The rest of the information describing a Region. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct RegionRecord { + /// The end of the Region. + pub end: Timeslice, + /// The owner of the Region. + pub owner: AccountId, + /// The amount paid to Polkadot for this Region. + pub paid: Option, } -impl BitOrAssign for CorePart { - fn bitor_assign(&mut self, rhs: Self) { - for i in 0..10 { - self.0[i].bitor_assign(rhs.0[i]); - } - } +pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf>; + +/// An distinct item which can be scheduled on a Polkadot Core. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct ScheduleItem { + /// The regularity parts in which this Item will be scheduled on the Core. + pub part: CorePart, + /// The job that the Core should be doing. + pub assignment: CoreAssignment, } -impl BitXor for CorePart { - type Output = Self; - fn bitxor(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitxor(rhs.0[i]); - } - Self(result) - } +pub type Schedule = BoundedVec>; + +/// Identity of a contributor to the Instantaneous Coretime Pool. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum Contributor { + /// The Polkadot system; revenue collected on its behalf goes to the `Config::OnRevenue` + /// handler. + System, + /// A private Bulk Coretime holder; revenue collected may be paid out to them. + Private(AccountId), } -impl BitXorAssign for CorePart { - fn bitxor_assign(&mut self, rhs: Self) { - for i in 0..10 { - self.0[i].bitxor_assign(rhs.0[i]); - } - } +pub type ContributorOf = Contributor<::AccountId>; + +/// The record of a Region which was contributed to the Instantaneous Coretime Pool. This helps +/// with making pro rata payments to contributors. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct ContributionRecord { + /// The beginning of the Region contributed. + pub begin: Timeslice, + /// The end of the Region contributed. + pub end: Timeslice, + /// The index of the Polkadot Core contributed. + pub core: CoreIndex, + /// The regularity parts of the Polkadot Core contributed. + pub part: CorePart, + /// The identity of the contributor. + pub payee: Contributor, } -impl Not for CorePart { - type Output = Self; - fn not(self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].not(); - } - Self(result) - } +pub type ContributionRecordOf = ContributionRecord<::AccountId>; + +/// A per-timeslice bookkeeping record for tracking Instantaneous Coretime Pool activity and +/// making proper payments to contributors. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct InstaPoolHistoryRecord { + /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block + /// of a Polkadot Core) contributed over a timeslice minus any contributions which have + /// already been paid out. + pub total_contributions: PartCount, + /// The payout remaining for the `total_contributions`, or `None` if the revenue is not yet + /// known. + pub maybe_payout: Option, } +pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; -#[cfg(test)] -mod tests { - use super::*; +/// A record of an allowed renewal. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct AllowedRenewalRecord { + /// The timeslice denoting the beginning of the Region for which a renewal can secure. + pub begin: Timeslice, + /// The price for which the next renewal can be made. + pub price: Balance, + /// The workload which will be scheduled on the Core in the case a renewal is made. + pub workload: Schedule, +} +pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; - #[test] - fn complete_works() { - assert_eq!(CorePart::complete(), CorePart([0xff; 10])); - assert!(CorePart([0xff; 10]).is_complete()); - for i in 0..80 { - assert!(!CorePart([0xff; 10]).clear(i).is_complete()); - } - } +/// General status of the system. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct StatusRecord { + /// The current size of the Instantaneous Coretime Pool, measured in (measured in + /// Regularity Parts or 1/80th of a single block of a Polkadot Core). + pub pool_size: PartCount, + /// The last (Relay-chain) timeslice which we processed for (this processing is generally + /// done some number of timeslices in advance of actual Relay-chain execution to make up + /// for latencies and any needed Relay-side preparations). + pub last_timeslice: Timeslice, +} - #[test] - fn void_works() { - assert_eq!(CorePart::void(), CorePart([0; 10])); - assert!(CorePart([0; 10]).is_void()); - for i in 0..80 { - assert!(!(CorePart([0; 10]).set(i).is_void())); - } - } +/// The status of a Bulk Coretime Sale. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct SaleInfoRecord { + /// The local block number at which the sale will/did start. + pub sale_start: BlockNumber, + /// The length in blocks of the Leadin Period (where the price is decreasing). + pub leadin_length: BlockNumber, + /// The price of Bulk Coretime at the beginning of the Leadin Period. + pub start_price: Balance, + /// The price of Bulk Coretime by the end of the Leadin Period. + pub reserve_price: Balance, + /// The first timeslice of the Regions which are being sold in this sale. + pub region_begin: Timeslice, + /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One + /// after the last timeslice which the Regions control.) + pub region_end: Timeslice, + /// The index of the first core which is for sale. Core of Regions which are sold have + /// incrementing indices from this. + pub first_core: CoreIndex, + /// The number of cores we want to sell, ideally. Selling this amount would result in no + /// change to the reserve_price for the next sale. + pub ideal_cores_sold: CoreIndex, + /// Number of cores which are/have been offered for sale. + pub cores_offered: CoreIndex, + /// Number of cores which have been sold; never more than cores_offered. + pub cores_sold: CoreIndex, +} +pub type SaleInfoRecordOf = SaleInfoRecord< + BalanceOf, + ::BlockNumber, +>; - #[test] - fn from_works() { - assert!(CorePart::from(0xfffff_fffff_fffff_fffff).is_complete()); - assert_eq!( - CorePart::from(0x12345_67890_abcde_f0123), - CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]), - ); - } +/// Record for Polkadot Core reservations (generally tasked with the maintenance of System +/// Chains). +pub type ReservationsRecord = BoundedVec; +pub type ReservationsRecordOf = ReservationsRecord<::MaxReservedCores>; +/// Record for Polkadot Core legacy leases. +pub type LeasesRecord = BoundedVec<(Timeslice, TaskId), Max>; +pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; - #[test] - fn chunk_works() { - assert_eq!( - CorePart::from_chunk(40, 60), - CorePart::from(0x00000_00000_fffff_00000), - ); - } -} \ No newline at end of file +/// Configuration of this pallet. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct ConfigRecord { + /// The total number of cores which can be assigned (one plus the maximum index which can + /// be used in `Coretime::assign`). + pub core_count: CoreIndex, + /// The number of timeslices in advance which scheduling should be fixed and the + /// `Coretime::assign` API used to inform the Relay-chain. + pub advance_notice: Timeslice, + /// The length in blocks of the Interlude Period for forthcoming sales. + pub interlude_length: BlockNumber, + /// The length in blocks of the Leadin Period for forthcoming sales. + pub leadin_length: BlockNumber, + /// The length in timeslices of Regions which are up for sale in forthcoming sales. + pub region_length: Timeslice, + /// The proportion of cores available for sale which should be sold in order for the price + /// to remain the same in the next sale. + pub ideal_bulk_proportion: Perbill, + /// An artificial limit to the number of cores which are allowed to be sold. If `Some` then + /// no more cores will be sold than this. + pub limit_cores_offered: Option, +} +pub type ConfigRecordOf = ConfigRecord< + ::BlockNumber, +>; diff --git a/frame/broker/src/utils.rs b/frame/broker/src/utils.rs new file mode 100644 index 0000000000000..3a473f196300e --- /dev/null +++ b/frame/broker/src/utils.rs @@ -0,0 +1,14 @@ +use sp_arithmetic::traits::Bounded; + +pub fn lerp, S: TryInto + TryFrom + Bounded>(v: T, a: T, d: T, x: S, y: S) -> Option { + use sp_arithmetic::{Rounding::NearestPrefUp, helpers_128bit::multiply_by_rational_with_rounding}; + let v: u128 = v.try_into().ok()?; + let a: u128 = a.try_into().ok()?; + let d: u128 = d.try_into().ok()?; + let r: u128 = x.try_into().ok()?; + let s: u128 = y.try_into().ok()?; + let rsd = r.max(s) - r.min(s); + let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; + if r < s { r + td } else { r - td }.try_into().ok() +} + From 08e9eb11b3926cdd61a38a0fe1edb3a3f79c5257 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 17:12:38 +0200 Subject: [PATCH 016/131] Tests --- frame/broker/src/mock.rs | 74 +++++++++++++++++++++++++++++-- frame/broker/src/tests.rs | 92 +++++++++++++++++++++++---------------- frame/broker/src/types.rs | 2 +- 3 files changed, 126 insertions(+), 42 deletions(-) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 5bdc12994f3e1..88e480590a363 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -18,7 +18,8 @@ #![cfg(test)] use crate::*; -use frame_support::{parameter_types, traits::fungible::ItemOf}; +use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate}}, assert_ok}; +use sp_arithmetic::Perbill; use sp_core::{H256, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ testing::Header, @@ -117,7 +118,72 @@ impl crate::Config for Test { type WeightInfo = (); } -// Build genesis storage according to the mock runtime. -pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default().build_storage::().unwrap().into() +pub fn advance_to(b: u64) { + while System::block_number() < b { + System::set_block_number(System::block_number() + 1); + Broker::on_initialize(System::block_number()); + } +} + +pub struct TestExt(ConfigRecordOf); +impl TestExt { + pub fn new() -> Self { + Self(ConfigRecord { + core_count: 1, + advance_notice: 1, + interlude_length: 1, + leadin_length: 1, + ideal_bulk_proportion: Default::default(), + limit_cores_offered: None, + region_length: 3, + }) + } + + pub fn core_count(mut self, core_count: CoreIndex) -> Self { + self.0.core_count = core_count; + self + } + + pub fn advance_notice(mut self, advance_notice: Timeslice) -> Self { + self.0.advance_notice = advance_notice; + self + } + + pub fn interlude_length(mut self, interlude_length: u64) -> Self { + self.0.interlude_length = interlude_length; + self + } + + pub fn leadin_length(mut self, leadin_length: u64) -> Self { + self.0.leadin_length = leadin_length; + self + } + + pub fn region_length(mut self, region_length: Timeslice) -> Self { + self.0.region_length = region_length; + self + } + + pub fn ideal_bulk_proportion(mut self, ideal_bulk_proportion: Perbill) -> Self { + self.0.ideal_bulk_proportion = ideal_bulk_proportion; + self + } + + pub fn limit_cores_offered(mut self, limit_cores_offered: Option) -> Self { + self.0.limit_cores_offered = limit_cores_offered; + self + } + + pub fn endow(self, who: u64, amount: u64) -> Self { + assert_ok!(<::Currency as Mutate<_>>::mint_into(&who, amount)); + self + } + + pub fn execute_with(self, f: impl Fn() -> R) -> R { + let c = frame_system::GenesisConfig::default().build_storage::().unwrap(); + sp_io::TestExternalities::from(c).execute_with(|| { + assert_ok!(Broker::do_configure(self.0)); + f() + }) + } } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 089e1a684b9ba..6863959555832 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,49 +17,24 @@ #![cfg(test)] -use crate::{*, mock::*, core_part::*, ConfigRecord}; -use frame_support::{assert_noop, assert_ok, traits::Hooks}; +use crate::{*, mock::*, core_part::*, test_fungibles::*}; +use frame_support::{assert_noop, assert_ok}; use CoreAssignment::*; use CoretimeTraceItem::*; use sp_arithmetic::Perbill; -fn advance_to(b: u64) { - while System::block_number() < b { - System::set_block_number(System::block_number() + 1); - Broker::on_initialize(System::block_number()); - } -} - #[test] fn basic_initialize_works() { - new_test_ext().execute_with(|| { - assert_ok!(Broker::do_configure(ConfigRecord { - core_count: 10, - advance_notice: 1, - interlude_length: 1, - leadin_length: 3, - ideal_bulk_proportion: Perbill::zero(), - limit_cores_offered: None, - region_length: 10, - })); + TestExt::new().execute_with(|| { assert_ok!(Broker::do_start_sales(100)); assert_eq!(CoretimeTrace::get(), vec![]); + assert_eq!(Broker::current_timeslice(), 0); }); } #[test] fn initialize_with_system_paras_works() { - new_test_ext().execute_with(|| { - assert_ok!(Broker::do_configure(ConfigRecord { - core_count: 3, - advance_notice: 1, - interlude_length: 1, - leadin_length: 3, - ideal_bulk_proportion: Perbill::zero(), - limit_cores_offered: None, - region_length: 5, - })); - + TestExt::new().core_count(2).execute_with(|| { let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); let items = vec![ @@ -68,18 +43,13 @@ fn initialize_with_system_paras_works() { ScheduleItem { assignment: Task(4u32), part: 0x00000_00000_00000_fffff.into() }, ]; assert_ok!(Broker::do_reserve(Schedule::truncate_from(items))); - - assert_eq!(Broker::current_timeslice(), 0); - assert_ok!(Broker::do_start_sales(100)); - assert_eq!(CoretimeTrace::get(), vec![]); - advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ - (10, AssignCore { core: 0, begin: 12, assignment: vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ (Task(1), 57600), ], end_hint: None }), - (10, AssignCore { core: 1, begin: 12, assignment: vec![ + (6, AssignCore { core: 1, begin: 8, assignment: vec![ (Task(2), 28800), (Task(3), 14400), (Task(4), 14400), @@ -87,3 +57,51 @@ fn initialize_with_system_paras_works() { ]); }); } + +#[test] +fn purchase_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region = RegionId { begin, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_assign(region, None, 1000)); + advance_to(6); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1000), 57600), + ], end_hint: None }), + ]); + }); +} + +#[test] +fn partition_purchase_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region1 = RegionId { begin, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_partition(region1, None, begin + 1)); + let region2 = RegionId { begin: begin + 1, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_partition(region2, None, begin + 2)); + let region3 = RegionId { begin: begin + 2, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_assign(region1, None, 1001)); + assert_ok!(Broker::do_assign(region2, None, 1002)); + assert_ok!(Broker::do_assign(region3, None, 1003)); + advance_to(10); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1001), 57600), + ], end_hint: None }), + (8, AssignCore { core: 0, begin: 10, assignment: vec![ + (Task(1002), 57600), + ], end_hint: None }), + (10, AssignCore { core: 0, begin: 12, assignment: vec![ + (Task(1003), 57600), + ], end_hint: None }), + ]); + }); +} diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index a1b0902a271db..dc56972df8827 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -20,7 +20,7 @@ pub type PartCount = u32; pub type SignedPartCount = i32; /// Self-describing identity for a Region of Bulk Coretime. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct RegionId { /// The timeslice at which this Region begins. pub begin: Timeslice, From 6f13d320bef743ca0bc9c913974cb0df6c63e2a3 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 17:37:42 +0200 Subject: [PATCH 017/131] Tests --- frame/broker/src/tests.rs | 102 +++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 6863959555832..2ca6ec996f65b 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -77,7 +77,7 @@ fn purchase_works() { } #[test] -fn partition_purchase_works() { +fn partition_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); @@ -105,3 +105,103 @@ fn partition_purchase_works() { ]); }); } + +#[test] +fn interlace_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region1 = RegionId { begin, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_interlace(region1, None, CorePart::from_chunk(0, 30))); + let region1 = RegionId { begin, core: 0, part: CorePart::from_chunk(0, 30) }; + let region2 = RegionId { begin, core: 0, part: CorePart::from_chunk(30, 80) }; + assert_ok!(Broker::do_interlace(region2, None, CorePart::from_chunk(30, 60))); + let region2 = RegionId { begin, core: 0, part: CorePart::from_chunk(30, 60) }; + let region3 = RegionId { begin, core: 0, part: CorePart::from_chunk(60, 80) }; + assert_ok!(Broker::do_assign(region1, None, 1001)); + assert_ok!(Broker::do_assign(region2, None, 1002)); + assert_ok!(Broker::do_assign(region3, None, 1003)); + advance_to(10); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1001), 21600), + (Task(1002), 21600), + (Task(1003), 14400), + ], end_hint: None }), + ]); + }); +} + +#[test] +fn interlace_then_partition_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region = RegionId { begin, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_interlace(region, None, CorePart::from_chunk(0, 20))); + let region1 = RegionId { part: CorePart::from_chunk(0, 20), ..region }; + let region2 = RegionId { part: CorePart::from_chunk(20, 80), ..region }; + assert_ok!(Broker::do_partition(region1, None, begin + 1)); + assert_ok!(Broker::do_partition(region2, None, begin + 2)); + let region3 = RegionId { begin: begin + 1, ..region1 }; + let region4 = RegionId { begin: begin + 2, ..region2 }; + assert_ok!(Broker::do_assign(region1, None, 1001)); + assert_ok!(Broker::do_assign(region2, None, 1002)); + assert_ok!(Broker::do_assign(region3, None, 1003)); + assert_ok!(Broker::do_assign(region4, None, 1004)); + advance_to(10); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1001), 14400), + (Task(1002), 43200), + ], end_hint: None }), + (8, AssignCore { core: 0, begin: 10, assignment: vec![ + (Task(1002), 43200), + (Task(1003), 14400), + ], end_hint: None }), + (10, AssignCore { core: 0, begin: 12, assignment: vec![ + (Task(1003), 14400), + (Task(1004), 43200), + ], end_hint: None }), + ]); + }); +} + +#[test] +fn partition_then_interlace_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region = RegionId { begin, core: 0, part: CorePart::complete() }; + assert_ok!(Broker::do_partition(region, None, begin + 1)); + let region1 = RegionId { begin, ..region }; + let region2 = RegionId { begin: begin + 1, ..region }; + assert_ok!(Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20))); + assert_ok!(Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30))); + let region3 = RegionId { part: CorePart::from_chunk(20, 80), ..region1 }; + let region4 = RegionId { part: CorePart::from_chunk(30, 80), ..region2 }; + let region1 = RegionId { part: CorePart::from_chunk(0, 20), ..region1 }; + let region2 = RegionId { part: CorePart::from_chunk(0, 30), ..region2 }; + assert_ok!(Broker::do_assign(region1, None, 1001)); + assert_ok!(Broker::do_assign(region2, None, 1002)); + assert_ok!(Broker::do_assign(region3, None, 1003)); + assert_ok!(Broker::do_assign(region4, None, 1004)); + advance_to(10); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1001), 14400), + (Task(1003), 43200), + ], end_hint: None }), + (8, AssignCore { core: 0, begin: 10, assignment: vec![ + (Task(1002), 21600), + (Task(1004), 36000), + ], end_hint: None }), + ]); + }); +} From 68df2d13c4ff6f07b1abaef0290da7c59931b00c Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 20:27:44 +0200 Subject: [PATCH 018/131] System InstaPool cores and payout --- frame/broker/src/implementation.rs | 136 +++++++++++++++++++++++++---- frame/broker/src/lib.rs | 16 +++- frame/broker/src/mock.rs | 7 +- frame/broker/src/tests.rs | 3 +- frame/broker/src/types.rs | 46 +++++----- 5 files changed, 159 insertions(+), 49 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index e8a4b189fd107..c801ed66a7e7e 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -1,9 +1,10 @@ use super::*; +use sp_runtime::traits::{Convert, ConvertBack, AccountIdConversion}; use frame_support::{ pallet_prelude::{*, DispatchResult}, traits::{ tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, - fungible::Balanced, OnUnbalanced + fungible::{Mutate, Balanced}, OnUnbalanced, DefensiveResult, } }; use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; @@ -15,13 +16,15 @@ impl Pallet { } /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is - /// less than `Self::last_timeslice`. + /// less than `Self::current_timeslice`. pub(crate) fn do_tick() -> DispatchResult { let mut status = Status::::get().ok_or(Error::::Uninitialized)?; let current_timeslice = Self::current_timeslice(); ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); status.last_timeslice.saturating_inc(); + T::Coretime::request_revenue_info_at(T::TimeslicePeriod::get() * status.last_timeslice.into()); + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let commit_timeslice = status.last_timeslice + config.advance_notice; Self::process_timeslice(commit_timeslice, &mut status, &config); @@ -44,8 +47,8 @@ impl Pallet { let status = StatusRecord { pool_size: 0, last_timeslice: Self::current_timeslice(), + system_pool_size: 0, }; - Status::::put(&status); let commit_timeslice = status.last_timeslice + config.advance_notice; let now = frame_system::Pallet::::block_number(); let dummy_sale = SaleInfoRecord { @@ -61,6 +64,7 @@ impl Pallet { cores_sold: 0, }; Self::rotate_sale(dummy_sale, &config); + Status::::put(&status); Ok(()) } @@ -97,33 +101,54 @@ impl Pallet { let now = frame_system::Pallet::::block_number(); // Calculate the start price for the sale after. - let reserve_price = { + let (reserve_price, unused) = { let core_count = config.core_count; let max_retail = core_count.saturating_sub(old_sale.first_core); let offered = old_sale.cores_offered.min(max_retail); let ideal = old_sale.ideal_cores_sold.min(max_retail); let sold = old_sale.cores_sold; let old_price = old_sale.reserve_price; - if offered > 0 { + (if offered > 0 { Self::bump_price(offered, ideal, sold, old_price) } else { old_price - } + }, offered.saturating_sub(ideal)) }; let start_price = reserve_price * 2u32.into(); - // TODO: commission system InstaPool cores. - // Set workload for the reserved (system, probably) workloads. let region_begin = old_sale.region_end; let region_end = region_begin + config.region_length; let mut first_core = 0; + let mut total_pooled: SignedPartCount = 0; for schedule in Reservations::::get().into_iter() { - Workplan::::insert((region_begin, first_core), schedule); + let parts: u32 = schedule.iter() + .filter(|i| matches!(i.assignment, CoreAssignment::Pool)) + .map(|i| i.part.count_ones()) + .sum(); + total_pooled.saturating_accrue(parts as i32); + + Workplan::::insert((region_begin, first_core), &schedule); + first_core.saturating_inc(); + } + let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CorePart::complete() }; + let just_pool = Schedule::truncate_from(vec![pool_item]); + for _ in 0..unused { + total_pooled.saturating_accrue(80); + Workplan::::insert((region_begin, first_core), &just_pool); first_core.saturating_inc(); } + InstaPoolIo::::mutate(region_begin, |r| { + r.total.saturating_accrue(total_pooled); + r.system.saturating_accrue(total_pooled); + }); + InstaPoolIo::::mutate(region_end, |r| { + r.total.saturating_reduce(total_pooled); + r.system.saturating_reduce(total_pooled); + }); + let mut leases = Leases::::get(); // can morph to a renewable as long as it's > begin and < end. leases.retain(|&(until, para)| { @@ -167,6 +192,79 @@ impl Pallet { Some(()) } + pub fn account_id() -> T::AccountId { + T::PalletId::get().into_account_truncating() + } + + pub(crate) fn do_check_revenue() -> DispatchResult { + if let Some((until, amount)) = T::Coretime::check_notify_revenue_info() { + let timeslice: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); + let mut amount = T::ConvertBalance::convert_back(amount); + if amount.is_zero() { + InstaPoolHistory::::remove(timeslice); + return Ok(()) + } + let mut pool_record = InstaPoolHistory::::get(timeslice).unwrap_or_default(); + ensure!(pool_record.maybe_payout.is_none(), Error::::RevenueAlreadyKnown); + + // Payout system InstaPool Cores. + let system_payout = amount.saturating_mul(pool_record.system_contributions.into()) + / pool_record.total_contributions.into(); + let _ = Self::charge(&Self::account_id(), system_payout); + pool_record.system_contributions = 0; + pool_record.total_contributions.saturating_reduce(pool_record.system_contributions); + amount.saturating_reduce(system_payout); + + if !amount.is_zero() && pool_record.total_contributions > 0 { + pool_record.maybe_payout = Some(amount); + InstaPoolHistory::::insert(timeslice, &pool_record); + } else { + InstaPoolHistory::::remove(timeslice); + } + } + Ok(()) + } + + pub(crate) fn do_purchase_credit( + who: T::AccountId, + amount: BalanceOf, + beneficiary: RelayAccountIdOf, + ) -> DispatchResult { + T::Currency::transfer(&who, &Self::account_id(), amount, Expendable)?; + let amount = T::ConvertBalance::convert(amount); + T::Coretime::credit_account(beneficiary, amount); + Ok(()) + } + + // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. + pub(crate) fn do_claim_revenue(region: RegionId) -> DispatchResult { + let mut pool_record = InstaPoolHistory::::get(region.begin).ok_or(Error::::NoRevenue)?; + let total_payout = pool_record.maybe_payout.ok_or(Error::::UnknownRevenue)?; + let mut contribution = InstaPoolContribution::::take(region).ok_or(Error::::UnknownContribution)?; + let contributed_parts = region.part.count_ones(); + + contribution.length.saturating_dec(); + if contribution.length > 0 { + let next_region = RegionId { begin: region.begin + 1, ..region }; + InstaPoolContribution::::insert(next_region, &contribution); + } + + let payout = total_payout.saturating_mul(contributed_parts.into()) + / pool_record.total_contributions.into(); + T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable).defensive_ok(); + + pool_record.total_contributions.saturating_reduce(contributed_parts); + + let remaining_payout = total_payout.saturating_sub(payout); + if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { + pool_record.maybe_payout = Some(remaining_payout); + InstaPoolHistory::::insert(region.begin, &pool_record); + } else { + InstaPoolHistory::::remove(region.begin); + } + Ok(()) + } + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { let mut r = Reservations::::get(); r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; @@ -190,9 +288,11 @@ impl Pallet { fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); - status.pool_size = (status.pool_size as i32).saturating_add(pool_io) as u32; + status.pool_size = (status.pool_size as i32).saturating_add(pool_io.total) as u32; + status.system_pool_size = (status.pool_size as i32).saturating_add(pool_io.system) as u32; let record = InstaPoolHistoryRecord { total_contributions: status.pool_size, + system_contributions: status.system_pool_size, maybe_payout: None, }; InstaPoolHistory::::insert(timeslice, record); @@ -452,16 +552,14 @@ impl Pallet { assignment: CoreAssignment::Pool, }).is_ok() { Workplan::::insert(&workplan_key, &workplan); - InstaPoolIo::::mutate(region_id.begin, |a| *a += region_id.part.count_ones() as i32); - InstaPoolIo::::mutate(region.end, |a| *a -= region_id.part.count_ones() as i32); - let contrib = ContributionRecord { - begin: region_id.begin, - end: region.end, - core: region_id.core, - part: region_id.part, - payee: Contributor::Private(payee), + let size = region_id.part.count_ones() as i32; + InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); + InstaPoolIo::::mutate(region.end, |a| a.total.saturating_reduce(size)); + let record = ContributionRecord { + length: region.end.saturating_sub(region_id.begin), + payee, }; - InstaPoolContribution::::insert(&contrib, ()); + InstaPoolContribution::::insert(®ion_id, record); } Self::deposit_event(Event::Pooled { region_id }); } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 0e4def2453c4a..42c509bc9b970 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -43,7 +43,8 @@ pub mod pallet { use super::*; use frame_support::{ pallet_prelude::{*, DispatchResult}, - traits::{fungible::{Credit, Balanced}, OnUnbalanced}, + traits::{fungible::{Credit, Mutate, Balanced}, OnUnbalanced}, + PalletId, }; use frame_system::pallet_prelude::*; use sp_runtime::traits::{ConvertBack, Convert}; @@ -59,7 +60,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// Currency used to pay for Coretime. - type Currency: Balanced; + type Currency: Mutate + Balanced; /// What to do with any revenues collected from the sale of Coretime. type OnRevenue: OnUnbalanced>; @@ -72,6 +73,9 @@ pub mod pallet { /// the `Identity`, but provided just in case the chains use different representations. type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; + /// Identifier from which the internal Pot is generated. + type PalletId: Get; + /// Number of Relay-chain blocks per timeslice. #[pallet::constant] type TimeslicePeriod: Get>; @@ -123,11 +127,11 @@ pub mod pallet { /// Record of a single contribution to the Instantaneous Coretime Pool. #[pallet::storage] - pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, ContributionRecordOf, (), OptionQuery>; + pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, RegionId, ContributionRecordOf, OptionQuery>; /// Record of Coretime entering or leaving the Instantaneous Coretime Pool. #[pallet::storage] - pub type InstaPoolIo = StorageMap<_, Blake2_128Concat, Timeslice, SignedPartCount, ValueQuery>; + pub type InstaPoolIo = StorageMap<_, Blake2_128Concat, Timeslice, PoolIoRecord, ValueQuery>; /// Total InstaPool rewards for each Timeslice and the number of core parts which contributed. #[pallet::storage] @@ -183,6 +187,10 @@ pub mod pallet { TooEarly, NothingToDo, TooManyReservations, + RevenueAlreadyKnown, + NoRevenue, + UnknownRevenue, + UnknownContribution, } #[pallet::hooks] diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 88e480590a363..d29a98d9bcb69 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] use crate::*; -use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate}}, assert_ok}; +use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate}}, assert_ok, PalletId}; use sp_arithmetic::Perbill; use sp_core::{H256, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ @@ -106,6 +106,10 @@ impl CoretimeInterface for CoretimeTrace { fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } } +parameter_types! { + pub const TestBrokerId: PalletId = PalletId(*b"TsBroker"); +} + impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; @@ -116,6 +120,7 @@ impl crate::Config for Test { type Coretime = CoretimeTrace; type ConvertBalance = Identity; type WeightInfo = (); + type PalletId = TestBrokerId; } pub fn advance_to(b: u64) { diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 2ca6ec996f65b..2ab2f18b4d3ef 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,11 +17,10 @@ #![cfg(test)] -use crate::{*, mock::*, core_part::*, test_fungibles::*}; +use crate::{*, mock::*, core_part::*}; use frame_support::{assert_noop, assert_ok}; use CoreAssignment::*; use CoretimeTraceItem::*; -use sp_arithmetic::Perbill; #[test] fn basic_initialize_works() { diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index dc56972df8827..a57d89d17a98f 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -10,6 +10,7 @@ use sp_runtime::BoundedVec; pub type BalanceOf = <::Currency as Inspect<::AccountId>>::Balance; pub type RelayBalanceOf = <::Coretime as CoretimeInterface>::Balance; pub type RelayBlockNumberOf = <::Coretime as CoretimeInterface>::BlockNumber; +pub type RelayAccountIdOf = <::Coretime as CoretimeInterface>::AccountId; /// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. pub type Timeslice = u32; @@ -52,42 +53,28 @@ pub struct ScheduleItem { } pub type Schedule = BoundedVec>; -/// Identity of a contributor to the Instantaneous Coretime Pool. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub enum Contributor { - /// The Polkadot system; revenue collected on its behalf goes to the `Config::OnRevenue` - /// handler. - System, - /// A private Bulk Coretime holder; revenue collected may be paid out to them. - Private(AccountId), -} -pub type ContributorOf = Contributor<::AccountId>; - -/// The record of a Region which was contributed to the Instantaneous Coretime Pool. This helps +/// The record body of a Region which was contributed to the Instantaneous Coretime Pool. This helps /// with making pro rata payments to contributors. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ContributionRecord { - /// The beginning of the Region contributed. - pub begin: Timeslice, /// The end of the Region contributed. - pub end: Timeslice, - /// The index of the Polkadot Core contributed. - pub core: CoreIndex, - /// The regularity parts of the Polkadot Core contributed. - pub part: CorePart, + pub length: Timeslice, /// The identity of the contributor. - pub payee: Contributor, + pub payee: AccountId, } pub type ContributionRecordOf = ContributionRecord<::AccountId>; /// A per-timeslice bookkeeping record for tracking Instantaneous Coretime Pool activity and /// making proper payments to contributors. -#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive(Encode, Decode, Clone, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct InstaPoolHistoryRecord { /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block /// of a Polkadot Core) contributed over a timeslice minus any contributions which have /// already been paid out. pub total_contributions: PartCount, + /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block + /// of a Polkadot Core) contributed by the Polkadot System in this timeslice. + pub system_contributions: PartCount, /// The payout remaining for the `total_contributions`, or `None` if the revenue is not yet /// known. pub maybe_payout: Option, @@ -109,15 +96,28 @@ pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; /// General status of the system. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct StatusRecord { - /// The current size of the Instantaneous Coretime Pool, measured in (measured in - /// Regularity Parts or 1/80th of a single block of a Polkadot Core). + /// The current size of the Instantaneous Coretime Pool, measured in + /// Regularity Parts or 1/80th of a single block of a Polkadot Core. pub pool_size: PartCount, + /// The current amount of the Instantaneous Coretime Pool which is provided by the Polkadot + /// System, rather than provided as a result of privately operated Coretime. + pub system_pool_size: PartCount, /// The last (Relay-chain) timeslice which we processed for (this processing is generally /// done some number of timeslices in advance of actual Relay-chain execution to make up /// for latencies and any needed Relay-side preparations). pub last_timeslice: Timeslice, } +/// A record of flux in the InstaPool. +#[derive(Encode, Decode, Clone, Copy, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct PoolIoRecord { + /// The total change of the pool, measured in Regularity Parts. + pub total: SignedPartCount, + /// The total change of the portion of the pool supplied by the Polkaot System, + /// measured in Regularity Parts. + pub system: SignedPartCount, +} + /// The status of a Bulk Coretime Sale. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct SaleInfoRecord { From ed575188297de3aadd1ff98a80cd51d0ab7aa51b Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 21:13:34 +0200 Subject: [PATCH 019/131] Better Relay Test framework --- frame/broker/src/implementation.rs | 2 +- frame/broker/src/mock.rs | 78 +++++++++++++++++++++++++----- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index c801ed66a7e7e..1b36a1b87e71b 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -264,7 +264,7 @@ impl Pallet { } Ok(()) } - + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { let mut r = Reservations::::get(); r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index d29a98d9bcb69..3b70266422b47 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -18,6 +18,7 @@ #![cfg(test)] use crate::*; +use sp_std::collections::btree_map::BTreeMap; use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate}}, assert_ok, PalletId}; use sp_arithmetic::Perbill; use sp_core::{H256, ConstU64, ConstU16, ConstU32}; @@ -82,28 +83,82 @@ use CoretimeTraceItem::*; parameter_types!{ pub static CoretimeTrace: Vec<(u32, CoretimeTraceItem)> = Default::default(); + pub static CoretimeCredit: BTreeMap = Default::default(); + pub static CoretimeSpending: Vec<(u32, u64)> = Default::default(); + pub static CoretimeWorkplan: BTreeMap<(u32, CoreIndex), Vec<(CoreAssignment, PartsOf57600)>> = Default::default(); + pub static CoretimeUsage: BTreeMap> = Default::default(); + pub static CoretimeInPool: PartCount = 0; + pub static NotifyCoreCount: Vec = Default::default(); + pub static NotifyRevenueInfo: Vec<(u32, u64)> = Default::default(); } -impl CoretimeInterface for CoretimeTrace { - type AccountId = (); +pub struct TestCoretimeProvider; +impl CoretimeInterface for TestCoretimeProvider { + type AccountId = u64; type Balance = u64; type BlockNumber = u32; fn latest() -> Self::BlockNumber { System::block_number() as u32 } - fn request_core_count(_count: CoreIndex) {} - fn request_revenue_info_at(_when: Self::BlockNumber) {} - fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} + fn request_core_count(count: CoreIndex) { + NotifyCoreCount::mutate(|s| s.insert(0, count)); + } + fn request_revenue_info_at(when: Self::BlockNumber) { + let mut total = 0; + CoretimeSpending::mutate(|s| s.retain(|(n, a)| if *n < when { total += a; false } else { true })); + NotifyRevenueInfo::mutate(|s| s.insert(0, (when, total))); + } + fn credit_account(who: Self::AccountId, amount: Self::Balance) { + CoretimeCredit::mutate(|c| *c.entry(who).or_default() += amount); + } fn assign_core( core: CoreIndex, begin: Self::BlockNumber, assignment: Vec<(CoreAssignment, PartsOf57600)>, end_hint: Option, ) { - let mut v = CoretimeTrace::get(); - v.push((Self::latest(), AssignCore { core, begin, assignment, end_hint })); - CoretimeTrace::set(v); + CoretimeWorkplan::mutate(|p| p.insert((begin, core), assignment.clone())); + let item = (Self::latest(), AssignCore { core, begin, assignment, end_hint }); + CoretimeTrace::mutate(|v| v.push(item)); + } + fn check_notify_core_count() -> Option { + NotifyCoreCount::mutate(|s| s.pop()) + } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { + NotifyRevenueInfo::mutate(|s| s.pop()) + } +} +impl TestCoretimeProvider { + pub fn spend_instantaneous(who: u64, price: u64) -> Result<(), ()> { + let mut c = CoretimeCredit::get(); + c.insert(who, c.get(&who).ok_or(())?.checked_sub(price).ok_or(())?); + CoretimeCredit::set(c); + CoretimeSpending::mutate(|v| v.push((Self::latest(), price))); + Ok(()) + } + pub fn bump() { + let mut pool_size = CoretimeInPool::get(); + let mut workplan = CoretimeWorkplan::get(); + let mut usage = CoretimeUsage::get(); + let now = Self::latest(); + workplan.retain(|(when, core), assignment| { + if *when <= now { + if let Some(old_assignment) = usage.get(core) { + if let Some(a) = old_assignment.iter().find(|i| i.0 == CoreAssignment::Pool) { + pool_size -= (a.1 / 720) as PartCount; + } + } + if let Some(a) = assignment.iter().find(|i| i.0 == CoreAssignment::Pool) { + pool_size += (a.1 / 720) as PartCount; + } + usage.insert(*core, assignment.clone()); + false + } else { + true + } + }); + CoretimeInPool::set(pool_size); + CoretimeWorkplan::set(workplan); + CoretimeUsage::set(usage); } - fn check_notify_core_count() -> Option { None } - fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } } parameter_types! { @@ -117,7 +172,7 @@ impl crate::Config for Test { type TimeslicePeriod = ConstU32<2>; type MaxLeasedCores = ConstU32<5>; type MaxReservedCores = ConstU32<5>; - type Coretime = CoretimeTrace; + type Coretime = TestCoretimeProvider; type ConvertBalance = Identity; type WeightInfo = (); type PalletId = TestBrokerId; @@ -126,6 +181,7 @@ impl crate::Config for Test { pub fn advance_to(b: u64) { while System::block_number() < b { System::set_block_number(System::block_number() + 1); + TestCoretimeProvider::bump(); Broker::on_initialize(System::block_number()); } } From f09cde2b7ff7d4a60d5a063bc6247f7d1f787115 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 10 Jul 2023 23:43:00 +0200 Subject: [PATCH 020/131] Tests and instapool fixes --- frame/broker/README.md | 8 +-- frame/broker/src/implementation.rs | 98 ++++++++++++++++++------------ frame/broker/src/lib.rs | 1 + frame/broker/src/mock.rs | 20 +++++- frame/broker/src/tests.rs | 55 ++++++++++++++++- 5 files changed, 134 insertions(+), 48 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index c386138f7ca94..7d664d91169e7 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -13,9 +13,9 @@ Properly described in RFC-0001 Agile Coretime. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 -------------------------------------------------------- < interlude > - < sale > - ... of which ... > - < descending-price >< fixed-price > + < sale > + ... of which ... + < descending-price >< fixed-price > | <-------\ price fixed, unsold assigned to instapool, system cores reserved -/ ``` @@ -32,8 +32,6 @@ fn main() { # TODO -- System Pooling & revenue -- Pool rewards - Dispatchables - Benchmarks diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 1b36a1b87e71b..50762a53b7838 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -27,7 +27,6 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let commit_timeslice = status.last_timeslice + config.advance_notice; - Self::process_timeslice(commit_timeslice, &mut status, &config); if let Some(sale) = SaleInfo::::get() { if commit_timeslice >= sale.region_begin { @@ -36,6 +35,8 @@ impl Pallet { } } + Self::process_timeslice(commit_timeslice, &mut status, &config); + Status::::put(&status); Ok(()) } @@ -100,19 +101,37 @@ impl Pallet { ) -> Option<()> { let now = frame_system::Pallet::::block_number(); + let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CorePart::complete() }; + let just_pool = Schedule::truncate_from(vec![pool_item]); + + // Clean up the old sale - we need to use up any unused cores by putting them into the + // InstaPool. + let mut total_old_pooled: SignedPartCount = 0; + for i in old_sale.cores_sold..old_sale.cores_offered { + total_old_pooled.saturating_accrue(80); + Workplan::::insert((old_sale.region_begin, old_sale.first_core + i), &just_pool); + } + InstaPoolIo::::mutate(old_sale.region_begin, |r| { + r.total.saturating_accrue(total_old_pooled); + r.system.saturating_accrue(total_old_pooled); + }); + InstaPoolIo::::mutate(old_sale.region_end, |r| { + r.total.saturating_reduce(total_old_pooled); + r.system.saturating_reduce(total_old_pooled); + }); + // Calculate the start price for the sale after. - let (reserve_price, unused) = { + let reserve_price = { let core_count = config.core_count; - let max_retail = core_count.saturating_sub(old_sale.first_core); - let offered = old_sale.cores_offered.min(max_retail); - let ideal = old_sale.ideal_cores_sold.min(max_retail); + let offered = old_sale.cores_offered; + let ideal = old_sale.ideal_cores_sold; let sold = old_sale.cores_sold; let old_price = old_sale.reserve_price; - (if offered > 0 { + if offered > 0 { Self::bump_price(offered, ideal, sold, old_price) } else { old_price - }, offered.saturating_sub(ideal)) + } }; let start_price = reserve_price * 2u32.into(); @@ -132,14 +151,6 @@ impl Pallet { Workplan::::insert((region_begin, first_core), &schedule); first_core.saturating_inc(); } - let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CorePart::complete() }; - let just_pool = Schedule::truncate_from(vec![pool_item]); - for _ in 0..unused { - total_pooled.saturating_accrue(80); - Workplan::::insert((region_begin, first_core), &just_pool); - first_core.saturating_inc(); - } - InstaPoolIo::::mutate(region_begin, |r| { r.total.saturating_accrue(total_pooled); r.system.saturating_accrue(total_pooled); @@ -196,23 +207,25 @@ impl Pallet { T::PalletId::get().into_account_truncating() } - pub(crate) fn do_check_revenue() -> DispatchResult { + pub(crate) fn do_check_revenue() -> Result { if let Some((until, amount)) = T::Coretime::check_notify_revenue_info() { let timeslice: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); let mut amount = T::ConvertBalance::convert_back(amount); if amount.is_zero() { InstaPoolHistory::::remove(timeslice); - return Ok(()) + return Ok(true) } let mut pool_record = InstaPoolHistory::::get(timeslice).unwrap_or_default(); ensure!(pool_record.maybe_payout.is_none(), Error::::RevenueAlreadyKnown); + ensure!(pool_record.total_contributions >= pool_record.system_contributions, Error::::InvalidContributions); + ensure!(pool_record.total_contributions > 0, Error::::InvalidContributions); // Payout system InstaPool Cores. let system_payout = amount.saturating_mul(pool_record.system_contributions.into()) / pool_record.total_contributions.into(); let _ = Self::charge(&Self::account_id(), system_payout); - pool_record.system_contributions = 0; pool_record.total_contributions.saturating_reduce(pool_record.system_contributions); + pool_record.system_contributions = 0; amount.saturating_reduce(system_payout); if !amount.is_zero() && pool_record.total_contributions > 0 { @@ -221,8 +234,9 @@ impl Pallet { } else { InstaPoolHistory::::remove(timeslice); } + return Ok(true) } - Ok(()) + Ok(false) } pub(crate) fn do_purchase_credit( @@ -237,31 +251,35 @@ impl Pallet { } // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. - pub(crate) fn do_claim_revenue(region: RegionId) -> DispatchResult { - let mut pool_record = InstaPoolHistory::::get(region.begin).ok_or(Error::::NoRevenue)?; - let total_payout = pool_record.maybe_payout.ok_or(Error::::UnknownRevenue)?; - let mut contribution = InstaPoolContribution::::take(region).ok_or(Error::::UnknownContribution)?; + pub(crate) fn do_claim_revenue(mut region: RegionId, max_timeslices: Timeslice) -> DispatchResult { + let mut contribution = InstaPoolContribution::::take(region) + .ok_or(Error::::UnknownContribution)?; let contributed_parts = region.part.count_ones(); - contribution.length.saturating_dec(); + let mut payout = BalanceOf::::zero(); + let last = region.begin + contribution.length.min(max_timeslices); + for r in region.begin..last { + let mut pool_record = match InstaPoolHistory::::get(r) { Some(x) => x, None => continue }; + let total_payout = match pool_record.maybe_payout { Some(x) => x, None => break }; + region.begin = r; + contribution.length.saturating_dec(); + payout.saturating_accrue(total_payout.saturating_mul(contributed_parts.into()) + / pool_record.total_contributions.into()); + pool_record.total_contributions.saturating_reduce(contributed_parts); + + let remaining_payout = total_payout.saturating_sub(payout); + if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { + pool_record.maybe_payout = Some(remaining_payout); + InstaPoolHistory::::insert(region.begin, &pool_record); + } else { + InstaPoolHistory::::remove(region.begin); + } + }; + if contribution.length > 0 { - let next_region = RegionId { begin: region.begin + 1, ..region }; - InstaPoolContribution::::insert(next_region, &contribution); + InstaPoolContribution::::insert(region, &contribution); } - - let payout = total_payout.saturating_mul(contributed_parts.into()) - / pool_record.total_contributions.into(); T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable).defensive_ok(); - - pool_record.total_contributions.saturating_reduce(contributed_parts); - - let remaining_payout = total_payout.saturating_sub(payout); - if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { - pool_record.maybe_payout = Some(remaining_payout); - InstaPoolHistory::::insert(region.begin, &pool_record); - } else { - InstaPoolHistory::::remove(region.begin); - } Ok(()) } @@ -289,7 +307,7 @@ impl Pallet { fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); status.pool_size = (status.pool_size as i32).saturating_add(pool_io.total) as u32; - status.system_pool_size = (status.pool_size as i32).saturating_add(pool_io.system) as u32; + status.system_pool_size = (status.system_pool_size as i32).saturating_add(pool_io.system) as u32; let record = InstaPoolHistoryRecord { total_contributions: status.pool_size, system_contributions: status.system_pool_size, diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 42c509bc9b970..0e61160d1a6a0 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -191,6 +191,7 @@ pub mod pallet { NoRevenue, UnknownRevenue, UnknownContribution, + InvalidContributions, } #[pallet::hooks] diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 3b70266422b47..d3a45de57c482 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -19,7 +19,7 @@ use crate::*; use sp_std::collections::btree_map::BTreeMap; -use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate}}, assert_ok, PalletId}; +use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate, Inspect, Credit, Balanced}, OnUnbalanced}, assert_ok, PalletId, ensure}; use sp_arithmetic::Perbill; use sp_core::{H256, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ @@ -129,6 +129,7 @@ impl CoretimeInterface for TestCoretimeProvider { impl TestCoretimeProvider { pub fn spend_instantaneous(who: u64, price: u64) -> Result<(), ()> { let mut c = CoretimeCredit::get(); + ensure!(CoretimeInPool::get() > 0, ()); c.insert(who, c.get(&who).ok_or(())?.checked_sub(price).ok_or(())?); CoretimeCredit::set(c); CoretimeSpending::mutate(|v| v.push((Self::latest(), price))); @@ -165,10 +166,17 @@ parameter_types! { pub const TestBrokerId: PalletId = PalletId(*b"TsBroker"); } +pub struct IntoZero; +impl OnUnbalanced::Currency>> for IntoZero { + fn on_nonzero_unbalanced(credit: Credit::Currency>) { + let _ = <::Currency as Balanced<_>>::resolve(&0, credit); + } +} + impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; - type OnRevenue = (); + type OnRevenue = IntoZero; type TimeslicePeriod = ConstU32<2>; type MaxLeasedCores = ConstU32<5>; type MaxReservedCores = ConstU32<5>; @@ -186,6 +194,14 @@ pub fn advance_to(b: u64) { } } +pub fn pot() -> u64 { + <::Currency as Inspect<_>>::total_balance(&Broker::account_id()) +} + +pub fn revenue() -> u64 { + <::Currency as Inspect<_>>::total_balance(&0) +} + pub struct TestExt(ConfigRecordOf); impl TestExt { pub fn new() -> Self { diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 2ab2f18b4d3ef..c250004a1a44f 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -18,7 +18,7 @@ #![cfg(test)] use crate::{*, mock::*, core_part::*}; -use frame_support::{assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok, traits::fungible::Inspect}; use CoreAssignment::*; use CoretimeTraceItem::*; @@ -31,6 +31,59 @@ fn basic_initialize_works() { }); } +#[test] +fn instapool_payouts_work() { + TestExt::new().core_count(3).endow(1, 1000).execute_with(|| { + let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; + assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region = RegionId { begin, core: 1, part: CorePart::complete() }; + assert_ok!(Broker::do_pool(region, None, 2)); + assert_ok!(Broker::do_purchase_credit(1, 20, 1)); + advance_to(8); + assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); + advance_to(10); + while Broker::do_check_revenue().unwrap() {} + assert_eq!(pot(), 14); + assert_eq!(revenue(), 106); + assert_ok!(Broker::do_claim_revenue(region, 100)); + assert_eq!(pot(), 10); + assert_eq!(::Currency::total_balance(&2), 4); + }); +} + +#[test] +fn instapool_partial_core_payouts_work() { + TestExt::new().core_count(2).endow(1, 1000).execute_with(|| { + let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; + assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + assert_ok!(Broker::do_purchase(1, u64::max_value())); + let begin = SaleInfo::::get().unwrap().region_begin; + let region = RegionId { begin, core: 1, part: CorePart::complete() }; + assert_ok!(Broker::do_interlace(region, None, CorePart::from_chunk(0, 20))); + let region1 = RegionId { begin, core: 1, part: CorePart::from_chunk(0, 20) }; + let region2 = RegionId { begin, core: 1, part: CorePart::from_chunk(20, 80) }; + assert_ok!(Broker::do_pool(region1, None, 2)); + assert_ok!(Broker::do_pool(region2, None, 3)); + assert_ok!(Broker::do_purchase_credit(1, 40, 1)); + advance_to(8); + assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); + advance_to(10); + while Broker::do_check_revenue().unwrap() {} + assert_ok!(Broker::do_claim_revenue(region1, 100)); + assert_ok!(Broker::do_claim_revenue(region2, 100)); + assert_eq!(pot(), 0); + assert_eq!(revenue(), 120); + assert_eq!(::Currency::total_balance(&2), 5); + assert_eq!(::Currency::total_balance(&3), 15); + }); +} + #[test] fn initialize_with_system_paras_works() { TestExt::new().core_count(2).execute_with(|| { From bd090a13e62f9b1974387ca31a6c8487690e9cd5 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 12:38:50 +0200 Subject: [PATCH 021/131] Support NFT interface --- frame/broker/README.md | 1 + frame/broker/src/core_part.rs | 18 ++++++++++-- frame/broker/src/implementation.rs | 1 - frame/broker/src/lib.rs | 2 ++ frame/broker/src/nonfungible_impl.rs | 44 ++++++++++++++++++++++++++++ frame/broker/src/types.rs | 22 ++++++++++++++ 6 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 frame/broker/src/nonfungible_impl.rs diff --git a/frame/broker/README.md b/frame/broker/README.md index 7d664d91169e7..78b3074bf5da8 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -33,6 +33,7 @@ fn main() { # TODO - Dispatchables +- nonfungible impl - Benchmarks - Weights diff --git a/frame/broker/src/core_part.rs b/frame/broker/src/core_part.rs index 2c15512294db7..d3d5edc2479d6 100644 --- a/frame/broker/src/core_part.rs +++ b/frame/broker/src/core_part.rs @@ -48,12 +48,15 @@ impl CorePart { impl From for CorePart { fn from(x: u128) -> Self { let mut v = [0u8; 10]; - for i in 0..10 { - v[i] = (x >> (72 - 8 * i)) as u8; - } + v.iter_mut().rev().fold(x, |a, i| { *i = a as u8; a >> 8 }); Self(v) } } +impl From for u128 { + fn from(x: CorePart) -> Self { + x.0.into_iter().fold(0u128, |a, i| a << 8 | i as u128) + } +} impl BitAnd for CorePart { type Output = Self; fn bitand(self, rhs: Self) -> Self { @@ -147,6 +150,15 @@ mod tests { ); } + #[test] + fn into_works() { + assert_eq!(u128::from(CorePart::complete()), 0xfffff_fffff_fffff_fffff); + assert_eq!( + 0x12345_67890_abcde_f0123u128, + CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]).into(), + ); + } + #[test] fn chunk_works() { assert_eq!( diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 50762a53b7838..aa32c1a5d066e 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -122,7 +122,6 @@ impl Pallet { // Calculate the start price for the sale after. let reserve_price = { - let core_count = config.core_count; let offered = old_sale.cores_offered; let ideal = old_sale.ideal_cores_sold; let sold = old_sale.cores_sold; diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 0e61160d1a6a0..8db8dce21757f 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -29,6 +29,7 @@ mod types; mod coretime_interface; mod utils; mod implementation; +mod nonfungible_impl; pub mod weights; pub use weights::WeightInfo; @@ -37,6 +38,7 @@ pub use types::*; pub use core_part::*; pub use coretime_interface::*; pub use utils::*; +pub use nonfungible_impl::*; #[frame_support::pallet] pub mod pallet { diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs new file mode 100644 index 0000000000000..3e8e8d4297cca --- /dev/null +++ b/frame/broker/src/nonfungible_impl.rs @@ -0,0 +1,44 @@ +use super::*; +use sp_runtime::TokenError; +use frame_support::{ + pallet_prelude::{*, DispatchResult}, + traits::{ + nonfungible::{Inspect, Transfer}, + } +}; + +impl Inspect for Pallet { + type ItemId = u128; + + fn owner(index: &Self::ItemId) -> Option { + Regions::::get(RegionId::from(*index)).map(|r| r.owner) + } + + fn attribute(index: &Self::ItemId, key: &[u8]) -> Option> { + let id = RegionId::from(*index); + let item = Regions::::get(id)?; + match key { + b"begin" => Some(id.begin.encode()), + b"end" => Some(item.end.encode()), + b"length" => Some(item.end.saturating_sub(id.begin).encode()), + b"core" => Some(id.core.encode()), + b"part" => Some(id.part.encode()), + b"owner" => Some(item.owner.encode()), + b"paid" => Some(item.paid.encode()), + _ => None, + } + } +} + +impl Transfer for Pallet { + fn transfer(index: &Self::ItemId, dest: &T::AccountId) -> DispatchResult { + let region_id = RegionId::from(*index); + let mut item = Regions::::get(region_id).ok_or(TokenError::UnknownAsset)?; + let old_owner = item.owner; + item.owner = dest.clone(); + Regions::::insert(®ion_id, &item); + let e = Event::::Transferred { region_id, old_owner, owner: item.owner }; + Pallet::::deposit_event(e); + Ok(()) + } +} diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index a57d89d17a98f..a6c5648c7fc20 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -30,6 +30,27 @@ pub struct RegionId { /// The regularity parts in which this Region will be scheduled. pub part: CorePart, } +impl From for RegionId { + fn from(x: u128) -> Self { + Self { + begin: (x >> 96) as u32, + core: (x >> 80) as u16, + part: x.into(), + } + } +} +impl From for u128 { + fn from(x: RegionId) -> Self { + (x.begin as u128) << 96 | (x.core as u128) << 80 | u128::from(x.part) + } +} +#[test] +fn region_id_converts_u128() { + let r = RegionId { begin: 0x12345678u32, core: 0xabcdu16, part: 0xdeadbeefcafef00d0123.into() }; + let u = 0x12345678_abcd_deadbeefcafef00d0123u128; + assert_eq!(RegionId::from(u), r); + assert_eq!(u128::from(r), u); +} /// The rest of the information describing a Region. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -89,6 +110,7 @@ pub struct AllowedRenewalRecord { /// The price for which the next renewal can be made. pub price: Balance, /// The workload which will be scheduled on the Core in the case a renewal is made. + // TODO: Use this as a counter; the renewal is not allowed until this is a complete schedule. pub workload: Schedule, } pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; From ad48ade0a7293f6359983a9a46ab265d7152c457 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 13:33:07 +0200 Subject: [PATCH 022/131] Proper renewals --- frame/broker/src/implementation.rs | 34 +++++++++++++++++------------- frame/broker/src/lib.rs | 1 + frame/broker/src/types.rs | 24 ++++++++++++++++++--- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index aa32c1a5d066e..b34b38c5c16f2 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -1,4 +1,5 @@ use super::*; +use CompletionStatus::{Complete, Partial}; use sp_runtime::traits::{Convert, ConvertBack, AccountIdConversion}; use frame_support::{ pallet_prelude::{*, DispatchResult}, @@ -172,7 +173,7 @@ impl Pallet { let record = AllowedRenewalRecord { begin: region_end, price: reserve_price, - workload: schedule, + completion: Complete(schedule), }; AllowedRenewals::::insert(first_core, record); } @@ -366,6 +367,7 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + let workload = record.completion.complete().ok_or(Error::::IncompleteAssignment)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); ensure!(sale.first_core < config.core_count, Error::::Unavailable); @@ -376,7 +378,7 @@ impl Pallet { let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); - Workplan::::insert((record.begin, core), &record.workload); + Workplan::::insert((record.begin, core), workload); let begin = sale.region_end; let price = record.price + record.price / 100u32.into() * 2u32.into(); @@ -534,20 +536,22 @@ impl Pallet { }).is_ok() { Workplan::::insert(&workplan_key, &workplan); } + if region.end.saturating_sub(region_id.begin) == config.region_length { - if workplan.iter() - .filter(|i| matches!(i.assignment, CoreAssignment::Task(..))) - .fold(CorePart::void(), |a, i| a | i.part) - .is_complete() - { - if let Some(price) = region.paid { - let record = AllowedRenewalRecord { - begin: region.end, - price, - workload: workplan, - }; - AllowedRenewals::::insert(region_id.core, &record); - } + if let Some(price) = region.paid { + let begin = region.end; + let assigned = match AllowedRenewals::::get(region_id.core) { + Some(AllowedRenewalRecord { completion: Partial(w), begin: b, price: p }) + if begin == b && price == p => w, + _ => CorePart::void(), + } | region_id.part; + let workload = if assigned.is_complete() { + Complete(workplan) + } else { + Partial(assigned) + }; + let record = AllowedRenewalRecord { begin, price, completion: workload }; + AllowedRenewals::::insert(region_id.core, &record); } } Self::deposit_event(Event::Assigned { region_id, task: target }); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 8db8dce21757f..d75c2b9149ef2 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -194,6 +194,7 @@ pub mod pallet { UnknownRevenue, UnknownContribution, InvalidContributions, + IncompleteAssignment, } #[pallet::hooks] diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index a6c5648c7fc20..ba87de130364e 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -102,6 +102,24 @@ pub struct InstaPoolHistoryRecord { } pub type InstaPoolHistoryRecordOf = InstaPoolHistoryRecord>; +/// How much of a core has been assigned or, if completely assigned, the workload itself. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum CompletionStatus { + /// The core is not fully assigned; the inner is the parts which have. + Partial(CorePart), + /// The core is fully assigned; the inner is the workload which has been assigned. + Complete(Schedule), +} +impl CompletionStatus { + /// Return the complete workload, or `None` if incomplete. + pub fn complete(&self) -> Option<&Schedule> { + match self { + Self::Complete(s) => Some(s), + Self::Partial(_) => None, + } + } +} + /// A record of an allowed renewal. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct AllowedRenewalRecord { @@ -109,9 +127,9 @@ pub struct AllowedRenewalRecord { pub begin: Timeslice, /// The price for which the next renewal can be made. pub price: Balance, - /// The workload which will be scheduled on the Core in the case a renewal is made. - // TODO: Use this as a counter; the renewal is not allowed until this is a complete schedule. - pub workload: Schedule, + /// The workload which will be scheduled on the Core in the case a renewal is made, or if + /// incomplete, then the parts of the core which have been scheduled. + pub completion: CompletionStatus, } pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; From 065b01957b4a1a8ddaa55a96225bf5cc942d5168 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 14:57:07 +0200 Subject: [PATCH 023/131] Better events, results --- frame/broker/src/implementation.rs | 67 +++++++++++++++--------- frame/broker/src/lib.rs | 22 +++++++- frame/broker/src/nonfungible_impl.rs | 9 +--- frame/broker/src/tests.rs | 76 +++++++++++----------------- frame/broker/src/types.rs | 9 +++- 5 files changed, 103 insertions(+), 80 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index b34b38c5c16f2..759b184f7bd33 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -363,53 +363,69 @@ impl Pallet { /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the /// current sale status's `region_end`. - pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> DispatchResult { + pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> Result { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - let workload = record.completion.complete().ok_or(Error::::IncompleteAssignment)?; + let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); Self::charge(who, record.price)?; + Self::deposit_event(Event::Renewed { + who: who.clone(), + core, + price: record.price, + begin: sale.region_begin, + length: sale.region_end.saturating_sub(sale.region_begin), + workload: workload.clone(), + }); let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); - Workplan::::insert((record.begin, core), workload); + Workplan::::insert((record.begin, core), &workload); let begin = sale.region_end; let price = record.price + record.price / 100u32.into() * 2u32.into(); - let new_record = AllowedRenewalRecord { begin, price, .. record }; - AllowedRenewals::::insert(core, new_record); + let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; + AllowedRenewals::::insert(core, &new_record); SaleInfo::::put(&sale); - Ok(()) + if let Some(workload) = new_record.completion.drain_complete() { + Self::deposit_event(Event::Renewable { core, price, begin, workload }); + } + Ok(core) } - pub(crate) fn do_purchase(who: T::AccountId, price_limit: BalanceOf) -> DispatchResult { + pub(crate) fn do_purchase( + who: T::AccountId, + price_limit: BalanceOf, + ) -> Result { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let now = frame_system::Pallet::::block_number(); ensure!(now > sale.sale_start, Error::::TooEarly); - let current_price = lerp( + let price = lerp( now, sale.sale_start, sale.leadin_length, sale.start_price, sale.reserve_price, ).ok_or(Error::::IndeterminablePrice)?; - ensure!(price_limit >= current_price, Error::::Overpriced); + ensure!(price_limit >= price, Error::::Overpriced); - Self::charge(&who, current_price)?; + Self::charge(&who, price)?; let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); SaleInfo::::put(&sale); - Self::issue(core, sale.region_begin, sale.region_end, who, Some(current_price)); - Ok(()) + let id = Self::issue(core, sale.region_begin, sale.region_end, who.clone(), Some(price)); + let length = sale.region_end.saturating_sub(sale.region_begin); + Self::deposit_event(Event::Purchased { who, region_id: id, price, length }); + Ok(id) } pub(crate) fn issue( @@ -418,10 +434,11 @@ impl Pallet { end: Timeslice, owner: T::AccountId, paid: Option>, - ) { + ) -> RegionId { let id = RegionId { begin, core, part: CorePart::complete() }; let record = RegionRecord { end, owner, paid }; - Regions::::insert(id, record); + Regions::::insert(&id, &record); + id } pub(crate) fn do_transfer( @@ -446,15 +463,14 @@ impl Pallet { pub(crate) fn do_partition( region_id: RegionId, maybe_check_owner: Option, - pivot: Timeslice, - ) -> Result<(), Error> { + pivot_offset: Timeslice, + ) -> Result<(RegionId, RegionId), Error> { let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; if let Some(check_owner) = maybe_check_owner { ensure!(check_owner == region.owner, Error::::NotOwner); } - - ensure!(pivot > region_id.begin, Error::::PivotTooEarly); + let pivot = region_id.begin.saturating_add(pivot_offset); ensure!(pivot < region.end, Error::::PivotTooLate); region.paid = None; @@ -465,14 +481,14 @@ impl Pallet { Regions::::insert(&new_region_id, ®ion); Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); - Ok(()) + Ok((region_id, new_region_id)) } pub(crate) fn do_interlace( mut region_id: RegionId, maybe_check_owner: Option, pivot: CorePart, - ) -> Result<(), Error> { + ) -> Result<(RegionId, RegionId), Error> { let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; if let Some(check_owner) = maybe_check_owner { @@ -486,12 +502,12 @@ impl Pallet { let antipivot = region_id.part ^ pivot; region_id.part = pivot; Regions::::insert(®ion_id, ®ion); - region_id.part = antipivot; - Regions::::insert(®ion_id, ®ion); + let new_region_id = RegionId { part: antipivot, ..region_id }; + Regions::::insert(&new_region_id, ®ion); - Self::deposit_event(Event::Interlaced { region_id, pivot }); + Self::deposit_event(Event::Interlaced { region_id, pivot, new_region_id }); - Ok(()) + Ok((region_id, new_region_id)) } pub(crate) fn utilize( @@ -552,6 +568,9 @@ impl Pallet { }; let record = AllowedRenewalRecord { begin, price, completion: workload }; AllowedRenewals::::insert(region_id.core, &record); + if let Some(workload) = record.completion.drain_complete() { + Self::deposit_event(Event::Renewable { core: region_id.core, price, begin, workload }); + } } } Self::deposit_event(Event::Assigned { region_id, task: target }); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index d75c2b9149ef2..96c41268d9301 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -155,6 +155,7 @@ pub mod pallet { Interlaced { region_id: RegionId, pivot: CorePart, + new_region_id: RegionId, }, Assigned { region_id: RegionId, @@ -166,13 +167,32 @@ pub mod pallet { Pooled { region_id: RegionId, }, + Renewable { + core: CoreIndex, + price: BalanceOf, + begin: Timeslice, + workload: Schedule, + }, + Renewed { + who: T::AccountId, + core: CoreIndex, + price: BalanceOf, + begin: Timeslice, + length: Timeslice, + workload: Schedule, + }, + Purchased { + who: T::AccountId, + region_id: RegionId, + price: BalanceOf, + length: Timeslice, + }, } #[pallet::error] pub enum Error { UnknownRegion, NotOwner, - PivotTooEarly, PivotTooLate, ExteriorPivot, NullPivot, diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index 3e8e8d4297cca..450dd987fe324 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -32,13 +32,6 @@ impl Inspect for Pallet { impl Transfer for Pallet { fn transfer(index: &Self::ItemId, dest: &T::AccountId) -> DispatchResult { - let region_id = RegionId::from(*index); - let mut item = Regions::::get(region_id).ok_or(TokenError::UnknownAsset)?; - let old_owner = item.owner; - item.owner = dest.clone(); - Regions::::insert(®ion_id, &item); - let e = Event::::Transferred { region_id, old_owner, owner: item.owner }; - Pallet::::deposit_event(e); - Ok(()) + Self::do_transfer((*index).into(), None, dest.clone()).map_err(Into::into) } } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index c250004a1a44f..2179cf1a947e3 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -31,6 +31,18 @@ fn basic_initialize_works() { }); } +#[test] +fn transfer_then_purchase_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + + }); +} + +// TODO: Renewal. + #[test] fn instapool_payouts_work() { TestExt::new().core_count(3).endow(1, 1000).execute_with(|| { @@ -38,7 +50,7 @@ fn instapool_payouts_work() { assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let begin = SaleInfo::::get().unwrap().region_begin; let region = RegionId { begin, core: 1, part: CorePart::complete() }; assert_ok!(Broker::do_pool(region, None, 2)); @@ -62,12 +74,10 @@ fn instapool_partial_core_payouts_work() { assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let begin = SaleInfo::::get().unwrap().region_begin; let region = RegionId { begin, core: 1, part: CorePart::complete() }; - assert_ok!(Broker::do_interlace(region, None, CorePart::from_chunk(0, 20))); - let region1 = RegionId { begin, core: 1, part: CorePart::from_chunk(0, 20) }; - let region2 = RegionId { begin, core: 1, part: CorePart::from_chunk(20, 80) }; + let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); assert_ok!(Broker::do_pool(region1, None, 2)); assert_ok!(Broker::do_pool(region2, None, 3)); assert_ok!(Broker::do_purchase_credit(1, 40, 1)); @@ -115,9 +125,7 @@ fn purchase_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); - let begin = SaleInfo::::get().unwrap().region_begin; - let region = RegionId { begin, core: 0, part: CorePart::complete() }; + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_assign(region, None, 1000)); advance_to(6); assert_eq!(CoretimeTrace::get(), vec![ @@ -133,13 +141,9 @@ fn partition_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); - let begin = SaleInfo::::get().unwrap().region_begin; - let region1 = RegionId { begin, core: 0, part: CorePart::complete() }; - assert_ok!(Broker::do_partition(region1, None, begin + 1)); - let region2 = RegionId { begin: begin + 1, core: 0, part: CorePart::complete() }; - assert_ok!(Broker::do_partition(region2, None, begin + 2)); - let region3 = RegionId { begin: begin + 2, core: 0, part: CorePart::complete() }; + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, region) = Broker::do_partition(region, None, 1).unwrap(); + let (region2, region3) = Broker::do_partition(region, None, 1).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001)); assert_ok!(Broker::do_assign(region2, None, 1002)); assert_ok!(Broker::do_assign(region3, None, 1003)); @@ -163,15 +167,9 @@ fn interlace_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); - let begin = SaleInfo::::get().unwrap().region_begin; - let region1 = RegionId { begin, core: 0, part: CorePart::complete() }; - assert_ok!(Broker::do_interlace(region1, None, CorePart::from_chunk(0, 30))); - let region1 = RegionId { begin, core: 0, part: CorePart::from_chunk(0, 30) }; - let region2 = RegionId { begin, core: 0, part: CorePart::from_chunk(30, 80) }; - assert_ok!(Broker::do_interlace(region2, None, CorePart::from_chunk(30, 60))); - let region2 = RegionId { begin, core: 0, part: CorePart::from_chunk(30, 60) }; - let region3 = RegionId { begin, core: 0, part: CorePart::from_chunk(60, 80) }; + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, region) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 30)).unwrap(); + let (region2, region3) =Broker::do_interlace(region, None, CorePart::from_chunk(30, 60)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001)); assert_ok!(Broker::do_assign(region2, None, 1002)); assert_ok!(Broker::do_assign(region3, None, 1003)); @@ -191,16 +189,10 @@ fn interlace_then_partition_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); - let begin = SaleInfo::::get().unwrap().region_begin; - let region = RegionId { begin, core: 0, part: CorePart::complete() }; - assert_ok!(Broker::do_interlace(region, None, CorePart::from_chunk(0, 20))); - let region1 = RegionId { part: CorePart::from_chunk(0, 20), ..region }; - let region2 = RegionId { part: CorePart::from_chunk(20, 80), ..region }; - assert_ok!(Broker::do_partition(region1, None, begin + 1)); - assert_ok!(Broker::do_partition(region2, None, begin + 2)); - let region3 = RegionId { begin: begin + 1, ..region1 }; - let region4 = RegionId { begin: begin + 2, ..region2 }; + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); + let (region1, region3) = Broker::do_partition(region1, None, 1).unwrap(); + let (region2, region4) = Broker::do_partition(region2, None, 2).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001)); assert_ok!(Broker::do_assign(region2, None, 1002)); assert_ok!(Broker::do_assign(region3, None, 1003)); @@ -228,18 +220,10 @@ fn partition_then_interlace_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); - assert_ok!(Broker::do_purchase(1, u64::max_value())); - let begin = SaleInfo::::get().unwrap().region_begin; - let region = RegionId { begin, core: 0, part: CorePart::complete() }; - assert_ok!(Broker::do_partition(region, None, begin + 1)); - let region1 = RegionId { begin, ..region }; - let region2 = RegionId { begin: begin + 1, ..region }; - assert_ok!(Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20))); - assert_ok!(Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30))); - let region3 = RegionId { part: CorePart::from_chunk(20, 80), ..region1 }; - let region4 = RegionId { part: CorePart::from_chunk(30, 80), ..region2 }; - let region1 = RegionId { part: CorePart::from_chunk(0, 20), ..region1 }; - let region2 = RegionId { part: CorePart::from_chunk(0, 30), ..region2 }; + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); + let (region1, region3) = Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20)).unwrap(); + let (region2, region4) = Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001)); assert_ok!(Broker::do_assign(region2, None, 1002)); assert_ok!(Broker::do_assign(region3, None, 1003)); diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index ba87de130364e..4205fccbdf4a9 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -111,13 +111,20 @@ pub enum CompletionStatus { Complete(Schedule), } impl CompletionStatus { - /// Return the complete workload, or `None` if incomplete. + /// Return reference to the complete workload, or `None` if incomplete. pub fn complete(&self) -> Option<&Schedule> { match self { Self::Complete(s) => Some(s), Self::Partial(_) => None, } } + /// Return the complete workload, or `None` if incomplete. + pub fn drain_complete(self) -> Option { + match self { + Self::Complete(s) => Some(s), + Self::Partial(_) => None, + } + } } /// A record of an allowed renewal. From 46852d2783629f9989688ed8d63a681b3dae608c Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 15:05:09 +0200 Subject: [PATCH 024/131] Test transfer --- frame/broker/src/lib.rs | 1 + frame/broker/src/tests.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 96c41268d9301..149ae1e27c6be 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -190,6 +190,7 @@ pub mod pallet { } #[pallet::error] + #[derive(PartialEq)] pub enum Error { UnknownRegion, NotOwner, diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 2179cf1a947e3..990eec515ba1b 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -18,7 +18,7 @@ #![cfg(test)] use crate::{*, mock::*, core_part::*}; -use frame_support::{assert_noop, assert_ok, traits::fungible::Inspect}; +use frame_support::{assert_noop, assert_ok, traits::{fungible::Inspect, nonfungible::{Transfer, Inspect as NftInspect}}}; use CoreAssignment::*; use CoretimeTraceItem::*; @@ -32,12 +32,15 @@ fn basic_initialize_works() { } #[test] -fn transfer_then_purchase_works() { +fn transfer_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_start_sales(100)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - + assert_ok!(>::transfer(®ion.into(), &2)); + assert_eq!(>::owner(®ion.into()), Some(2)); + assert_noop!(Broker::do_assign(region, Some(1), 1001), Error::::NotOwner); + assert_ok!(Broker::do_assign(region, Some(2), 1002)); }); } From e309594efbd01a8d4eb0e0df455c1b0930ae4e72 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 15:14:39 +0200 Subject: [PATCH 025/131] Renewal test --- frame/broker/src/implementation.rs | 2 +- frame/broker/src/mock.rs | 14 ++++++++++++-- frame/broker/src/tests.rs | 27 +++++++++++++++++++++++---- frame/broker/src/types.rs | 2 ++ 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 759b184f7bd33..87e77874c3449 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -389,7 +389,7 @@ impl Pallet { Workplan::::insert((record.begin, core), &workload); let begin = sale.region_end; - let price = record.price + record.price / 100u32.into() * 2u32.into(); + let price = record.price + config.renewal_bump * record.price; let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; AllowedRenewals::::insert(core, &new_record); SaleInfo::::put(&sale); diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index d3a45de57c482..453c850e5da1b 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -195,11 +195,15 @@ pub fn advance_to(b: u64) { } pub fn pot() -> u64 { - <::Currency as Inspect<_>>::total_balance(&Broker::account_id()) + balance(Broker::account_id()) } pub fn revenue() -> u64 { - <::Currency as Inspect<_>>::total_balance(&0) + balance(0) +} + +pub fn balance(who: u64) -> u64 { + <::Currency as Inspect<_>>::total_balance(&who) } pub struct TestExt(ConfigRecordOf); @@ -213,6 +217,7 @@ impl TestExt { ideal_bulk_proportion: Default::default(), limit_cores_offered: None, region_length: 3, + renewal_bump: Perbill::from_percent(10), }) } @@ -251,6 +256,11 @@ impl TestExt { self } + pub fn renewal_bump(mut self, renewal_bump: Perbill) -> Self { + self.0.renewal_bump = renewal_bump; + self + } + pub fn endow(self, who: u64, amount: u64) -> Self { assert_ok!(<::Currency as Mutate<_>>::mint_into(&who, amount)); self diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 990eec515ba1b..ffffe9697adf0 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -44,7 +44,26 @@ fn transfer_works() { }); } -// TODO: Renewal. +#[test] +fn renewal_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_eq!(balance(1), 900); + assert_ok!(Broker::do_assign(region, None, 1001)); + // Should now be renewable. + advance_to(6); + assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::TooEarly); + let core = Broker::do_renew(&1, region.core).unwrap(); + assert_eq!(balance(1), 800); + advance_to(8); + assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::SoldOut); + advance_to(12); + let region = Broker::do_renew(&1, core).unwrap(); + assert_eq!(balance(1), 690); + }); +} #[test] fn instapool_payouts_work() { @@ -66,7 +85,7 @@ fn instapool_payouts_work() { assert_eq!(revenue(), 106); assert_ok!(Broker::do_claim_revenue(region, 100)); assert_eq!(pot(), 10); - assert_eq!(::Currency::total_balance(&2), 4); + assert_eq!(balance(2), 4); }); } @@ -92,8 +111,8 @@ fn instapool_partial_core_payouts_work() { assert_ok!(Broker::do_claim_revenue(region2, 100)); assert_eq!(pot(), 0); assert_eq!(revenue(), 120); - assert_eq!(::Currency::total_balance(&2), 5); - assert_eq!(::Currency::total_balance(&3), 15); + assert_eq!(balance(2), 5); + assert_eq!(balance(3), 15); }); } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 4205fccbdf4a9..f9ac0072aa327 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -226,6 +226,8 @@ pub struct ConfigRecord { /// An artificial limit to the number of cores which are allowed to be sold. If `Some` then /// no more cores will be sold than this. pub limit_cores_offered: Option, + /// The amount by which the renewal price increases each sale period. + pub renewal_bump: Perbill, } pub type ConfigRecordOf = ConfigRecord< ::BlockNumber, From 955356f17ea1105da85821d7f85e23b62129c90f Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 16:25:42 +0200 Subject: [PATCH 026/131] Repot some impls and make dispatchables. --- frame/broker/README.md | 2 +- frame/broker/src/dispatchable_impls.rs | 317 +++++++++++++++++++++++++ frame/broker/src/implementation.rs | 298 +---------------------- frame/broker/src/lib.rs | 130 +++++++++- frame/broker/src/mock.rs | 2 + frame/broker/src/tests.rs | 8 +- frame/broker/src/weights.rs | 47 +++- frame/core-fellowship/src/lib.rs | 2 +- frame/glutton/src/lib.rs | 6 +- frame/support/src/traits/dispatch.rs | 24 ++ 10 files changed, 525 insertions(+), 311 deletions(-) create mode 100644 frame/broker/src/dispatchable_impls.rs diff --git a/frame/broker/README.md b/frame/broker/README.md index 78b3074bf5da8..4a554967b302c 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -33,7 +33,7 @@ fn main() { # TODO - Dispatchables -- nonfungible impl +- Nicer API for price finding; should include auction-sell-out info - Benchmarks - Weights diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs new file mode 100644 index 0000000000000..33ba72f914c0f --- /dev/null +++ b/frame/broker/src/dispatchable_impls.rs @@ -0,0 +1,317 @@ +use super::*; +use CompletionStatus::{Complete, Partial}; +use sp_runtime::traits::{Convert, ConvertBack, AccountIdConversion}; +use frame_support::{ + pallet_prelude::{*, DispatchResult}, + traits::{ + tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, + fungible::{Mutate, Balanced}, OnUnbalanced, DefensiveResult, + } +}; +use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; + +impl Pallet { + pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { + Configuration::::put(config); + Ok(()) + } + + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { + let mut r = Reservations::::get(); + r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; + Reservations::::put(r); + Ok(()) + } + + pub(crate) fn do_unreserve(item_index: u32) -> DispatchResult { + let mut r = Reservations::::get(); + r.remove(item_index as usize); + Reservations::::put(r); + Ok(()) + } + + pub(crate) fn do_set_lease(task: TaskId, until: Timeslice) -> DispatchResult { + let mut r = Leases::::get(); + r.try_push((until, task)).map_err(|_| Error::::TooManyLeases)?; + Leases::::put(r); + Ok(()) + } + + pub(crate) fn do_start_sales( + reserve_price: BalanceOf, + ) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = StatusRecord { + pool_size: 0, + last_timeslice: Self::current_timeslice(), + system_pool_size: 0, + }; + let commit_timeslice = status.last_timeslice + config.advance_notice; + let now = frame_system::Pallet::::block_number(); + let dummy_sale = SaleInfoRecord { + sale_start: now, + leadin_length: Zero::zero(), + start_price: Zero::zero(), + reserve_price, + region_begin: commit_timeslice, + region_end: commit_timeslice + config.region_length, + first_core: 0, + ideal_cores_sold: 0, + cores_offered: 0, + cores_sold: 0, + }; + Self::rotate_sale(dummy_sale, &config); + Status::::put(&status); + Ok(()) + } + + pub(crate) fn do_purchase( + who: T::AccountId, + price_limit: BalanceOf, + ) -> Result { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + let now = frame_system::Pallet::::block_number(); + ensure!(now > sale.sale_start, Error::::TooEarly); + let price = lerp( + now, + sale.sale_start, + sale.leadin_length, + sale.start_price, + sale.reserve_price, + ).ok_or(Error::::IndeterminablePrice)?; + ensure!(price_limit >= price, Error::::Overpriced); + + Self::charge(&who, price)?; + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + SaleInfo::::put(&sale); + let id = Self::issue(core, sale.region_begin, sale.region_end, who.clone(), Some(price)); + let length = sale.region_end.saturating_sub(sale.region_begin); + Self::deposit_event(Event::Purchased { who, region_id: id, price, length }); + Ok(id) + } + + /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the + /// current sale status's `region_end`. + pub(crate) fn do_renew(who: T::AccountId, core: CoreIndex) -> Result { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; + let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; + let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; + + ensure!(record.begin == sale.region_begin, Error::::WrongTime); + ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + + Self::charge(&who, record.price)?; + Self::deposit_event(Event::Renewed { + who, + core, + price: record.price, + begin: sale.region_begin, + length: sale.region_end.saturating_sub(sale.region_begin), + workload: workload.clone(), + }); + + let core = sale.first_core + sale.cores_sold; + sale.cores_sold.saturating_inc(); + + Workplan::::insert((record.begin, core), &workload); + + let begin = sale.region_end; + let price = record.price + config.renewal_bump * record.price; + let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; + AllowedRenewals::::insert(core, &new_record); + SaleInfo::::put(&sale); + if let Some(workload) = new_record.completion.drain_complete() { + Self::deposit_event(Event::Renewable { core, price, begin, workload }); + } + Ok(core) + } + + pub(crate) fn do_transfer( + region_id: RegionId, + maybe_check_owner: Option, + new_owner: T::AccountId, + ) -> Result<(), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + let old_owner = region.owner; + region.owner = new_owner; + Regions::::insert(®ion_id, ®ion); + Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); + + Ok(()) + } + + pub(crate) fn do_partition( + region_id: RegionId, + maybe_check_owner: Option, + pivot_offset: Timeslice, + ) -> Result<(RegionId, RegionId), Error> { + let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + let pivot = region_id.begin.saturating_add(pivot_offset); + ensure!(pivot < region.end, Error::::PivotTooLate); + + region.paid = None; + let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; + let new_region = RegionRecord { end: pivot, ..region.clone() }; + + Regions::::insert(®ion_id, &new_region); + Regions::::insert(&new_region_id, ®ion); + Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); + + Ok((region_id, new_region_id)) + } + + pub(crate) fn do_interlace( + mut region_id: RegionId, + maybe_check_owner: Option, + pivot: CorePart, + ) -> Result<(RegionId, RegionId), Error> { + let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); + ensure!(!pivot.is_void(), Error::::NullPivot); + ensure!(pivot != region_id.part, Error::::CompletePivot); + + let antipivot = region_id.part ^ pivot; + region_id.part = pivot; + Regions::::insert(®ion_id, ®ion); + let new_region_id = RegionId { part: antipivot, ..region_id }; + Regions::::insert(&new_region_id, ®ion); + + Self::deposit_event(Event::Interlaced { region_id, pivot, new_region_id }); + + Ok((region_id, new_region_id)) + } + + pub(crate) fn do_assign( + region_id: RegionId, + maybe_check_owner: Option, + target: TaskId, + ) -> Result<(), Error> { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + assignment: CoreAssignment::Task(target), + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + } + + if region.end.saturating_sub(region_id.begin) == config.region_length { + if let Some(price) = region.paid { + let begin = region.end; + let assigned = match AllowedRenewals::::get(region_id.core) { + Some(AllowedRenewalRecord { completion: Partial(w), begin: b, price: p }) + if begin == b && price == p => w, + _ => CorePart::void(), + } | region_id.part; + let workload = if assigned.is_complete() { + Complete(workplan) + } else { + Partial(assigned) + }; + let record = AllowedRenewalRecord { begin, price, completion: workload }; + AllowedRenewals::::insert(region_id.core, &record); + if let Some(workload) = record.completion.drain_complete() { + Self::deposit_event(Event::Renewable { core: region_id.core, price, begin, workload }); + } + } + } + Self::deposit_event(Event::Assigned { region_id, task: target }); + } + Ok(()) + } + + pub(crate) fn do_pool( + region_id: RegionId, + maybe_check_owner: Option, + payee: T::AccountId, + ) -> Result<(), Error> { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + let workplan_key = (region_id.begin, region_id.core); + let mut workplan = Workplan::::get(&workplan_key) + .unwrap_or_default(); + if workplan.try_push(ScheduleItem { + part: region_id.part, + assignment: CoreAssignment::Pool, + }).is_ok() { + Workplan::::insert(&workplan_key, &workplan); + let size = region_id.part.count_ones() as i32; + InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); + InstaPoolIo::::mutate(region.end, |a| a.total.saturating_reduce(size)); + let record = ContributionRecord { + length: region.end.saturating_sub(region_id.begin), + payee, + }; + InstaPoolContribution::::insert(®ion_id, record); + } + Self::deposit_event(Event::Pooled { region_id }); + } + Ok(()) + } + + // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. + pub(crate) fn do_claim_revenue(mut region: RegionId, max_timeslices: Timeslice) -> DispatchResult { + let mut contribution = InstaPoolContribution::::take(region) + .ok_or(Error::::UnknownContribution)?; + let contributed_parts = region.part.count_ones(); + + let mut payout = BalanceOf::::zero(); + let last = region.begin + contribution.length.min(max_timeslices); + for r in region.begin..last { + let mut pool_record = match InstaPoolHistory::::get(r) { Some(x) => x, None => continue }; + let total_payout = match pool_record.maybe_payout { Some(x) => x, None => break }; + region.begin = r; + contribution.length.saturating_dec(); + payout.saturating_accrue(total_payout.saturating_mul(contributed_parts.into()) + / pool_record.total_contributions.into()); + pool_record.total_contributions.saturating_reduce(contributed_parts); + + let remaining_payout = total_payout.saturating_sub(payout); + if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { + pool_record.maybe_payout = Some(remaining_payout); + InstaPoolHistory::::insert(region.begin, &pool_record); + } else { + InstaPoolHistory::::remove(region.begin); + } + }; + + if contribution.length > 0 { + InstaPoolContribution::::insert(region, &contribution); + } + T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable).defensive_ok(); + Ok(()) + } + + pub(crate) fn do_purchase_credit( + who: T::AccountId, + amount: BalanceOf, + beneficiary: RelayAccountIdOf, + ) -> DispatchResult { + T::Currency::transfer(&who, &Self::account_id(), amount, Expendable)?; + let amount = T::ConvertBalance::convert(amount); + T::Coretime::credit_account(beneficiary, amount); + Ok(()) + } +} \ No newline at end of file diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 87e77874c3449..dc409617b1427 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -11,11 +11,6 @@ use frame_support::{ use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; impl Pallet { - pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { - Configuration::::put(config); - Ok(()) - } - /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is /// less than `Self::current_timeslice`. pub(crate) fn do_tick() -> DispatchResult { @@ -35,41 +30,13 @@ impl Pallet { Self::rotate_sale(sale, &config); } } - Self::process_timeslice(commit_timeslice, &mut status, &config); + Self::process_revenue()?; Status::::put(&status); Ok(()) } - pub(crate) fn do_start_sales( - reserve_price: BalanceOf, - ) -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let status = StatusRecord { - pool_size: 0, - last_timeslice: Self::current_timeslice(), - system_pool_size: 0, - }; - let commit_timeslice = status.last_timeslice + config.advance_notice; - let now = frame_system::Pallet::::block_number(); - let dummy_sale = SaleInfoRecord { - sale_start: now, - leadin_length: Zero::zero(), - start_price: Zero::zero(), - reserve_price, - region_begin: commit_timeslice, - region_end: commit_timeslice + config.region_length, - first_core: 0, - ideal_cores_sold: 0, - cores_offered: 0, - cores_sold: 0, - }; - Self::rotate_sale(dummy_sale, &config); - Status::::put(&status); - Ok(()) - } - fn bump_price( offered: CoreIndex, ideal: CoreIndex, @@ -207,7 +174,7 @@ impl Pallet { T::PalletId::get().into_account_truncating() } - pub(crate) fn do_check_revenue() -> Result { + fn process_revenue() -> Result { if let Some((until, amount)) = T::Coretime::check_notify_revenue_info() { let timeslice: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); let mut amount = T::ConvertBalance::convert_back(amount); @@ -239,58 +206,7 @@ impl Pallet { Ok(false) } - pub(crate) fn do_purchase_credit( - who: T::AccountId, - amount: BalanceOf, - beneficiary: RelayAccountIdOf, - ) -> DispatchResult { - T::Currency::transfer(&who, &Self::account_id(), amount, Expendable)?; - let amount = T::ConvertBalance::convert(amount); - T::Coretime::credit_account(beneficiary, amount); - Ok(()) - } - - // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. - pub(crate) fn do_claim_revenue(mut region: RegionId, max_timeslices: Timeslice) -> DispatchResult { - let mut contribution = InstaPoolContribution::::take(region) - .ok_or(Error::::UnknownContribution)?; - let contributed_parts = region.part.count_ones(); - - let mut payout = BalanceOf::::zero(); - let last = region.begin + contribution.length.min(max_timeslices); - for r in region.begin..last { - let mut pool_record = match InstaPoolHistory::::get(r) { Some(x) => x, None => continue }; - let total_payout = match pool_record.maybe_payout { Some(x) => x, None => break }; - region.begin = r; - contribution.length.saturating_dec(); - payout.saturating_accrue(total_payout.saturating_mul(contributed_parts.into()) - / pool_record.total_contributions.into()); - pool_record.total_contributions.saturating_reduce(contributed_parts); - - let remaining_payout = total_payout.saturating_sub(payout); - if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { - pool_record.maybe_payout = Some(remaining_payout); - InstaPoolHistory::::insert(region.begin, &pool_record); - } else { - InstaPoolHistory::::remove(region.begin); - } - }; - - if contribution.length > 0 { - InstaPoolContribution::::insert(region, &contribution); - } - T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable).defensive_ok(); - Ok(()) - } - - pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { - let mut r = Reservations::::get(); - r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; - Reservations::::put(r); - Ok(()) - } - - pub(crate) fn current_timeslice() -> Timeslice { + pub fn current_timeslice() -> Timeslice { let latest = T::Coretime::latest(); let timeslice_period = T::TimeslicePeriod::get(); (latest / timeslice_period).saturated_into() @@ -356,78 +272,11 @@ impl Pallet { T::Coretime::assign_core(core, rc_begin, assignment, None); } - fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { T::OnRevenue::on_unbalanced(T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?); Ok(()) } - /// Must be called on a core in `AllowedRenewals` whose value is a timeslice equal to the - /// current sale status's `region_end`. - pub(crate) fn do_renew(who: &T::AccountId, core: CoreIndex) -> Result { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; - let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; - - ensure!(record.begin == sale.region_begin, Error::::WrongTime); - ensure!(sale.first_core < config.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); - - Self::charge(who, record.price)?; - Self::deposit_event(Event::Renewed { - who: who.clone(), - core, - price: record.price, - begin: sale.region_begin, - length: sale.region_end.saturating_sub(sale.region_begin), - workload: workload.clone(), - }); - - let core = sale.first_core + sale.cores_sold; - sale.cores_sold.saturating_inc(); - - Workplan::::insert((record.begin, core), &workload); - - let begin = sale.region_end; - let price = record.price + config.renewal_bump * record.price; - let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; - AllowedRenewals::::insert(core, &new_record); - SaleInfo::::put(&sale); - if let Some(workload) = new_record.completion.drain_complete() { - Self::deposit_event(Event::Renewable { core, price, begin, workload }); - } - Ok(core) - } - - pub(crate) fn do_purchase( - who: T::AccountId, - price_limit: BalanceOf, - ) -> Result { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < config.core_count, Error::::Unavailable); - ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); - let now = frame_system::Pallet::::block_number(); - ensure!(now > sale.sale_start, Error::::TooEarly); - let price = lerp( - now, - sale.sale_start, - sale.leadin_length, - sale.start_price, - sale.reserve_price, - ).ok_or(Error::::IndeterminablePrice)?; - ensure!(price_limit >= price, Error::::Overpriced); - - Self::charge(&who, price)?; - let core = sale.first_core + sale.cores_sold; - sale.cores_sold.saturating_inc(); - SaleInfo::::put(&sale); - let id = Self::issue(core, sale.region_begin, sale.region_end, who.clone(), Some(price)); - let length = sale.region_end.saturating_sub(sale.region_begin); - Self::deposit_event(Event::Purchased { who, region_id: id, price, length }); - Ok(id) - } - pub(crate) fn issue( core: CoreIndex, begin: Timeslice, @@ -441,75 +290,6 @@ impl Pallet { id } - pub(crate) fn do_transfer( - region_id: RegionId, - maybe_check_owner: Option, - new_owner: T::AccountId, - ) -> Result<(), Error> { - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - let old_owner = region.owner; - region.owner = new_owner; - Regions::::insert(®ion_id, ®ion); - Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); - - Ok(()) - } - - pub(crate) fn do_partition( - region_id: RegionId, - maybe_check_owner: Option, - pivot_offset: Timeslice, - ) -> Result<(RegionId, RegionId), Error> { - let mut region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - let pivot = region_id.begin.saturating_add(pivot_offset); - ensure!(pivot < region.end, Error::::PivotTooLate); - - region.paid = None; - let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; - let new_region = RegionRecord { end: pivot, ..region.clone() }; - - Regions::::insert(®ion_id, &new_region); - Regions::::insert(&new_region_id, ®ion); - Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); - - Ok((region_id, new_region_id)) - } - - pub(crate) fn do_interlace( - mut region_id: RegionId, - maybe_check_owner: Option, - pivot: CorePart, - ) -> Result<(RegionId, RegionId), Error> { - let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); - ensure!(!pivot.is_void(), Error::::NullPivot); - ensure!(pivot != region_id.part, Error::::CompletePivot); - - let antipivot = region_id.part ^ pivot; - region_id.part = pivot; - Regions::::insert(®ion_id, ®ion); - let new_region_id = RegionId { part: antipivot, ..region_id }; - Regions::::insert(&new_region_id, ®ion); - - Self::deposit_event(Event::Interlaced { region_id, pivot, new_region_id }); - - Ok((region_id, new_region_id)) - } - pub(crate) fn utilize( mut region_id: RegionId, maybe_check_owner: Option, @@ -535,74 +315,4 @@ impl Pallet { Ok(None) } } - - pub(crate) fn do_assign( - region_id: RegionId, - maybe_check_owner: Option, - target: TaskId, - ) -> Result<(), Error> { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { - let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Task(target), - }).is_ok() { - Workplan::::insert(&workplan_key, &workplan); - } - - if region.end.saturating_sub(region_id.begin) == config.region_length { - if let Some(price) = region.paid { - let begin = region.end; - let assigned = match AllowedRenewals::::get(region_id.core) { - Some(AllowedRenewalRecord { completion: Partial(w), begin: b, price: p }) - if begin == b && price == p => w, - _ => CorePart::void(), - } | region_id.part; - let workload = if assigned.is_complete() { - Complete(workplan) - } else { - Partial(assigned) - }; - let record = AllowedRenewalRecord { begin, price, completion: workload }; - AllowedRenewals::::insert(region_id.core, &record); - if let Some(workload) = record.completion.drain_complete() { - Self::deposit_event(Event::Renewable { core: region_id.core, price, begin, workload }); - } - } - } - Self::deposit_event(Event::Assigned { region_id, task: target }); - } - Ok(()) - } - - pub(crate) fn do_pool( - region_id: RegionId, - maybe_check_owner: Option, - payee: T::AccountId, - ) -> Result<(), Error> { - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { - let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Pool, - }).is_ok() { - Workplan::::insert(&workplan_key, &workplan); - let size = region_id.part.count_ones() as i32; - InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); - InstaPoolIo::::mutate(region.end, |a| a.total.saturating_reduce(size)); - let record = ContributionRecord { - length: region.end.saturating_sub(region_id.begin), - payee, - }; - InstaPoolContribution::::insert(®ion_id, record); - } - Self::deposit_event(Event::Pooled { region_id }); - } - Ok(()) - } } \ No newline at end of file diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 149ae1e27c6be..73e4c085e134d 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -29,6 +29,7 @@ mod types; mod coretime_interface; mod utils; mod implementation; +mod dispatchable_impls; mod nonfungible_impl; pub mod weights; @@ -45,7 +46,7 @@ pub mod pallet { use super::*; use frame_support::{ pallet_prelude::{*, DispatchResult}, - traits::{fungible::{Credit, Mutate, Balanced}, OnUnbalanced}, + traits::{fungible::{Credit, Mutate, Balanced}, OnUnbalanced, EnsureOrigin}, PalletId, }; use frame_system::pallet_prelude::*; @@ -64,6 +65,9 @@ pub mod pallet { /// Currency used to pay for Coretime. type Currency: Mutate + Balanced; + /// The origin test needed for administrating this pallet. + type AdminOrigin: EnsureOrigin; + /// What to do with any revenues collected from the sale of Coretime. type OnRevenue: OnUnbalanced>; @@ -76,6 +80,7 @@ pub mod pallet { type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; /// Identifier from which the internal Pot is generated. + #[pallet::constant] type PalletId: Get; /// Number of Relay-chain blocks per timeslice. @@ -210,6 +215,7 @@ pub mod pallet { TooEarly, NothingToDo, TooManyReservations, + TooManyLeases, RevenueAlreadyKnown, NoRevenue, UnknownRevenue, @@ -229,10 +235,130 @@ pub mod pallet { #[pallet::call(weight(::WeightInfo))] impl Pallet { #[pallet::call_index(0)] - pub fn transfer(origin: OriginFor, region_id: RegionId, new_owner: T::AccountId) -> DispatchResult { + pub fn configure(origin: OriginFor, config: ConfigRecordOf) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_configure(config)?; + Ok(()) + } + + #[pallet::call_index(1)] + pub fn reserve(origin: OriginFor, schedule: Schedule) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_reserve(schedule)?; + Ok(()) + } + + #[pallet::call_index(2)] + pub fn unreserve(origin: OriginFor, item_index: u32) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_unreserve(item_index)?; + Ok(()) + } + + #[pallet::call_index(3)] + pub fn set_lease(origin: OriginFor, task: TaskId, until: Timeslice) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_set_lease(task, until)?; + Ok(()) + } + + #[pallet::call_index(4)] + pub fn start_sales(origin: OriginFor, initial_price: BalanceOf) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_start_sales(initial_price)?; + Ok(()) + } + + #[pallet::call_index(5)] + pub fn purchase(origin: OriginFor, price_limit: BalanceOf) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_purchase(who, price_limit)?; + Ok(()) + } + + #[pallet::call_index(6)] + pub fn renew(origin: OriginFor, core: CoreIndex) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_renew(who, core)?; + Ok(()) + } + + #[pallet::call_index(7)] + pub fn transfer( + origin: OriginFor, + region_id: RegionId, + new_owner: T::AccountId, + ) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_transfer(region_id, Some(who), new_owner)?; Ok(()) } + + #[pallet::call_index(8)] + pub fn partition( + origin: OriginFor, + region_id: RegionId, + pivot: Timeslice, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_partition(region_id, Some(who), pivot)?; + Ok(()) + } + + #[pallet::call_index(9)] + pub fn interlace( + origin: OriginFor, + region_id: RegionId, + pivot: CorePart, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_interlace(region_id, Some(who), pivot)?; + Ok(()) + } + + #[pallet::call_index(10)] + pub fn assign( + origin: OriginFor, + region_id: RegionId, + target: TaskId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_assign(region_id, Some(who), target)?; + Ok(()) + } + + #[pallet::call_index(11)] + pub fn pool( + origin: OriginFor, + region_id: RegionId, + payee: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_pool(region_id, Some(who), payee)?; + Ok(()) + } + + #[pallet::call_index(12)] + pub fn claim_revenue( + origin: OriginFor, + region_id: RegionId, + max_timeslices: Timeslice, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_claim_revenue(region_id, max_timeslices)?; + Ok(()) + } + + #[pallet::call_index(13)] + pub fn purchase_credit( + origin: OriginFor, + who: T::AccountId, + amount: BalanceOf, + beneficiary: RelayAccountIdOf, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + Self::do_purchase_credit(who, amount, beneficiary)?; + Ok(()) + } } } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 453c850e5da1b..b2f909da89fe1 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -18,6 +18,7 @@ #![cfg(test)] use crate::*; +use frame_system::EnsureNever; use sp_std::collections::btree_map::BTreeMap; use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate, Inspect, Credit, Balanced}, OnUnbalanced}, assert_ok, PalletId, ensure}; use sp_arithmetic::Perbill; @@ -184,6 +185,7 @@ impl crate::Config for Test { type ConvertBalance = Identity; type WeightInfo = (); type PalletId = TestBrokerId; + type AdminOrigin = EnsureNever<()>; } pub fn advance_to(b: u64) { diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index ffffe9697adf0..4075f1fbf1fe8 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -55,12 +55,12 @@ fn renewal_works() { // Should now be renewable. advance_to(6); assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::TooEarly); - let core = Broker::do_renew(&1, region.core).unwrap(); + let core = Broker::do_renew(1, region.core).unwrap(); assert_eq!(balance(1), 800); advance_to(8); assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::SoldOut); advance_to(12); - let region = Broker::do_renew(&1, core).unwrap(); + let region = Broker::do_renew(1, core).unwrap(); assert_eq!(balance(1), 690); }); } @@ -80,7 +80,7 @@ fn instapool_payouts_work() { advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); advance_to(10); - while Broker::do_check_revenue().unwrap() {} +// while Broker::check_revenue().unwrap() {} assert_eq!(pot(), 14); assert_eq!(revenue(), 106); assert_ok!(Broker::do_claim_revenue(region, 100)); @@ -106,7 +106,7 @@ fn instapool_partial_core_payouts_work() { advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); advance_to(10); - while Broker::do_check_revenue().unwrap() {} +// while Broker::check_revenue().unwrap() {} assert_ok!(Broker::do_claim_revenue(region1, 100)); assert_ok!(Broker::do_claim_revenue(region2, 100)); assert_eq!(pot(), 0); diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index ed6f964377ce0..70abe6ae37156 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -26,20 +26,55 @@ use core::marker::PhantomData; /// Weight functions needed for `pallet-broker`. pub trait WeightInfo { + fn configure() -> Weight; + fn reserve() -> Weight; + fn unreserve() -> Weight; + fn set_lease() -> Weight; + fn start_sales() -> Weight; + fn purchase() -> Weight; + fn renew() -> Weight; fn transfer() -> Weight; + fn partition() -> Weight; + fn interlace() -> Weight; + fn assign() -> Weight; + fn pool() -> Weight; + fn claim_revenue() -> Weight; + fn purchase_credit() -> Weight; } /// Weights for `pallet-broker` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn transfer() -> Weight { - Weight::from_parts(123, 456) - } + fn configure() -> Weight { Weight::from_parts(123, 456) } + fn reserve() -> Weight { Weight::from_parts(123, 456) } + fn unreserve() -> Weight { Weight::from_parts(123, 456) } + fn set_lease() -> Weight { Weight::from_parts(123, 456) } + fn start_sales() -> Weight { Weight::from_parts(123, 456) } + fn purchase() -> Weight { Weight::from_parts(123, 456) } + fn renew() -> Weight { Weight::from_parts(123, 456) } + fn transfer() -> Weight { Weight::from_parts(123, 456) } + fn partition() -> Weight { Weight::from_parts(123, 456) } + fn interlace() -> Weight { Weight::from_parts(123, 456) } + fn assign() -> Weight { Weight::from_parts(123, 456) } + fn pool() -> Weight { Weight::from_parts(123, 456) } + fn claim_revenue() -> Weight { Weight::from_parts(123, 456) } + fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } } // For backwards compatibility and tests impl WeightInfo for () { - fn transfer() -> Weight { - Weight::from_parts(123, 456) - } + fn configure() -> Weight { Weight::from_parts(123, 456) } + fn reserve() -> Weight { Weight::from_parts(123, 456) } + fn unreserve() -> Weight { Weight::from_parts(123, 456) } + fn set_lease() -> Weight { Weight::from_parts(123, 456) } + fn start_sales() -> Weight { Weight::from_parts(123, 456) } + fn purchase() -> Weight { Weight::from_parts(123, 456) } + fn renew() -> Weight { Weight::from_parts(123, 456) } + fn transfer() -> Weight { Weight::from_parts(123, 456) } + fn partition() -> Weight { Weight::from_parts(123, 456) } + fn interlace() -> Weight { Weight::from_parts(123, 456) } + fn assign() -> Weight { Weight::from_parts(123, 456) } + fn pool() -> Weight { Weight::from_parts(123, 456) } + fn claim_revenue() -> Weight { Weight::from_parts(123, 456) } + fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } } diff --git a/frame/core-fellowship/src/lib.rs b/frame/core-fellowship/src/lib.rs index ba02627ec11b9..938dcff66c13e 100644 --- a/frame/core-fellowship/src/lib.rs +++ b/frame/core-fellowship/src/lib.rs @@ -328,7 +328,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::set_params())] #[pallet::call_index(1)] pub fn set_params(origin: OriginFor, params: Box>) -> DispatchResult { - T::ParamsOrigin::try_origin(origin).map(|_| ()).or_else(|o| ensure_root(o))?; + T::ParamsOrigin::try_origin_or_root(origin)?; Params::::put(params.as_ref()); Self::deposit_event(Event::::ParamsChanged { params: *params }); Ok(()) diff --git a/frame/glutton/src/lib.rs b/frame/glutton/src/lib.rs index c02a14810d0b2..e3a1685d54f65 100644 --- a/frame/glutton/src/lib.rs +++ b/frame/glutton/src/lib.rs @@ -211,7 +211,7 @@ pub mod pallet { new_count: u32, witness_count: Option, ) -> DispatchResult { - T::AdminOrigin::try_origin(origin).map(|_| ()).or_else(|o| ensure_root(o))?; + T::AdminOrigin::try_origin_or_root(origin)?; let current_count = TrashDataCount::::get(); ensure!( @@ -236,7 +236,7 @@ pub mod pallet { /// Only callable by Root or `AdminOrigin`. #[pallet::call_index(1)] pub fn set_compute(origin: OriginFor, compute: FixedU64) -> DispatchResult { - T::AdminOrigin::try_origin(origin).map(|_| ()).or_else(|o| ensure_root(o))?; + T::AdminOrigin::try_origin_or_root(origin)?; ensure!(compute <= RESOURCE_HARD_LIMIT, Error::::InsaneLimit); Compute::::set(compute); @@ -254,7 +254,7 @@ pub mod pallet { /// Only callable by Root or `AdminOrigin`. #[pallet::call_index(2)] pub fn set_storage(origin: OriginFor, storage: FixedU64) -> DispatchResult { - T::AdminOrigin::try_origin(origin).map(|_| ()).or_else(|o| ensure_root(o))?; + T::AdminOrigin::try_origin_or_root(origin)?; ensure!(storage <= RESOURCE_HARD_LIMIT, Error::::InsaneLimit); Storage::::set(storage); diff --git a/frame/support/src/traits/dispatch.rs b/frame/support/src/traits/dispatch.rs index 9ea58479a0dfe..53d66cd056463 100644 --- a/frame/support/src/traits/dispatch.rs +++ b/frame/support/src/traits/dispatch.rs @@ -37,9 +37,33 @@ pub trait EnsureOrigin { Self::try_origin(o).map_err(|_| BadOrigin) } + /// The same as `ensure_origin` except that Root origin will always pass. This can only be + /// used if `Success` has a sensible impl of `Default` since that will be used in the result. + fn ensure_origin_or_root(o: OuterOrigin) -> Result, BadOrigin> where + OuterOrigin: OriginTrait, + { + if o.caller().is_root() { + return Ok(None) + } else { + Self::ensure_origin(o).map(Some) + } + } + /// Perform the origin check. fn try_origin(o: OuterOrigin) -> Result; + /// The same as `try_origin` except that Root origin will always pass. This can only be + /// used if `Success` has a sensible impl of `Default` since that will be used in the result. + fn try_origin_or_root(o: OuterOrigin) -> Result, OuterOrigin> where + OuterOrigin: OriginTrait, + { + if o.caller().is_root() { + return Ok(None) + } else { + Self::try_origin(o).map(Some) + } + } + /// Attempt to get an outer origin capable of passing `try_origin` check. May return `Err` if it /// is impossible. /// From 2f20e0a4f4cc7ff7d830578ee8a4a076bbc418bc Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 11 Jul 2023 16:55:51 +0200 Subject: [PATCH 027/131] Better weight --- frame/broker/src/dispatchable_impls.rs | 3 ++- frame/broker/src/implementation.rs | 14 ++++++++++---- frame/broker/src/lib.rs | 1 + frame/broker/src/tests.rs | 21 +++++++++++++++++++-- frame/broker/src/types.rs | 10 +++++++++- frame/broker/src/weights.rs | 6 +++--- 6 files changed, 44 insertions(+), 11 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 33ba72f914c0f..1af61119425ac 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -32,7 +32,8 @@ impl Pallet { pub(crate) fn do_set_lease(task: TaskId, until: Timeslice) -> DispatchResult { let mut r = Leases::::get(); - r.try_push((until, task)).map_err(|_| Error::::TooManyLeases)?; + r.try_push(LeaseRecordItem { until, task }) + .map_err(|_| Error::::TooManyLeases)?; Leases::::put(r); Ok(()) } diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index dc409617b1427..7cdc5d79c3ddc 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -129,12 +129,12 @@ impl Pallet { let mut leases = Leases::::get(); // can morph to a renewable as long as it's > begin and < end. - leases.retain(|&(until, para)| { + leases.retain(|&LeaseRecordItem { until, task }| { let part = CorePart::complete(); - let assignment = CoreAssignment::Task(para); + let assignment = CoreAssignment::Task(task); let schedule = BoundedVec::truncate_from(vec![ScheduleItem { part, assignment }]); Workplan::::insert((region_begin, first_core), &schedule); - let expiring = until >= region_begin; + let expiring = until >= region_begin && until < region_end; if expiring { // last time for this one - make it renewable. let record = AllowedRenewalRecord { @@ -142,7 +142,13 @@ impl Pallet { price: reserve_price, completion: Complete(schedule), }; - AllowedRenewals::::insert(first_core, record); + AllowedRenewals::::insert(first_core, &record); + Self::deposit_event(Event::Renewable { + core: first_core, + price: reserve_price, + begin: region_end, + workload: record.completion.drain_complete().unwrap_or_default(), + }); } first_core.saturating_inc(); !expiring diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 73e4c085e134d..95a62523b68f0 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -339,6 +339,7 @@ pub mod pallet { } #[pallet::call_index(12)] + #[pallet::weight(T::WeightInfo::claim_revenue(*max_timeslices))] pub fn claim_revenue( origin: OriginFor, region_id: RegionId, diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 4075f1fbf1fe8..d44e23eeaf198 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -80,7 +80,6 @@ fn instapool_payouts_work() { advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); advance_to(10); -// while Broker::check_revenue().unwrap() {} assert_eq!(pot(), 14); assert_eq!(revenue(), 106); assert_ok!(Broker::do_claim_revenue(region, 100)); @@ -106,7 +105,6 @@ fn instapool_partial_core_payouts_work() { advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); advance_to(10); -// while Broker::check_revenue().unwrap() {} assert_ok!(Broker::do_claim_revenue(region1, 100)); assert_ok!(Broker::do_claim_revenue(region2, 100)); assert_eq!(pot(), 0); @@ -142,6 +140,25 @@ fn initialize_with_system_paras_works() { }); } +#[test] +fn initialize_with_leased_slots_works() { + TestExt::new().core_count(2).execute_with(|| { + assert_ok!(Broker::do_set_lease(1000, 6)); + assert_ok!(Broker::do_set_lease(1001, 7)); + assert_ok!(Broker::do_start_sales(100)); + advance_to(18); + let end_hint = None; + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ (Task(1000), 57600), ], end_hint }), + (6, AssignCore { core: 1, begin: 8, assignment: vec![ (Task(1001), 57600), ], end_hint }), + (12, AssignCore { core: 0, begin: 14, assignment: vec![ (Task(1001), 57600), ], end_hint }), + (12, AssignCore { core: 1, begin: 14, assignment: vec![ (Pool, 57600), ], end_hint }), + (18, AssignCore { core: 0, begin: 20, assignment: vec![ (Pool, 57600), ], end_hint }), + (18, AssignCore { core: 1, begin: 20, assignment: vec![ (Pool, 57600), ], end_hint }), + ]); + }); +} + #[test] fn purchase_works() { TestExt::new().endow(1, 1000).execute_with(|| { diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index f9ac0072aa327..9d48c29145cbd 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -201,8 +201,16 @@ pub type SaleInfoRecordOf = SaleInfoRecord< /// Chains). pub type ReservationsRecord = BoundedVec; pub type ReservationsRecordOf = ReservationsRecord<::MaxReservedCores>; + +/// Information on a single legacy lease. +#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct LeaseRecordItem { + pub until: Timeslice, + pub task: TaskId, +} + /// Record for Polkadot Core legacy leases. -pub type LeasesRecord = BoundedVec<(Timeslice, TaskId), Max>; +pub type LeasesRecord = BoundedVec; pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; /// Configuration of this pallet. diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index 70abe6ae37156..f3e121c3758a8 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -38,7 +38,7 @@ pub trait WeightInfo { fn interlace() -> Weight; fn assign() -> Weight; fn pool() -> Weight; - fn claim_revenue() -> Weight; + fn claim_revenue(m: u32,) -> Weight; fn purchase_credit() -> Weight; } @@ -57,7 +57,7 @@ impl WeightInfo for SubstrateWeight { fn interlace() -> Weight { Weight::from_parts(123, 456) } fn assign() -> Weight { Weight::from_parts(123, 456) } fn pool() -> Weight { Weight::from_parts(123, 456) } - fn claim_revenue() -> Weight { Weight::from_parts(123, 456) } + fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } } @@ -75,6 +75,6 @@ impl WeightInfo for () { fn interlace() -> Weight { Weight::from_parts(123, 456) } fn assign() -> Weight { Weight::from_parts(123, 456) } fn pool() -> Weight { Weight::from_parts(123, 456) } - fn claim_revenue() -> Weight { Weight::from_parts(123, 456) } + fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } } From 3638f55795c96382730edcc79915e2053b30cc65 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 12 Jul 2023 11:15:43 +0200 Subject: [PATCH 028/131] Test migration --- frame/broker/README.md | 26 ++------- frame/broker/src/dispatchable_impls.rs | 26 ++++----- frame/broker/src/implementation.rs | 43 +++++---------- frame/broker/src/lib.rs | 12 +++-- frame/broker/src/mock.rs | 8 ++- frame/broker/src/nonfungible_impl.rs | 1 - frame/broker/src/tests.rs | 67 +++++++++++++++++++++--- frame/broker/src/types.rs | 2 + primitives/arithmetic/src/fixed_point.rs | 23 ++++---- primitives/arithmetic/src/traits.rs | 2 + 10 files changed, 122 insertions(+), 88 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index 4a554967b302c..50cb256c40db6 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -4,9 +4,9 @@ Brokerage tool for managing Polkadot Core scheduling. Properly described in RFC-0001 Agile Coretime. -# Implemnentation Specifics +## Implemnentation Specifics -## The Sale +### The Sale ``` 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 @@ -20,31 +20,11 @@ Properly described in RFC-0001 Agile Coretime. price fixed, unsold assigned to instapool, system cores reserved -/ ``` -# Examples +## TODO -```rust -use pallet_broker::Pallet as Broker; - -fn main() { - -} -``` - -# TODO - -- Dispatchables - Nicer API for price finding; should include auction-sell-out info - Benchmarks - Weights - Final docs - Tests - -# License - -Apache-2.0 - -# References -This crate was auto generated by FRAMY CLI . -Please report bugs and build failures at . - diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 1af61119425ac..007e14e9f06c7 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -1,14 +1,14 @@ use super::*; use CompletionStatus::{Complete, Partial}; -use sp_runtime::traits::{Convert, ConvertBack, AccountIdConversion}; +use sp_runtime::traits::Convert; use frame_support::{ pallet_prelude::{*, DispatchResult}, traits::{ - tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, - fungible::{Mutate, Balanced}, OnUnbalanced, DefensiveResult, + tokens::Preservation::Expendable, + fungible::Mutate, DefensiveResult, } }; -use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; +use sp_arithmetic::traits::{Zero, Saturating}; impl Pallet { pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { @@ -33,7 +33,7 @@ impl Pallet { pub(crate) fn do_set_lease(task: TaskId, until: Timeslice) -> DispatchResult { let mut r = Leases::::get(); r.try_push(LeaseRecordItem { until, task }) - .map_err(|_| Error::::TooManyLeases)?; + .map_err(|_| Error::::TooManyLeases)?; Leases::::put(r); Ok(()) } @@ -54,6 +54,7 @@ impl Pallet { leadin_length: Zero::zero(), start_price: Zero::zero(), reserve_price, + sellout_price: None, region_begin: commit_timeslice, region_end: commit_timeslice + config.region_length, first_core: 0, @@ -76,18 +77,15 @@ impl Pallet { ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let now = frame_system::Pallet::::block_number(); ensure!(now > sale.sale_start, Error::::TooEarly); - let price = lerp( - now, - sale.sale_start, - sale.leadin_length, - sale.start_price, - sale.reserve_price, - ).ok_or(Error::::IndeterminablePrice)?; + let price = Self::sale_price(&sale, now); ensure!(price_limit >= price, Error::::Overpriced); Self::charge(&who, price)?; let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); + if sale.cores_sold >= sale.ideal_cores_sold && sale.sellout_price.is_none() { + sale.sellout_price = Some(price); + } SaleInfo::::put(&sale); let id = Self::issue(core, sale.region_begin, sale.region_end, who.clone(), Some(price)); let length = sale.region_end.saturating_sub(sale.region_begin); @@ -126,6 +124,10 @@ impl Pallet { let price = record.price + config.renewal_bump * record.price; let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; AllowedRenewals::::insert(core, &new_record); + if sale.cores_sold >= sale.ideal_cores_sold && sale.sellout_price.is_none() { + let price = Self::sale_price(&sale, frame_system::Pallet::::block_number()); + sale.sellout_price = Some(price); + } SaleInfo::::put(&sale); if let Some(workload) = new_record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core, price, begin, workload }); diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 7cdc5d79c3ddc..3492d7f03f8df 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -1,14 +1,14 @@ use super::*; -use CompletionStatus::{Complete, Partial}; -use sp_runtime::traits::{Convert, ConvertBack, AccountIdConversion}; +use CompletionStatus::Complete; +use sp_runtime::traits::{ConvertBack, AccountIdConversion}; use frame_support::{ pallet_prelude::{*, DispatchResult}, traits::{ tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, - fungible::{Mutate, Balanced}, OnUnbalanced, DefensiveResult, + fungible::Balanced, OnUnbalanced, } }; -use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, Perbill, PerThing}; +use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, FixedPointNumber}; impl Pallet { /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is @@ -37,29 +37,6 @@ impl Pallet { Ok(()) } - fn bump_price( - offered: CoreIndex, - ideal: CoreIndex, - sold: CoreIndex, - old: BalanceOf, - ) -> BalanceOf { - if sold > ideal { - let extra = if offered > ideal { - Perbill::from_rational((sold - ideal) as u32, (offered - ideal) as u32) - } else { - Perbill::zero() - }; - old + extra * old - } else { - let extra = if ideal > 0 { - Perbill::from_rational(sold as u32, ideal as u32).left_from_one() - } else { - Perbill::zero() - }; - old - extra * old - } - } - /// Begin selling for the next sale period. /// /// Triggered by Relay-chain block number/timeslice. @@ -93,9 +70,9 @@ impl Pallet { let offered = old_sale.cores_offered; let ideal = old_sale.ideal_cores_sold; let sold = old_sale.cores_sold; - let old_price = old_sale.reserve_price; - if offered > 0 { - Self::bump_price(offered, ideal, sold, old_price) + let old_price = old_sale.sellout_price.unwrap_or(old_sale.reserve_price); + if sold <= offered && offered > 0 { + T::PriceAdapter::adapt_price(sold, ideal, offered).saturating_mul_int(old_price) } else { old_price } @@ -164,6 +141,7 @@ impl Pallet { leadin_length: config.leadin_length, start_price, reserve_price, + sellout_price: None, region_begin, region_end, first_core, @@ -212,6 +190,11 @@ impl Pallet { Ok(false) } + pub fn sale_price(sale: &SaleInfoRecordOf, now: T::BlockNumber) -> BalanceOf { + lerp(now, sale.sale_start, sale.leadin_length, sale.start_price, sale.reserve_price) + .unwrap_or(sale.start_price) + } + pub fn current_timeslice() -> Timeslice { let latest = T::Coretime::latest(); let timeslice_period = T::TimeslicePeriod::get(); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 95a62523b68f0..141e350e99abe 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -31,15 +31,17 @@ mod utils; mod implementation; mod dispatchable_impls; mod nonfungible_impl; +mod adapt_price; pub mod weights; pub use weights::WeightInfo; -pub use types::*; +pub use adapt_price::*; pub use core_part::*; pub use coretime_interface::*; -pub use utils::*; pub use nonfungible_impl::*; +pub use types::*; +pub use utils::*; #[frame_support::pallet] pub mod pallet { @@ -75,6 +77,9 @@ pub mod pallet { /// system. type Coretime: CoretimeInterface; + /// The algorithm to determine the next price on the basis of market performance. + type PriceAdapter: AdaptPrice; + /// Reversible conversion from local balance to Relay-chain balance. This will typically be /// the `Identity`, but provided just in case the chains use different representations. type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; @@ -345,7 +350,7 @@ pub mod pallet { region_id: RegionId, max_timeslices: Timeslice, ) -> DispatchResult { - let who = ensure_signed(origin)?; + let _ = ensure_signed(origin)?; Self::do_claim_revenue(region_id, max_timeslices)?; Ok(()) } @@ -353,7 +358,6 @@ pub mod pallet { #[pallet::call_index(13)] pub fn purchase_credit( origin: OriginFor, - who: T::AccountId, amount: BalanceOf, beneficiary: RelayAccountIdOf, ) -> DispatchResult { diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index b2f909da89fe1..9d2912c6f660d 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -20,7 +20,7 @@ use crate::*; use frame_system::EnsureNever; use sp_std::collections::btree_map::BTreeMap; -use frame_support::{parameter_types, traits::{Hooks, fungible::{ItemOf, Mutate, Inspect, Credit, Balanced}, OnUnbalanced}, assert_ok, PalletId, ensure}; +use frame_support::{parameter_types, traits::{Hooks, nonfungible::{Inspect as NftInspect}, fungible::{ItemOf, Mutate, Inspect, Credit, Balanced}, OnUnbalanced}, assert_ok, PalletId, ensure}; use sp_arithmetic::Perbill; use sp_core::{H256, ConstU64, ConstU16, ConstU32}; use sp_runtime::{ @@ -186,6 +186,7 @@ impl crate::Config for Test { type WeightInfo = (); type PalletId = TestBrokerId; type AdminOrigin = EnsureNever<()>; + type PriceAdapter = Linear; } pub fn advance_to(b: u64) { @@ -208,7 +209,12 @@ pub fn balance(who: u64) -> u64 { <::Currency as Inspect<_>>::total_balance(&who) } +pub fn attribute(nft: RegionId, attribute: impl codec::Encode) -> T { + >::typed_attribute::<_, T>(&nft.into(), &attribute).unwrap() +} + pub struct TestExt(ConfigRecordOf); +#[allow(dead_code)] impl TestExt { pub fn new() -> Self { Self(ConfigRecord { diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index 450dd987fe324..a41d3e3443320 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -1,5 +1,4 @@ use super::*; -use sp_runtime::TokenError; use frame_support::{ pallet_prelude::{*, DispatchResult}, traits::{ diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index d44e23eeaf198..dd20355d607fa 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -18,7 +18,7 @@ #![cfg(test)] use crate::{*, mock::*, core_part::*}; -use frame_support::{assert_noop, assert_ok, traits::{fungible::Inspect, nonfungible::{Transfer, Inspect as NftInspect}}}; +use frame_support::{assert_noop, assert_ok, traits::{nonfungible::{Transfer, Inspect as NftInspect}}}; use CoreAssignment::*; use CoretimeTraceItem::*; @@ -44,6 +44,65 @@ fn transfer_works() { }); } +#[test] +fn nft_metadata_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_eq!(attribute::(region, b"begin"), 4); + assert_eq!(attribute::(region, b"length"), 3); + assert_eq!(attribute::(region, b"end"), 7); + assert_eq!(attribute::(region, b"owner"), 1); + assert_eq!(attribute::(region, b"part"), 0xfffff_fffff_fffff_fffff.into()); + assert_eq!(attribute::(region, b"core"), 0); + assert_eq!(attribute::>(region, b"paid"), Some(100)); + + assert_ok!(Broker::do_transfer(region, None, 42)); + let (_, region) = Broker::do_partition(region, None, 2).unwrap(); + let (region, _) = Broker::do_interlace(region, None, 0x00000_fffff_fffff_00000.into()).unwrap(); + assert_eq!(attribute::(region, b"begin"), 6); + assert_eq!(attribute::(region, b"length"), 1); + assert_eq!(attribute::(region, b"end"), 7); + assert_eq!(attribute::(region, b"owner"), 42); + assert_eq!(attribute::(region, b"part"), 0x00000_fffff_fffff_00000.into()); + assert_eq!(attribute::(region, b"core"), 0); + assert_eq!(attribute::>(region, b"paid"), None); + }); +} + +#[test] +fn migration_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_set_lease(1000, 8)); + assert_ok!(Broker::do_start_sales(100)); + + // Sale is for regions from TS4..7 + // Not ending in this sale period. + assert_noop!(Broker::do_renew(1, 0), Error::::NotAllowed); + + advance_to(12); + // Sale is now for regions from TS10..13 + // Ending in this sale period. + // Should now be renewable. + assert_ok!(Broker::do_renew(1, 0)); + assert_eq!(balance(1), 900); + advance_to(18); + + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Task(1000), 57600), + ], end_hint: None }), + (12, AssignCore { core: 0, begin: 14, assignment: vec![ + (Task(1000), 57600), + ], end_hint: None }), + (18, AssignCore { core: 0, begin: 20, assignment: vec![ + (Task(1000), 57600), + ], end_hint: None }), + ]); + }); +} + #[test] fn renewal_works() { TestExt::new().endow(1, 1000).execute_with(|| { @@ -60,7 +119,7 @@ fn renewal_works() { advance_to(8); assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::SoldOut); advance_to(12); - let region = Broker::do_renew(1, core).unwrap(); + assert_ok!(Broker::do_renew(1, core)); assert_eq!(balance(1), 690); }); } @@ -73,8 +132,6 @@ fn instapool_payouts_work() { assert_ok!(Broker::do_start_sales(100)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let begin = SaleInfo::::get().unwrap().region_begin; - let region = RegionId { begin, core: 1, part: CorePart::complete() }; assert_ok!(Broker::do_pool(region, None, 2)); assert_ok!(Broker::do_purchase_credit(1, 20, 1)); advance_to(8); @@ -96,8 +153,6 @@ fn instapool_partial_core_payouts_work() { assert_ok!(Broker::do_start_sales(100)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let begin = SaleInfo::::get().unwrap().region_begin; - let region = RegionId { begin, core: 1, part: CorePart::complete() }; let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); assert_ok!(Broker::do_pool(region1, None, 2)); assert_ok!(Broker::do_pool(region2, None, 3)); diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 9d48c29145cbd..94f8126c46b3b 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -176,6 +176,8 @@ pub struct SaleInfoRecord { pub start_price: Balance, /// The price of Bulk Coretime by the end of the Leadin Period. pub reserve_price: Balance, + /// The price at which the Bulk Coretime offered sold out, if it did sell out. + pub sellout_price: Option, /// The first timeslice of the Regions which are being sold in this sale. pub region_begin: Timeslice, /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One diff --git a/primitives/arithmetic/src/fixed_point.rs b/primitives/arithmetic/src/fixed_point.rs index 08b788e9abd76..370e8d7267b0d 100644 --- a/primitives/arithmetic/src/fixed_point.rs +++ b/primitives/arithmetic/src/fixed_point.rs @@ -45,23 +45,24 @@ pub trait FixedPointOperand: + Bounded + Zero + Saturating - + PartialOrd + + PartialOrd + UniqueSaturatedInto + TryFrom + CheckedNeg { } -impl FixedPointOperand for i128 {} -impl FixedPointOperand for u128 {} -impl FixedPointOperand for i64 {} -impl FixedPointOperand for u64 {} -impl FixedPointOperand for i32 {} -impl FixedPointOperand for u32 {} -impl FixedPointOperand for i16 {} -impl FixedPointOperand for u16 {} -impl FixedPointOperand for i8 {} -impl FixedPointOperand for u8 {} +impl + + UniqueSaturatedInto + + TryFrom + + CheckedNeg +> FixedPointOperand for T {} /// Something that implements a decimal fixed point number. /// diff --git a/primitives/arithmetic/src/traits.rs b/primitives/arithmetic/src/traits.rs index 061b11b3e9c72..6fcc8248539ca 100644 --- a/primitives/arithmetic/src/traits.rs +++ b/primitives/arithmetic/src/traits.rs @@ -59,6 +59,7 @@ pub trait BaseArithmetic: + CheckedMul + CheckedDiv + CheckedRem + + CheckedNeg + Ensure + Saturating + PartialOrd @@ -116,6 +117,7 @@ impl< + CheckedMul + CheckedDiv + CheckedRem + + CheckedNeg + Ensure + Saturating + PartialOrd From 66b80829b0f3e814d09adb39de8b338982e2cd26 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 12 Jul 2023 14:04:55 +0200 Subject: [PATCH 029/131] Document events --- frame/broker/README.md | 3 +- frame/broker/src/dispatchable_impls.rs | 32 ++++----- frame/broker/src/lib.rs | 92 ++++++++++++++++++-------- 3 files changed, 82 insertions(+), 45 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index 50cb256c40db6..ee3a9a015726a 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -22,7 +22,8 @@ price fixed, unsold assigned to instapool, system cores reserved -/ ## TODO -- Nicer API for price finding; should include auction-sell-out info +- Dropping out of date storage +- Events - Benchmarks - Weights diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 007e14e9f06c7..d7ed798161f01 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -105,9 +105,12 @@ impl Pallet { ensure!(sale.first_core < config.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + let old_core = core; + let core = sale.first_core + sale.cores_sold; Self::charge(&who, record.price)?; Self::deposit_event(Event::Renewed { who, + old_core, core, price: record.price, begin: sale.region_begin, @@ -115,7 +118,6 @@ impl Pallet { workload: workload.clone(), }); - let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); Workplan::::insert((record.begin, core), &workload); @@ -168,18 +170,17 @@ impl Pallet { ensure!(pivot < region.end, Error::::PivotTooLate); region.paid = None; - let new_region_id = RegionId { begin: pivot, ..region_id.clone() }; - let new_region = RegionRecord { end: pivot, ..region.clone() }; + let new_region_ids = (region_id, RegionId { begin: pivot, ..region_id.clone() }); - Regions::::insert(®ion_id, &new_region); - Regions::::insert(&new_region_id, ®ion); - Self::deposit_event(Event::Partitioned { region_id, pivot, new_region_id }); + Regions::::insert(&new_region_ids.0, &RegionRecord { end: pivot, ..region.clone() }); + Regions::::insert(&new_region_ids.1, ®ion); + Self::deposit_event(Event::Partitioned { old_region_id: region_id, new_region_ids }); - Ok((region_id, new_region_id)) + Ok(new_region_ids) } pub(crate) fn do_interlace( - mut region_id: RegionId, + region_id: RegionId, maybe_check_owner: Option, pivot: CorePart, ) -> Result<(RegionId, RegionId), Error> { @@ -193,15 +194,14 @@ impl Pallet { ensure!(!pivot.is_void(), Error::::NullPivot); ensure!(pivot != region_id.part, Error::::CompletePivot); - let antipivot = region_id.part ^ pivot; - region_id.part = pivot; - Regions::::insert(®ion_id, ®ion); - let new_region_id = RegionId { part: antipivot, ..region_id }; - Regions::::insert(&new_region_id, ®ion); - - Self::deposit_event(Event::Interlaced { region_id, pivot, new_region_id }); + let one = RegionId { part: pivot, ..region_id }; + Regions::::insert(&one, ®ion); + let other = RegionId { part: region_id.part ^ pivot, ..region_id }; + Regions::::insert(&other, ®ion); - Ok((region_id, new_region_id)) + let new_region_ids = (one, other); + Self::deposit_event(Event::Interlaced { old_region_id: region_id, new_region_ids }); + Ok(new_region_ids) } pub(crate) fn do_assign( diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 141e350e99abe..8066f37a7e33c 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -152,53 +152,89 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// A Region of Bulk Coretime has been purchased. + Purchased { + /// The identity of the purchaser. + who: T::AccountId, + /// The identity of the Region. + region_id: RegionId, + /// The price paid for this Region. + price: BalanceOf, + /// The duration of the Region. + length: Timeslice, + }, + /// The workload of a core has become renewable. + Renewable { + /// The core whose workload can be renewed. + core: CoreIndex, + /// The price at which the workload can be renewed. + price: BalanceOf, + /// The time at which the workload would recommence of this renewal. The call to renew + /// cannot happen before the beginning of the interlude prior to the sale for regions + /// which begin at this time. + begin: Timeslice, + /// The actual workload which can be renewed. + workload: Schedule, + }, + /// A workload has been renewed. + Renewed { + /// The identity of the renewer. + who: T::AccountId, + /// The price paid for this renewal. + price: BalanceOf, + /// The index of the core on which the `workload` was previously scheduled. + old_core: CoreIndex, + /// The index of the core on which the renewed `workload` has been scheduled. + core: CoreIndex, + /// The time at which the `workload` will begin on the `core`. + begin: Timeslice, + /// The number of timeslices for which this `workload` is newly scheduled. + length: Timeslice, + /// The workload which was renewed. + workload: Schedule, + }, + /// Ownership of a Region has been transferred. Transferred { + /// The Region which has been transferred. region_id: RegionId, + /// The old owner of the Region. old_owner: T::AccountId, + /// The new owner of the Region. owner: T::AccountId, }, + /// A Region has been split into two non-overlapping Regions. Partitioned { - region_id: RegionId, - pivot: Timeslice, - new_region_id: RegionId, + /// The Region which was split. + old_region_id: RegionId, + /// The new Regions into which it became. + new_region_ids: (RegionId, RegionId), }, + /// A Region has been converted into two overlapping Regions each of lesser regularity. Interlaced { - region_id: RegionId, - pivot: CorePart, - new_region_id: RegionId, + /// The Region which was interlaced. + old_region_id: RegionId, + /// The new Regions into which it became. + new_region_ids: (RegionId, RegionId), }, + /// A Region has been assigned to a particular task. Assigned { + /// The Region which was assigned. region_id: RegionId, + /// The task to which the Region was assigned. task: TaskId, }, - Dropped { - region_id: RegionId, - }, + /// A Region has been added to the Instantaneous Coretime Pool. Pooled { + /// The Region which was added to the Instantaneous Coretime Pool. region_id: RegionId, }, - Renewable { - core: CoreIndex, - price: BalanceOf, - begin: Timeslice, - workload: Schedule, - }, - Renewed { - who: T::AccountId, - core: CoreIndex, - price: BalanceOf, - begin: Timeslice, - length: Timeslice, - workload: Schedule, - }, - Purchased { - who: T::AccountId, + /// A Region has been dropped due to being out of date. + Dropped { + /// The Region which no longer exists. region_id: RegionId, - price: BalanceOf, - length: Timeslice, }, } - + #[pallet::error] #[derive(PartialEq)] pub enum Error { From f9a3665862a6a7647dd51824633db9119b14b92e Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 12 Jul 2023 14:39:48 +0200 Subject: [PATCH 030/131] Introduce durations --- frame/broker/src/dispatchable_impls.rs | 23 ++++++++++++----------- frame/broker/src/implementation.rs | 3 ++- frame/broker/src/lib.rs | 14 +++++++++++--- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index d7ed798161f01..8457087c86bb9 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -88,8 +88,8 @@ impl Pallet { } SaleInfo::::put(&sale); let id = Self::issue(core, sale.region_begin, sale.region_end, who.clone(), Some(price)); - let length = sale.region_end.saturating_sub(sale.region_begin); - Self::deposit_event(Event::Purchased { who, region_id: id, price, length }); + let duration = sale.region_end.saturating_sub(sale.region_begin); + Self::deposit_event(Event::Purchased { who, region_id: id, price, duration }); Ok(id) } @@ -114,7 +114,7 @@ impl Pallet { core, price: record.price, begin: sale.region_begin, - length: sale.region_end.saturating_sub(sale.region_begin), + duration: sale.region_end.saturating_sub(sale.region_begin), workload: workload.clone(), }); @@ -151,7 +151,8 @@ impl Pallet { let old_owner = region.owner; region.owner = new_owner; Regions::::insert(®ion_id, ®ion); - Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner }); + let duration = region.end.saturating_sub(region_id.begin); + Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner, duration }); Ok(()) } @@ -221,7 +222,8 @@ impl Pallet { Workplan::::insert(&workplan_key, &workplan); } - if region.end.saturating_sub(region_id.begin) == config.region_length { + let duration = region.end.saturating_sub(region_id.begin); + if duration == config.region_length { if let Some(price) = region.paid { let begin = region.end; let assigned = match AllowedRenewals::::get(region_id.core) { @@ -241,7 +243,7 @@ impl Pallet { } } } - Self::deposit_event(Event::Assigned { region_id, task: target }); + Self::deposit_event(Event::Assigned { region_id, task: target, duration }); } Ok(()) } @@ -255,6 +257,7 @@ impl Pallet { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) .unwrap_or_default(); + let duration = region.end.saturating_sub(region_id.begin); if workplan.try_push(ScheduleItem { part: region_id.part, assignment: CoreAssignment::Pool, @@ -263,13 +266,11 @@ impl Pallet { let size = region_id.part.count_ones() as i32; InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); InstaPoolIo::::mutate(region.end, |a| a.total.saturating_reduce(size)); - let record = ContributionRecord { - length: region.end.saturating_sub(region_id.begin), - payee, - }; + let record = ContributionRecord { length: duration, payee }; InstaPoolContribution::::insert(®ion_id, record); } - Self::deposit_event(Event::Pooled { region_id }); + + Self::deposit_event(Event::Pooled { region_id, duration }); } Ok(()) } diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 3492d7f03f8df..767af380b4d58 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -300,7 +300,8 @@ impl Pallet { if region_id.begin < region.end { Ok(Some((region_id, region))) } else { - Self::deposit_event(Event::Dropped { region_id }); + let duration = region.end.saturating_sub(region_id.begin); + Self::deposit_event(Event::Dropped { region_id, duration }); Ok(None) } } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 8066f37a7e33c..b51f58bbb0edb 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -161,7 +161,7 @@ pub mod pallet { /// The price paid for this Region. price: BalanceOf, /// The duration of the Region. - length: Timeslice, + duration: Timeslice, }, /// The workload of a core has become renewable. Renewable { @@ -189,7 +189,7 @@ pub mod pallet { /// The time at which the `workload` will begin on the `core`. begin: Timeslice, /// The number of timeslices for which this `workload` is newly scheduled. - length: Timeslice, + duration: Timeslice, /// The workload which was renewed. workload: Schedule, }, @@ -197,6 +197,8 @@ pub mod pallet { Transferred { /// The Region which has been transferred. region_id: RegionId, + /// The duration of the Region. + duration: Timeslice, /// The old owner of the Region. old_owner: T::AccountId, /// The new owner of the Region. @@ -220,6 +222,8 @@ pub mod pallet { Assigned { /// The Region which was assigned. region_id: RegionId, + /// The duration of the assignment. + duration: Timeslice, /// The task to which the Region was assigned. task: TaskId, }, @@ -227,14 +231,18 @@ pub mod pallet { Pooled { /// The Region which was added to the Instantaneous Coretime Pool. region_id: RegionId, + /// The duration of the Region. + duration: Timeslice, }, /// A Region has been dropped due to being out of date. Dropped { /// The Region which no longer exists. region_id: RegionId, + /// The duration of the Region. + duration: Timeslice, }, } - + #[pallet::error] #[derive(PartialEq)] pub enum Error { From a5c4062be38b31b0b4dbfb2a3772635f0ea9b6da Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 12 Jul 2023 15:33:41 +0200 Subject: [PATCH 031/131] Core count --- frame/broker/README.md | 5 ++- frame/broker/src/dispatchable_impls.rs | 50 ++++++++++++++++++++++-- frame/broker/src/implementation.rs | 20 +++++++--- frame/broker/src/lib.rs | 47 ++++++++++++++++++++-- frame/broker/src/mock.rs | 12 +++--- frame/broker/src/tests.rs | 36 ++++++++--------- frame/broker/src/types.rs | 8 ++-- frame/broker/src/weights.rs | 12 ++++++ frame/support/src/storage/mod.rs | 11 ++++++ frame/support/src/storage/types/value.rs | 7 ++++ 10 files changed, 167 insertions(+), 41 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index ee3a9a015726a..cd9a07ab23d97 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -8,7 +8,7 @@ Properly described in RFC-0001 Agile Coretime. ### The Sale -``` +```nocompile 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 -------------------------------------------------------- @@ -22,8 +22,9 @@ price fixed, unsold assigned to instapool, system cores reserved -/ ## TODO -- Dropping out of date storage +- Tests for dropping out of date storage - Events +- Tests for core count changes - Benchmarks - Weights diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 8457087c86bb9..9f3b6fc18a50a 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -16,6 +16,13 @@ impl Pallet { Ok(()) } + pub(crate) fn do_request_core_count( + core_count: CoreIndex, + ) -> DispatchResult { + T::Coretime::request_core_count(core_count); + Ok(()) + } + pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { let mut r = Reservations::::get(); r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; @@ -40,9 +47,11 @@ impl Pallet { pub(crate) fn do_start_sales( reserve_price: BalanceOf, + core_count: CoreIndex, ) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = StatusRecord { + core_count, pool_size: 0, last_timeslice: Self::current_timeslice(), system_pool_size: 0, @@ -62,7 +71,7 @@ impl Pallet { cores_offered: 0, cores_sold: 0, }; - Self::rotate_sale(dummy_sale, &config); + Self::rotate_sale(dummy_sale, &config, &status); Status::::put(&status); Ok(()) } @@ -71,9 +80,9 @@ impl Pallet { who: T::AccountId, price_limit: BalanceOf, ) -> Result { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.first_core < status.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let now = frame_system::Pallet::::block_number(); ensure!(now > sale.sale_start, Error::::TooEarly); @@ -97,12 +106,13 @@ impl Pallet { /// current sale status's `region_end`. pub(crate) fn do_renew(who: T::AccountId, core: CoreIndex) -> Result { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); - ensure!(sale.first_core < config.core_count, Error::::Unavailable); + ensure!(sale.first_core < status.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); let old_core = core; @@ -318,4 +328,36 @@ impl Pallet { T::Coretime::credit_account(beneficiary, amount); Ok(()) } + + pub(crate) fn do_drop_region(region_id: RegionId) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + let next_commit_timeslice = status.last_timeslice + config.advance_notice + 1; + ensure!(next_commit_timeslice >= region.end, Error::::StillValid); + + Regions::::remove(®ion_id); + let duration = region.end.saturating_sub(region_id.begin); + Self::deposit_event(Event::Dropped { region_id, duration }); + Ok(()) + } + + pub(crate) fn do_drop_contribution(region_id: RegionId) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let contrib = InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + let end = region_id.begin.saturating_add(contrib.length); + ensure!(status.last_timeslice > end + config.contribution_timeout, Error::::StillValid); + InstaPoolContribution::::remove(region_id); + Ok(()) + } + + pub(crate) fn do_drop_history(when: Timeslice) -> DispatchResult { + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let status = Status::::get().ok_or(Error::::Uninitialized)?; + ensure!(status.last_timeslice > when + config.contribution_timeout, Error::::StillValid); + ensure!(InstaPoolHistory::::contains_key(when), Error::::NoHistory); + InstaPoolHistory::::remove(when); + Ok(()) + } } \ No newline at end of file diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 767af380b4d58..cc069405ed1e9 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -27,10 +27,11 @@ impl Pallet { if let Some(sale) = SaleInfo::::get() { if commit_timeslice >= sale.region_begin { // Sale can be rotated. - Self::rotate_sale(sale, &config); + Self::rotate_sale(sale, &config, &status); } } Self::process_timeslice(commit_timeslice, &mut status, &config); + Self::process_core_count()?; Self::process_revenue()?; Status::::put(&status); @@ -43,6 +44,7 @@ impl Pallet { pub(crate) fn rotate_sale( old_sale: SaleInfoRecordOf, config: &ConfigRecordOf, + status: &StatusRecord, ) -> Option<()> { let now = frame_system::Pallet::::block_number(); @@ -105,7 +107,7 @@ impl Pallet { }); let mut leases = Leases::::get(); - // can morph to a renewable as long as it's > begin and < end. + // Can morph to a renewable as long as it's >=begin and Pallet { }); Leases::::put(&leases); - let max_possible_sales = config.core_count.saturating_sub(first_core); + let max_possible_sales = status.core_count.saturating_sub(first_core); let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); let cores_offered = limit_cores_offered.min(max_possible_sales); // Update SaleInfo @@ -158,6 +160,14 @@ impl Pallet { T::PalletId::get().into_account_truncating() } + fn process_core_count() -> Result { + if let Some(new_count) = T::Coretime::check_notify_core_count() { + Status::::mutate_extant(|c| c.core_count = new_count); + return Ok(true) + } + Ok(false) + } + fn process_revenue() -> Result { if let Some((until, amount)) = T::Coretime::check_notify_revenue_info() { let timeslice: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); @@ -201,10 +211,10 @@ impl Pallet { (latest / timeslice_period).saturated_into() } - pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, config: &ConfigRecordOf) { + pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, _config: &ConfigRecordOf) { Self::process_pool(timeslice, status); let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); - for core in 0..config.core_count { + for core in 0..status.core_count { Self::process_core_schedule(timeslice, rc_begin, core); } } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index b51f58bbb0edb..6a29e6e79041a 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -47,7 +47,7 @@ pub use utils::*; pub mod pallet { use super::*; use frame_support::{ - pallet_prelude::{*, DispatchResult}, + pallet_prelude::{*, DispatchResult, DispatchResultWithPostInfo}, traits::{fungible::{Credit, Mutate, Balanced}, OnUnbalanced, EnsureOrigin}, PalletId, }; @@ -271,6 +271,10 @@ pub mod pallet { UnknownContribution, InvalidContributions, IncompleteAssignment, + /// An item cannot be dropped because it is still valid. + StillValid, + /// The history item does not exist. + NoHistory, } #[pallet::hooks] @@ -312,9 +316,9 @@ pub mod pallet { } #[pallet::call_index(4)] - pub fn start_sales(origin: OriginFor, initial_price: BalanceOf) -> DispatchResult { + pub fn start_sales(origin: OriginFor, initial_price: BalanceOf, core_count: CoreIndex) -> DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; - Self::do_start_sales(initial_price)?; + Self::do_start_sales(initial_price, core_count)?; Ok(()) } @@ -409,5 +413,42 @@ pub mod pallet { Self::do_purchase_credit(who, amount, beneficiary)?; Ok(()) } + + #[pallet::call_index(14)] + pub fn drop_region( + origin: OriginFor, + region_id: RegionId, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + Self::do_drop_region(region_id)?; + Ok(Pays::No.into()) + } + + #[pallet::call_index(15)] + pub fn drop_contribution( + origin: OriginFor, + region_id: RegionId, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + Self::do_drop_contribution(region_id)?; + Ok(Pays::No.into()) + } + + #[pallet::call_index(16)] + pub fn drop_history( + origin: OriginFor, + when: Timeslice, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + Self::do_drop_history(when)?; + Ok(Pays::No.into()) + } + + #[pallet::call_index(17)] + pub fn request_core_count(origin: OriginFor, core_count: CoreIndex) -> DispatchResult { + T::AdminOrigin::ensure_origin_or_root(origin)?; + Self::do_request_core_count(core_count)?; + Ok(()) + } } } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 9d2912c6f660d..85ce724a3b2e1 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -218,7 +218,6 @@ pub struct TestExt(ConfigRecordOf); impl TestExt { pub fn new() -> Self { Self(ConfigRecord { - core_count: 1, advance_notice: 1, interlude_length: 1, leadin_length: 1, @@ -226,14 +225,10 @@ impl TestExt { limit_cores_offered: None, region_length: 3, renewal_bump: Perbill::from_percent(10), + contribution_timeout: 5, }) } - pub fn core_count(mut self, core_count: CoreIndex) -> Self { - self.0.core_count = core_count; - self - } - pub fn advance_notice(mut self, advance_notice: Timeslice) -> Self { self.0.advance_notice = advance_notice; self @@ -269,6 +264,11 @@ impl TestExt { self } + pub fn contribution_timeout(mut self, contribution_timeout: Timeslice) -> Self { + self.0.contribution_timeout = contribution_timeout; + self + } + pub fn endow(self, who: u64, amount: u64) -> Self { assert_ok!(<::Currency as Mutate<_>>::mint_into(&who, amount)); self diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index dd20355d607fa..60df13303210e 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -25,7 +25,7 @@ use CoretimeTraceItem::*; #[test] fn basic_initialize_works() { TestExt::new().execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); assert_eq!(CoretimeTrace::get(), vec![]); assert_eq!(Broker::current_timeslice(), 0); }); @@ -34,7 +34,7 @@ fn basic_initialize_works() { #[test] fn transfer_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(>::transfer(®ion.into(), &2)); @@ -47,7 +47,7 @@ fn transfer_works() { #[test] fn nft_metadata_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_eq!(attribute::(region, b"begin"), 4); @@ -75,7 +75,7 @@ fn nft_metadata_works() { fn migration_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_set_lease(1000, 8)); - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); // Sale is for regions from TS4..7 // Not ending in this sale period. @@ -106,7 +106,7 @@ fn migration_works() { #[test] fn renewal_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_eq!(balance(1), 900); @@ -126,10 +126,10 @@ fn renewal_works() { #[test] fn instapool_payouts_work() { - TestExt::new().core_count(3).endow(1, 1000).execute_with(|| { + TestExt::new().endow(1, 1000).execute_with(|| { let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 3)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_pool(region, None, 2)); @@ -147,10 +147,10 @@ fn instapool_payouts_work() { #[test] fn instapool_partial_core_payouts_work() { - TestExt::new().core_count(2).endow(1, 1000).execute_with(|| { + TestExt::new().endow(1, 1000).execute_with(|| { let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 2)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); @@ -171,7 +171,7 @@ fn instapool_partial_core_payouts_work() { #[test] fn initialize_with_system_paras_works() { - TestExt::new().core_count(2).execute_with(|| { + TestExt::new().execute_with(|| { let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); let items = vec![ @@ -180,7 +180,7 @@ fn initialize_with_system_paras_works() { ScheduleItem { assignment: Task(4u32), part: 0x00000_00000_00000_fffff.into() }, ]; assert_ok!(Broker::do_reserve(Schedule::truncate_from(items))); - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 2)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -197,10 +197,10 @@ fn initialize_with_system_paras_works() { #[test] fn initialize_with_leased_slots_works() { - TestExt::new().core_count(2).execute_with(|| { + TestExt::new().execute_with(|| { assert_ok!(Broker::do_set_lease(1000, 6)); assert_ok!(Broker::do_set_lease(1001, 7)); - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 2)); advance_to(18); let end_hint = None; assert_eq!(CoretimeTrace::get(), vec![ @@ -217,7 +217,7 @@ fn initialize_with_leased_slots_works() { #[test] fn purchase_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_assign(region, None, 1000)); @@ -233,7 +233,7 @@ fn purchase_works() { #[test] fn partition_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_partition(region, None, 1).unwrap(); @@ -259,7 +259,7 @@ fn partition_works() { #[test] fn interlace_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 30)).unwrap(); @@ -281,7 +281,7 @@ fn interlace_works() { #[test] fn interlace_then_partition_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); @@ -312,7 +312,7 @@ fn interlace_then_partition_works() { #[test] fn partition_then_interlace_works() { TestExt::new().endow(1, 1000).execute_with(|| { - assert_ok!(Broker::do_start_sales(100)); + assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 94f8126c46b3b..8030527026610 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -143,6 +143,9 @@ pub type AllowedRenewalRecordOf = AllowedRenewalRecord>; /// General status of the system. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct StatusRecord { + /// The total number of cores which can be assigned (one plus the maximum index which can + /// be used in `Coretime::assign`). + pub core_count: CoreIndex, /// The current size of the Instantaneous Coretime Pool, measured in /// Regularity Parts or 1/80th of a single block of a Polkadot Core. pub pool_size: PartCount, @@ -218,9 +221,6 @@ pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; /// Configuration of this pallet. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ConfigRecord { - /// The total number of cores which can be assigned (one plus the maximum index which can - /// be used in `Coretime::assign`). - pub core_count: CoreIndex, /// The number of timeslices in advance which scheduling should be fixed and the /// `Coretime::assign` API used to inform the Relay-chain. pub advance_notice: Timeslice, @@ -238,6 +238,8 @@ pub struct ConfigRecord { pub limit_cores_offered: Option, /// The amount by which the renewal price increases each sale period. pub renewal_bump: Perbill, + /// The duration by which rewards for contributions to the InstaPool must be collected. + pub contribution_timeout: Timeslice, } pub type ConfigRecordOf = ConfigRecord< ::BlockNumber, diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index f3e121c3758a8..6c1d6b54a9cec 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -40,6 +40,10 @@ pub trait WeightInfo { fn pool() -> Weight; fn claim_revenue(m: u32,) -> Weight; fn purchase_credit() -> Weight; + fn drop_region() -> Weight; + fn drop_contribution() -> Weight; + fn drop_history() -> Weight; + fn request_core_count() -> Weight; } /// Weights for `pallet-broker` using the Substrate node and recommended hardware. @@ -59,6 +63,10 @@ impl WeightInfo for SubstrateWeight { fn pool() -> Weight { Weight::from_parts(123, 456) } fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } + fn drop_region() -> Weight { Weight::from_parts(123, 456) } + fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } + fn drop_history() -> Weight { Weight::from_parts(123, 456) } + fn request_core_count() -> Weight { Weight::from_parts(123, 456) } } // For backwards compatibility and tests @@ -77,4 +85,8 @@ impl WeightInfo for () { fn pool() -> Weight { Weight::from_parts(123, 456) } fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } + fn drop_region() -> Weight { Weight::from_parts(123, 456) } + fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } + fn drop_history() -> Weight { Weight::from_parts(123, 456) } + fn request_core_count() -> Weight { Weight::from_parts(123, 456) } } diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 470af0a1d5520..57d31dade6dcd 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -111,6 +111,17 @@ pub trait StorageValue { /// Mutate the value fn mutate R>(f: F) -> R; + /// Mutate the value under a key if the value already exists. Do nothing and return the default + /// value if not. + fn mutate_extant R>( + f: F, + ) -> R { + Self::mutate_exists(|maybe_v| match maybe_v { + Some(ref mut value) => f(value), + None => R::default(), + }) + } + /// Mutate the value if closure returns `Ok` fn try_mutate Result>(f: F) -> Result; diff --git a/frame/support/src/storage/types/value.rs b/frame/support/src/storage/types/value.rs index d5fbb0656bbd1..509ede67c976a 100644 --- a/frame/support/src/storage/types/value.rs +++ b/frame/support/src/storage/types/value.rs @@ -135,6 +135,13 @@ where >::mutate(f) } + /// Mutate the value under a key iff it exists. Do nothing and return the default value if not. + pub fn mutate_extant R>( + f: F, + ) -> R { + >::mutate_extant(f) + } + /// Mutate the value if closure returns `Ok` pub fn try_mutate Result>( f: F, From 08c08accf3ecd434d99bbeb3433a2e8348f53d34 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 12:34:30 +0100 Subject: [PATCH 032/131] Allow reassignment --- frame/broker/README.md | 2 +- frame/broker/src/dispatchable_impls.rs | 10 ++- frame/broker/src/implementation.rs | 24 +++++--- frame/broker/src/lib.rs | 6 +- frame/broker/src/tests.rs | 84 +++++++++++++++++++------- frame/broker/src/types.rs | 11 +++- 6 files changed, 100 insertions(+), 37 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index cd9a07ab23d97..9bf88fc5da10c 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -22,8 +22,8 @@ price fixed, unsold assigned to instapool, system cores reserved -/ ## TODO +- More Events - Tests for dropping out of date storage -- Events - Tests for core count changes - Benchmarks diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 9f3b6fc18a50a..42d905b22e6d2 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -219,12 +219,15 @@ impl Pallet { region_id: RegionId, maybe_check_owner: Option, target: TaskId, + permanence: Permanence, ) -> Result<(), Error> { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, permanence)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) .unwrap_or_default(); + // Ensure no previous allocations exist. + workplan.retain(|i| (i.part & region_id.part).is_void()); if workplan.try_push(ScheduleItem { part: region_id.part, assignment: CoreAssignment::Task(target), @@ -233,7 +236,7 @@ impl Pallet { } let duration = region.end.saturating_sub(region_id.begin); - if duration == config.region_length { + if duration == config.region_length && permanence == Permanence::Permanent { if let Some(price) = region.paid { let begin = region.end; let assigned = match AllowedRenewals::::get(region_id.core) { @@ -262,8 +265,9 @@ impl Pallet { region_id: RegionId, maybe_check_owner: Option, payee: T::AccountId, + permanence: Permanence, ) -> Result<(), Error> { - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner)? { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, permanence)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) .unwrap_or_default(); diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index cc069405ed1e9..263b5e061be99 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -292,6 +292,7 @@ impl Pallet { pub(crate) fn utilize( mut region_id: RegionId, maybe_check_owner: Option, + permanence: Permanence, ) -> Result)>, Error> { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; @@ -301,18 +302,25 @@ impl Pallet { ensure!(check_owner == region.owner, Error::::NotOwner); } + Regions::::remove(®ion_id); + let last_commit_timeslice = status.last_timeslice + config.advance_notice; if region_id.begin <= last_commit_timeslice { region_id.begin = last_commit_timeslice + 1; - } - Regions::::remove(®ion_id); - - if region_id.begin < region.end { - Ok(Some((region_id, region))) + if region_id.begin >= region.end { + let duration = region.end.saturating_sub(region_id.begin); + Self::deposit_event(Event::Dropped { region_id, duration }); + return Ok(None) + } } else { - let duration = region.end.saturating_sub(region_id.begin); - Self::deposit_event(Event::Dropped { region_id, duration }); - Ok(None) + Workplan::::mutate_extant((region_id.begin, region_id.core), |p| + p.retain(|i| (i.part & region_id.part).is_void()) + ); } + if permanence == Permanence::Provisional { + Regions::::insert(®ion_id, ®ion); + } + + Ok(Some((region_id, region))) } } \ No newline at end of file diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 6a29e6e79041a..4ca0d6cbba7ea 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -374,9 +374,10 @@ pub mod pallet { origin: OriginFor, region_id: RegionId, target: TaskId, + permanence: Permanence, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_assign(region_id, Some(who), target)?; + Self::do_assign(region_id, Some(who), target, permanence)?; Ok(()) } @@ -385,9 +386,10 @@ pub mod pallet { origin: OriginFor, region_id: RegionId, payee: T::AccountId, + permanence: Permanence, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_pool(region_id, Some(who), payee)?; + Self::do_pool(region_id, Some(who), payee, permanence)?; Ok(()) } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 60df13303210e..806b001235024 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -18,9 +18,10 @@ #![cfg(test)] use crate::{*, mock::*, core_part::*}; -use frame_support::{assert_noop, assert_ok, traits::{nonfungible::{Transfer, Inspect as NftInspect}}}; +use frame_support::{assert_noop, assert_ok, traits::nonfungible::{Transfer, Inspect as NftInspect}}; use CoreAssignment::*; use CoretimeTraceItem::*; +use Permanence::*; #[test] fn basic_initialize_works() { @@ -39,8 +40,47 @@ fn transfer_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(>::transfer(®ion.into(), &2)); assert_eq!(>::owner(®ion.into()), Some(2)); - assert_noop!(Broker::do_assign(region, Some(1), 1001), Error::::NotOwner); - assert_ok!(Broker::do_assign(region, Some(2), 1002)); + assert_noop!(Broker::do_assign(region, Some(1), 1001, Permanent), Error::::NotOwner); + assert_ok!(Broker::do_assign(region, Some(2), 1002, Permanent)); + }); +} + +#[test] +fn permanent_is_not_reassignable() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Permanent)); + assert_noop!(Broker::do_assign(region, Some(1), 1002, Permanent), Error::::UnknownRegion); + assert_noop!(Broker::do_pool(region, Some(1), 1002, Permanent), Error::::UnknownRegion); + assert_noop!(Broker::do_partition(region, Some(1), 1), Error::::UnknownRegion); + assert_noop!(Broker::do_interlace(region, Some(1), CorePart::from_chunk(0, 40)), Error::::UnknownRegion); + }); +} + +#[test] +fn provisional_is_reassignable() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Provisional)); + let (region1, region) = Broker::do_partition(region, Some(1), 1).unwrap(); + let (region2, region3) = Broker::do_interlace(region, Some(1), CorePart::from_chunk(0, 40)).unwrap(); + assert_ok!(Broker::do_pool(region1, Some(1), 1, Provisional)); + assert_ok!(Broker::do_assign(region2, Some(1), 1002, Provisional)); + assert_ok!(Broker::do_assign(region3, Some(1), 1003, Provisional)); + advance_to(8); + assert_eq!(CoretimeTrace::get(), vec![ + (6, AssignCore { core: 0, begin: 8, assignment: vec![ + (Pool, 57600), + ], end_hint: None }), + (8, AssignCore { core: 0, begin: 10, assignment: vec![ + (Task(1002), 28800), + (Task(1003), 28800), + ], end_hint: None }), + ]); }); } @@ -110,7 +150,7 @@ fn renewal_works() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_eq!(balance(1), 900); - assert_ok!(Broker::do_assign(region, None, 1001)); + assert_ok!(Broker::do_assign(region, None, 1001, Permanent)); // Should now be renewable. advance_to(6); assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::TooEarly); @@ -132,7 +172,7 @@ fn instapool_payouts_work() { assert_ok!(Broker::do_start_sales(100, 3)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - assert_ok!(Broker::do_pool(region, None, 2)); + assert_ok!(Broker::do_pool(region, None, 2, Permanent)); assert_ok!(Broker::do_purchase_credit(1, 20, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); @@ -154,8 +194,8 @@ fn instapool_partial_core_payouts_work() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); - assert_ok!(Broker::do_pool(region1, None, 2)); - assert_ok!(Broker::do_pool(region2, None, 3)); + assert_ok!(Broker::do_pool(region1, None, 2, Permanent)); + assert_ok!(Broker::do_pool(region2, None, 3, Permanent)); assert_ok!(Broker::do_purchase_credit(1, 40, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); @@ -220,7 +260,7 @@ fn purchase_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - assert_ok!(Broker::do_assign(region, None, 1000)); + assert_ok!(Broker::do_assign(region, None, 1000, Permanent)); advance_to(6); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -238,9 +278,9 @@ fn partition_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_partition(region, None, 1).unwrap(); let (region2, region3) = Broker::do_partition(region, None, 1).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001)); - assert_ok!(Broker::do_assign(region2, None, 1002)); - assert_ok!(Broker::do_assign(region3, None, 1003)); + assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); + assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); + assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -264,9 +304,9 @@ fn interlace_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 30)).unwrap(); let (region2, region3) =Broker::do_interlace(region, None, CorePart::from_chunk(30, 60)).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001)); - assert_ok!(Broker::do_assign(region2, None, 1002)); - assert_ok!(Broker::do_assign(region3, None, 1003)); + assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); + assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); + assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -287,10 +327,10 @@ fn interlace_then_partition_works() { let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); let (region1, region3) = Broker::do_partition(region1, None, 1).unwrap(); let (region2, region4) = Broker::do_partition(region2, None, 2).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001)); - assert_ok!(Broker::do_assign(region2, None, 1002)); - assert_ok!(Broker::do_assign(region3, None, 1003)); - assert_ok!(Broker::do_assign(region4, None, 1004)); + assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); + assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); + assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); + assert_ok!(Broker::do_assign(region4, None, 1004, Permanent)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -318,10 +358,10 @@ fn partition_then_interlace_works() { let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); let (region1, region3) = Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20)).unwrap(); let (region2, region4) = Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30)).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001)); - assert_ok!(Broker::do_assign(region2, None, 1002)); - assert_ok!(Broker::do_assign(region3, None, 1003)); - assert_ok!(Broker::do_assign(region4, None, 1004)); + assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); + assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); + assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); + assert_ok!(Broker::do_assign(region4, None, 1004, Permanent)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 8030527026610..776651d772a4e 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -20,6 +20,15 @@ pub type PartCount = u32; /// The same as `PartCount` but signed. pub type SignedPartCount = i32; +/// Whether a core assignment is revokable or not. +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub enum Permanence { + /// The region remains with the same owner allowing the assignment to be altered. + Provisional, + /// The region is removed; the assignment may be eligible for renewal. + Permanent, +} + /// Self-describing identity for a Region of Bulk Coretime. #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct RegionId { @@ -59,7 +68,7 @@ pub struct RegionRecord { pub end: Timeslice, /// The owner of the Region. pub owner: AccountId, - /// The amount paid to Polkadot for this Region. + /// The amount paid to Polkadot for this Region, or `None` if renewal is not allowed. pub paid: Option, } pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf>; From 72bf053bb7ab665f321365e9dcc9ef721d57f507 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 12:57:13 +0100 Subject: [PATCH 033/131] Better naming --- frame/broker/src/dispatchable_impls.rs | 10 +++--- frame/broker/src/implementation.rs | 4 +-- frame/broker/src/lib.rs | 8 ++--- frame/broker/src/tests.rs | 50 +++++++++++++------------- frame/broker/src/types.rs | 4 +-- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 42d905b22e6d2..f81079d84bb83 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -219,10 +219,10 @@ impl Pallet { region_id: RegionId, maybe_check_owner: Option, target: TaskId, - permanence: Permanence, + finality: Finality, ) -> Result<(), Error> { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, permanence)? { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, finality)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) .unwrap_or_default(); @@ -236,7 +236,7 @@ impl Pallet { } let duration = region.end.saturating_sub(region_id.begin); - if duration == config.region_length && permanence == Permanence::Permanent { + if duration == config.region_length && finality == Finality::Final { if let Some(price) = region.paid { let begin = region.end; let assigned = match AllowedRenewals::::get(region_id.core) { @@ -265,9 +265,9 @@ impl Pallet { region_id: RegionId, maybe_check_owner: Option, payee: T::AccountId, - permanence: Permanence, + finality: Finality, ) -> Result<(), Error> { - if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, permanence)? { + if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, finality)? { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key) .unwrap_or_default(); diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 263b5e061be99..6ce31044bbb34 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -292,7 +292,7 @@ impl Pallet { pub(crate) fn utilize( mut region_id: RegionId, maybe_check_owner: Option, - permanence: Permanence, + finality: Finality, ) -> Result)>, Error> { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; @@ -317,7 +317,7 @@ impl Pallet { p.retain(|i| (i.part & region_id.part).is_void()) ); } - if permanence == Permanence::Provisional { + if finality == Finality::Provisional { Regions::::insert(®ion_id, ®ion); } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 4ca0d6cbba7ea..18c786e314f89 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -374,10 +374,10 @@ pub mod pallet { origin: OriginFor, region_id: RegionId, target: TaskId, - permanence: Permanence, + finality: Finality, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_assign(region_id, Some(who), target, permanence)?; + Self::do_assign(region_id, Some(who), target, finality)?; Ok(()) } @@ -386,10 +386,10 @@ pub mod pallet { origin: OriginFor, region_id: RegionId, payee: T::AccountId, - permanence: Permanence, + finality: Finality, ) -> DispatchResult { let who = ensure_signed(origin)?; - Self::do_pool(region_id, Some(who), payee, permanence)?; + Self::do_pool(region_id, Some(who), payee, finality)?; Ok(()) } diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 806b001235024..bf60f018951ea 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -21,7 +21,7 @@ use crate::{*, mock::*, core_part::*}; use frame_support::{assert_noop, assert_ok, traits::nonfungible::{Transfer, Inspect as NftInspect}}; use CoreAssignment::*; use CoretimeTraceItem::*; -use Permanence::*; +use Finality::*; #[test] fn basic_initialize_works() { @@ -40,8 +40,8 @@ fn transfer_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(>::transfer(®ion.into(), &2)); assert_eq!(>::owner(®ion.into()), Some(2)); - assert_noop!(Broker::do_assign(region, Some(1), 1001, Permanent), Error::::NotOwner); - assert_ok!(Broker::do_assign(region, Some(2), 1002, Permanent)); + assert_noop!(Broker::do_assign(region, Some(1), 1001, Final), Error::::NotOwner); + assert_ok!(Broker::do_assign(region, Some(2), 1002, Final)); }); } @@ -51,9 +51,9 @@ fn permanent_is_not_reassignable() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - assert_ok!(Broker::do_assign(region, Some(1), 1001, Permanent)); - assert_noop!(Broker::do_assign(region, Some(1), 1002, Permanent), Error::::UnknownRegion); - assert_noop!(Broker::do_pool(region, Some(1), 1002, Permanent), Error::::UnknownRegion); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Final)); + assert_noop!(Broker::do_assign(region, Some(1), 1002, Final), Error::::UnknownRegion); + assert_noop!(Broker::do_pool(region, Some(1), 1002, Final), Error::::UnknownRegion); assert_noop!(Broker::do_partition(region, Some(1), 1), Error::::UnknownRegion); assert_noop!(Broker::do_interlace(region, Some(1), CorePart::from_chunk(0, 40)), Error::::UnknownRegion); }); @@ -150,7 +150,7 @@ fn renewal_works() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_eq!(balance(1), 900); - assert_ok!(Broker::do_assign(region, None, 1001, Permanent)); + assert_ok!(Broker::do_assign(region, None, 1001, Final)); // Should now be renewable. advance_to(6); assert_noop!(Broker::do_purchase(1, u64::max_value()), Error::::TooEarly); @@ -172,7 +172,7 @@ fn instapool_payouts_work() { assert_ok!(Broker::do_start_sales(100, 3)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - assert_ok!(Broker::do_pool(region, None, 2, Permanent)); + assert_ok!(Broker::do_pool(region, None, 2, Final)); assert_ok!(Broker::do_purchase_credit(1, 20, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); @@ -194,8 +194,8 @@ fn instapool_partial_core_payouts_work() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); - assert_ok!(Broker::do_pool(region1, None, 2, Permanent)); - assert_ok!(Broker::do_pool(region2, None, 3, Permanent)); + assert_ok!(Broker::do_pool(region1, None, 2, Final)); + assert_ok!(Broker::do_pool(region2, None, 3, Final)); assert_ok!(Broker::do_purchase_credit(1, 40, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); @@ -260,7 +260,7 @@ fn purchase_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - assert_ok!(Broker::do_assign(region, None, 1000, Permanent)); + assert_ok!(Broker::do_assign(region, None, 1000, Final)); advance_to(6); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -278,9 +278,9 @@ fn partition_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_partition(region, None, 1).unwrap(); let (region2, region3) = Broker::do_partition(region, None, 1).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); - assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); - assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); + assert_ok!(Broker::do_assign(region1, None, 1001, Final)); + assert_ok!(Broker::do_assign(region2, None, 1002, Final)); + assert_ok!(Broker::do_assign(region3, None, 1003, Final)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -304,9 +304,9 @@ fn interlace_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 30)).unwrap(); let (region2, region3) =Broker::do_interlace(region, None, CorePart::from_chunk(30, 60)).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); - assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); - assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); + assert_ok!(Broker::do_assign(region1, None, 1001, Final)); + assert_ok!(Broker::do_assign(region2, None, 1002, Final)); + assert_ok!(Broker::do_assign(region3, None, 1003, Final)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -327,10 +327,10 @@ fn interlace_then_partition_works() { let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); let (region1, region3) = Broker::do_partition(region1, None, 1).unwrap(); let (region2, region4) = Broker::do_partition(region2, None, 2).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); - assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); - assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); - assert_ok!(Broker::do_assign(region4, None, 1004, Permanent)); + assert_ok!(Broker::do_assign(region1, None, 1001, Final)); + assert_ok!(Broker::do_assign(region2, None, 1002, Final)); + assert_ok!(Broker::do_assign(region3, None, 1003, Final)); + assert_ok!(Broker::do_assign(region4, None, 1004, Final)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ @@ -358,10 +358,10 @@ fn partition_then_interlace_works() { let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); let (region1, region3) = Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20)).unwrap(); let (region2, region4) = Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30)).unwrap(); - assert_ok!(Broker::do_assign(region1, None, 1001, Permanent)); - assert_ok!(Broker::do_assign(region2, None, 1002, Permanent)); - assert_ok!(Broker::do_assign(region3, None, 1003, Permanent)); - assert_ok!(Broker::do_assign(region4, None, 1004, Permanent)); + assert_ok!(Broker::do_assign(region1, None, 1001, Final)); + assert_ok!(Broker::do_assign(region2, None, 1002, Final)); + assert_ok!(Broker::do_assign(region3, None, 1003, Final)); + assert_ok!(Broker::do_assign(region4, None, 1004, Final)); advance_to(10); assert_eq!(CoretimeTrace::get(), vec![ (6, AssignCore { core: 0, begin: 8, assignment: vec![ diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 776651d772a4e..c4623f50df451 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -22,11 +22,11 @@ pub type SignedPartCount = i32; /// Whether a core assignment is revokable or not. #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub enum Permanence { +pub enum Finality { /// The region remains with the same owner allowing the assignment to be altered. Provisional, /// The region is removed; the assignment may be eligible for renewal. - Permanent, + Final, } /// Self-describing identity for a Region of Bulk Coretime. From de702d0e67b7f248c5814a074039a73db25b25fc Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 13:16:16 +0100 Subject: [PATCH 034/131] Error docs --- frame/broker/README.md | 5 +-- frame/broker/src/core_part.rs | 50 +++++++++++++------------- frame/broker/src/dispatchable_impls.rs | 6 ++-- frame/broker/src/implementation.rs | 8 ++--- frame/broker/src/lib.rs | 34 ++++++++++++++++-- frame/broker/src/tests.rs | 26 +++++++------- frame/broker/src/types.rs | 10 +++--- 7 files changed, 84 insertions(+), 55 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index 9bf88fc5da10c..4f0b688bcb393 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -23,10 +23,11 @@ price fixed, unsold assigned to instapool, system cores reserved -/ ## TODO - More Events -- Tests for dropping out of date storage -- Tests for core count changes - Benchmarks - Weights - Final docs - Tests + - Tests for dropping out of date storage + - Tests for core count changes + - Tests for every error diff --git a/frame/broker/src/core_part.rs b/frame/broker/src/core_part.rs index d3d5edc2479d6..fba954871f2c9 100644 --- a/frame/broker/src/core_part.rs +++ b/frame/broker/src/core_part.rs @@ -5,8 +5,8 @@ use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. #[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct CorePart([u8; 10]); -impl CorePart { +pub struct CoreMask([u8; 10]); +impl CoreMask { pub fn void() -> Self { Self([0u8; 10]) } @@ -45,19 +45,19 @@ impl CorePart { Self(v) } } -impl From for CorePart { +impl From for CoreMask { fn from(x: u128) -> Self { let mut v = [0u8; 10]; v.iter_mut().rev().fold(x, |a, i| { *i = a as u8; a >> 8 }); Self(v) } } -impl From for u128 { - fn from(x: CorePart) -> Self { +impl From for u128 { + fn from(x: CoreMask) -> Self { x.0.into_iter().fold(0u128, |a, i| a << 8 | i as u128) } } -impl BitAnd for CorePart { +impl BitAnd for CoreMask { type Output = Self; fn bitand(self, rhs: Self) -> Self { let mut result = [0u8; 10]; @@ -67,14 +67,14 @@ impl BitAnd for CorePart { Self(result) } } -impl BitAndAssign for CorePart { +impl BitAndAssign for CoreMask { fn bitand_assign(&mut self, rhs: Self) { for i in 0..10 { self.0[i].bitand_assign(rhs.0[i]); } } } -impl BitOr for CorePart { +impl BitOr for CoreMask { type Output = Self; fn bitor(self, rhs: Self) -> Self { let mut result = [0u8; 10]; @@ -84,14 +84,14 @@ impl BitOr for CorePart { Self(result) } } -impl BitOrAssign for CorePart { +impl BitOrAssign for CoreMask { fn bitor_assign(&mut self, rhs: Self) { for i in 0..10 { self.0[i].bitor_assign(rhs.0[i]); } } } -impl BitXor for CorePart { +impl BitXor for CoreMask { type Output = Self; fn bitxor(self, rhs: Self) -> Self { let mut result = [0u8; 10]; @@ -101,14 +101,14 @@ impl BitXor for CorePart { Self(result) } } -impl BitXorAssign for CorePart { +impl BitXorAssign for CoreMask { fn bitxor_assign(&mut self, rhs: Self) { for i in 0..10 { self.0[i].bitxor_assign(rhs.0[i]); } } } -impl Not for CorePart { +impl Not for CoreMask { type Output = Self; fn not(self) -> Self { let mut result = [0u8; 10]; @@ -125,45 +125,45 @@ mod tests { #[test] fn complete_works() { - assert_eq!(CorePart::complete(), CorePart([0xff; 10])); - assert!(CorePart([0xff; 10]).is_complete()); + assert_eq!(CoreMask::complete(), CoreMask([0xff; 10])); + assert!(CoreMask([0xff; 10]).is_complete()); for i in 0..80 { - assert!(!CorePart([0xff; 10]).clear(i).is_complete()); + assert!(!CoreMask([0xff; 10]).clear(i).is_complete()); } } #[test] fn void_works() { - assert_eq!(CorePart::void(), CorePart([0; 10])); - assert!(CorePart([0; 10]).is_void()); + assert_eq!(CoreMask::void(), CoreMask([0; 10])); + assert!(CoreMask([0; 10]).is_void()); for i in 0..80 { - assert!(!(CorePart([0; 10]).set(i).is_void())); + assert!(!(CoreMask([0; 10]).set(i).is_void())); } } #[test] fn from_works() { - assert!(CorePart::from(0xfffff_fffff_fffff_fffff).is_complete()); + assert!(CoreMask::from(0xfffff_fffff_fffff_fffff).is_complete()); assert_eq!( - CorePart::from(0x12345_67890_abcde_f0123), - CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]), + CoreMask::from(0x12345_67890_abcde_f0123), + CoreMask([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]), ); } #[test] fn into_works() { - assert_eq!(u128::from(CorePart::complete()), 0xfffff_fffff_fffff_fffff); + assert_eq!(u128::from(CoreMask::complete()), 0xfffff_fffff_fffff_fffff); assert_eq!( 0x12345_67890_abcde_f0123u128, - CorePart([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]).into(), + CoreMask([0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef, 0x01, 0x23]).into(), ); } #[test] fn chunk_works() { assert_eq!( - CorePart::from_chunk(40, 60), - CorePart::from(0x00000_00000_fffff_00000), + CoreMask::from_chunk(40, 60), + CoreMask::from(0x00000_00000_fffff_00000), ); } } \ No newline at end of file diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index f81079d84bb83..e947316699444 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -193,7 +193,7 @@ impl Pallet { pub(crate) fn do_interlace( region_id: RegionId, maybe_check_owner: Option, - pivot: CorePart, + pivot: CoreMask, ) -> Result<(RegionId, RegionId), Error> { let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; @@ -202,7 +202,7 @@ impl Pallet { } ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); - ensure!(!pivot.is_void(), Error::::NullPivot); + ensure!(!pivot.is_void(), Error::::VoidPivot); ensure!(pivot != region_id.part, Error::::CompletePivot); let one = RegionId { part: pivot, ..region_id }; @@ -242,7 +242,7 @@ impl Pallet { let assigned = match AllowedRenewals::::get(region_id.core) { Some(AllowedRenewalRecord { completion: Partial(w), begin: b, price: p }) if begin == b && price == p => w, - _ => CorePart::void(), + _ => CoreMask::void(), } | region_id.part; let workload = if assigned.is_complete() { Complete(workplan) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 6ce31044bbb34..845a026d0e530 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -48,7 +48,7 @@ impl Pallet { ) -> Option<()> { let now = frame_system::Pallet::::block_number(); - let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CorePart::complete() }; + let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CoreMask::complete() }; let just_pool = Schedule::truncate_from(vec![pool_item]); // Clean up the old sale - we need to use up any unused cores by putting them into the @@ -109,7 +109,7 @@ impl Pallet { let mut leases = Leases::::get(); // Can morph to a renewable as long as it's >=begin and ::insert((region_begin, first_core), &schedule); @@ -242,7 +242,7 @@ impl Pallet { None => return, }; let workload = Workload::::get(core); - let parts_used = workplan.iter().map(|i| i.part).fold(CorePart::void(), |a, i| a | i); + let parts_used = workplan.iter().map(|i| i.part).fold(CoreMask::void(), |a, i| a | i); let mut workplan = workplan.into_inner(); workplan.extend(workload.into_iter().filter(|i| (i.part & parts_used).is_void())); let workplan = Schedule::truncate_from(workplan); @@ -283,7 +283,7 @@ impl Pallet { owner: T::AccountId, paid: Option>, ) -> RegionId { - let id = RegionId { begin, core, part: CorePart::complete() }; + let id = RegionId { begin, core, part: CoreMask::complete() }; let record = RegionRecord { end, owner, paid }; Regions::::insert(&id, &record); id diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 18c786e314f89..9beed17f6b90b 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -246,30 +246,58 @@ pub mod pallet { #[pallet::error] #[derive(PartialEq)] pub enum Error { + /// The given region identity is not known. UnknownRegion, + /// The owner of the region is not the origin. NotOwner, + /// The pivot point of the partition at or after the end of the region. PivotTooLate, + /// The pivot mask for the interlacing is not contained within the region's interlace mask. ExteriorPivot, - NullPivot, + /// The pivot mask for the interlacing is void (and therefore unschedulable). + VoidPivot, + /// The pivot mask for the interlacing is complete (and therefore not a strict subset). CompletePivot, + /// The workplan of the pallet's state is invalid. This indicates a state corruption. CorruptWorkplan, + /// There is no sale happening currently. NoSales, + /// The price for the sale could not be determined. This indicates a logic error. IndeterminablePrice, + /// The price limit is exceeded. Overpriced, + /// There are no cores available. Unavailable, + /// The sale limit has been reached. SoldOut, + /// The renewal operation is not valid at the current time (it may become valid in the next + /// sale). WrongTime, + /// Invalid attempt to renew. NotAllowed, + /// This pallet has not yet been initialized. Uninitialized, + /// The purchase cannot happen yet as the sale period is yet to begin. TooEarly, + /// There is no work to be done. NothingToDo, + /// The maximum amount of reservations has already been reached. TooManyReservations, + /// The maximum amount of leases has already been reached. TooManyLeases, + /// The revenue for the Instantaneous Core Sales of this period is already known. This + /// is unexpected and indicates a logic error. RevenueAlreadyKnown, - NoRevenue, + /// The revenue for the Instantaneous Core Sales of this period is not (yet) known and thus + /// this operation cannot proceed. UnknownRevenue, + /// The identified contribution to the Instantaneous Core Pool is unknown. UnknownContribution, + /// The recorded contributions to the Instantaneous Core Pool are invalid. This is + /// unexpected and indicates a logic error. InvalidContributions, + /// The workload assigned for renewal is incomplete. This is unexpected and indicates a + /// logic error. IncompleteAssignment, /// An item cannot be dropped because it is still valid. StillValid, @@ -362,7 +390,7 @@ pub mod pallet { pub fn interlace( origin: OriginFor, region_id: RegionId, - pivot: CorePart, + pivot: CoreMask, ) -> DispatchResult { let who = ensure_signed(origin)?; Self::do_interlace(region_id, Some(who), pivot)?; diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index bf60f018951ea..fd26b6f86f95b 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -55,7 +55,7 @@ fn permanent_is_not_reassignable() { assert_noop!(Broker::do_assign(region, Some(1), 1002, Final), Error::::UnknownRegion); assert_noop!(Broker::do_pool(region, Some(1), 1002, Final), Error::::UnknownRegion); assert_noop!(Broker::do_partition(region, Some(1), 1), Error::::UnknownRegion); - assert_noop!(Broker::do_interlace(region, Some(1), CorePart::from_chunk(0, 40)), Error::::UnknownRegion); + assert_noop!(Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)), Error::::UnknownRegion); }); } @@ -67,7 +67,7 @@ fn provisional_is_reassignable() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_assign(region, Some(1), 1001, Provisional)); let (region1, region) = Broker::do_partition(region, Some(1), 1).unwrap(); - let (region2, region3) = Broker::do_interlace(region, Some(1), CorePart::from_chunk(0, 40)).unwrap(); + let (region2, region3) = Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)).unwrap(); assert_ok!(Broker::do_pool(region1, Some(1), 1, Provisional)); assert_ok!(Broker::do_assign(region2, Some(1), 1002, Provisional)); assert_ok!(Broker::do_assign(region3, Some(1), 1003, Provisional)); @@ -94,7 +94,7 @@ fn nft_metadata_works() { assert_eq!(attribute::(region, b"length"), 3); assert_eq!(attribute::(region, b"end"), 7); assert_eq!(attribute::(region, b"owner"), 1); - assert_eq!(attribute::(region, b"part"), 0xfffff_fffff_fffff_fffff.into()); + assert_eq!(attribute::(region, b"part"), 0xfffff_fffff_fffff_fffff.into()); assert_eq!(attribute::(region, b"core"), 0); assert_eq!(attribute::>(region, b"paid"), Some(100)); @@ -105,7 +105,7 @@ fn nft_metadata_works() { assert_eq!(attribute::(region, b"length"), 1); assert_eq!(attribute::(region, b"end"), 7); assert_eq!(attribute::(region, b"owner"), 42); - assert_eq!(attribute::(region, b"part"), 0x00000_fffff_fffff_00000.into()); + assert_eq!(attribute::(region, b"part"), 0x00000_fffff_fffff_00000.into()); assert_eq!(attribute::(region, b"core"), 0); assert_eq!(attribute::>(region, b"paid"), None); }); @@ -167,7 +167,7 @@ fn renewal_works() { #[test] fn instapool_payouts_work() { TestExt::new().endow(1, 1000).execute_with(|| { - let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; + let item = ScheduleItem { assignment: Pool, part: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100, 3)); advance_to(2); @@ -188,12 +188,12 @@ fn instapool_payouts_work() { #[test] fn instapool_partial_core_payouts_work() { TestExt::new().endow(1, 1000).execute_with(|| { - let item = ScheduleItem { assignment: Pool, part: CorePart::complete() }; + let item = ScheduleItem { assignment: Pool, part: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100, 2)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); + let (region1, region2) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); assert_ok!(Broker::do_pool(region1, None, 2, Final)); assert_ok!(Broker::do_pool(region2, None, 3, Final)); assert_ok!(Broker::do_purchase_credit(1, 40, 1)); @@ -212,7 +212,7 @@ fn instapool_partial_core_payouts_work() { #[test] fn initialize_with_system_paras_works() { TestExt::new().execute_with(|| { - let item = ScheduleItem { assignment: Task(1u32), part: CorePart::complete() }; + let item = ScheduleItem { assignment: Task(1u32), part: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); let items = vec![ ScheduleItem { assignment: Task(2u32), part: 0xfffff_fffff_00000_00000.into() }, @@ -302,8 +302,8 @@ fn interlace_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 30)).unwrap(); - let (region2, region3) =Broker::do_interlace(region, None, CorePart::from_chunk(30, 60)).unwrap(); + let (region1, region) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 30)).unwrap(); + let (region2, region3) =Broker::do_interlace(region, None, CoreMask::from_chunk(30, 60)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); assert_ok!(Broker::do_assign(region2, None, 1002, Final)); assert_ok!(Broker::do_assign(region3, None, 1003, Final)); @@ -324,7 +324,7 @@ fn interlace_then_partition_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region2) = Broker::do_interlace(region, None, CorePart::from_chunk(0, 20)).unwrap(); + let (region1, region2) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); let (region1, region3) = Broker::do_partition(region1, None, 1).unwrap(); let (region2, region4) = Broker::do_partition(region2, None, 2).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); @@ -356,8 +356,8 @@ fn partition_then_interlace_works() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); - let (region1, region3) = Broker::do_interlace(region1, None, CorePart::from_chunk(0, 20)).unwrap(); - let (region2, region4) = Broker::do_interlace(region2, None, CorePart::from_chunk(0, 30)).unwrap(); + let (region1, region3) = Broker::do_interlace(region1, None, CoreMask::from_chunk(0, 20)).unwrap(); + let (region2, region4) = Broker::do_interlace(region2, None, CoreMask::from_chunk(0, 30)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); assert_ok!(Broker::do_assign(region2, None, 1002, Final)); assert_ok!(Broker::do_assign(region3, None, 1003, Final)); diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index c4623f50df451..3816ebe52c4a1 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,4 +1,4 @@ -use crate::{Config, CoretimeInterface, CoreIndex, CorePart, CoreAssignment, TaskId}; +use crate::{Config, CoretimeInterface, CoreIndex, CoreMask, CoreAssignment, TaskId}; use codec::{Encode, Decode, MaxEncodedLen}; use scale_info::TypeInfo; use frame_support::traits::fungible::Inspect; @@ -14,7 +14,7 @@ pub type RelayAccountIdOf = <::Coretime as CoretimeInterface>::A /// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. pub type Timeslice = u32; -/// Counter for the total number of set bits over every core's `CorePart`. `u32` so we don't +/// Counter for the total number of set bits over every core's `CoreMask`. `u32` so we don't /// ever get an overflow. pub type PartCount = u32; /// The same as `PartCount` but signed. @@ -37,7 +37,7 @@ pub struct RegionId { /// The index of the Polakdot Core on which this Region will be scheduled. pub core: CoreIndex, /// The regularity parts in which this Region will be scheduled. - pub part: CorePart, + pub part: CoreMask, } impl From for RegionId { fn from(x: u128) -> Self { @@ -77,7 +77,7 @@ pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf = InstaPoolHistoryRecord>; #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum CompletionStatus { /// The core is not fully assigned; the inner is the parts which have. - Partial(CorePart), + Partial(CoreMask), /// The core is fully assigned; the inner is the workload which has been assigned. Complete(Schedule), } From f86115ac02bbc91f565d77d61ac03141b55a64fb Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 14:22:07 +0100 Subject: [PATCH 035/131] Docs --- frame/broker/src/dispatchable_impls.rs | 6 +- frame/broker/src/lib.rs | 158 +++++++++++++++++++++---- 2 files changed, 139 insertions(+), 25 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index e947316699444..a06d44bbdd5db 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -360,8 +360,10 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; ensure!(status.last_timeslice > when + config.contribution_timeout, Error::::StillValid); - ensure!(InstaPoolHistory::::contains_key(when), Error::::NoHistory); - InstaPoolHistory::::remove(when); + let record = InstaPoolHistory::::take(when).ok_or(Error::::NoHistory)?; + if let Some(payout) = record.maybe_payout { + let _ = Self::charge(&Self::account_id(), payout); + } Ok(()) } } \ No newline at end of file diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 9beed17f6b90b..881c9b4ac8870 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -308,6 +308,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_now: T::BlockNumber) -> Weight { + // NOTE: This may need some clever benchmarking... let _ = Self::do_tick(); Weight::zero() } @@ -315,55 +316,107 @@ pub mod pallet { #[pallet::call(weight(::WeightInfo))] impl Pallet { + /// Configure the pallet. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `config`: The configuration for this pallet. #[pallet::call_index(0)] - pub fn configure(origin: OriginFor, config: ConfigRecordOf) -> DispatchResult { + pub fn configure( + origin: OriginFor, + config: ConfigRecordOf, + ) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_configure(config)?; - Ok(()) + Ok(Pays::No.into()) } + /// Reserve a core for a workload. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `workload`: The workload which should be permanently placed on a core. #[pallet::call_index(1)] - pub fn reserve(origin: OriginFor, schedule: Schedule) -> DispatchResult { + pub fn reserve(origin: OriginFor, workload: Schedule) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; - Self::do_reserve(schedule)?; - Ok(()) + Self::do_reserve(workload)?; + Ok(Pays::No.into()) } + /// Cancel a reserved workload. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `item_index`: The index of the reservation. #[pallet::call_index(2)] - pub fn unreserve(origin: OriginFor, item_index: u32) -> DispatchResult { + pub fn unreserve(origin: OriginFor, item_index: u32) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_unreserve(item_index)?; - Ok(()) + Ok(Pays::No.into()) } + /// Reserve a core for a single task workload for a limited period. + /// + /// In the interlude and sale period where Bulk Coretime is sold for the period immediately + /// after `until`, then the same workload may be renewed. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `task`: The workload which should be placed on a core. + /// - `until`: The timeslice now earlier than which `task` should be placed as a workload + /// on a core. #[pallet::call_index(3)] - pub fn set_lease(origin: OriginFor, task: TaskId, until: Timeslice) -> DispatchResult { + pub fn set_lease( + origin: OriginFor, + task: TaskId, + until: Timeslice, + ) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_set_lease(task, until)?; - Ok(()) + Ok(Pays::No.into()) } + /// Begin the Bulk Coretime sales rotation. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `initial_price`: The price of Bulk Coretime in the first sale. + /// - `core_count`: The number of cores which can be allocated. #[pallet::call_index(4)] - pub fn start_sales(origin: OriginFor, initial_price: BalanceOf, core_count: CoreIndex) -> DispatchResult { + pub fn start_sales( + origin: OriginFor, + initial_price: BalanceOf, + core_count: CoreIndex, + ) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_start_sales(initial_price, core_count)?; - Ok(()) + Ok(Pays::No.into()) } + /// Purchase Bulk Coretime in the ongoing Sale. + /// + /// - `origin`: Must be a Signed origin with at least enough funds to pay the current price + /// of Bulk Coretime. + /// - `price_limit`: An amount no more than which should be paid. #[pallet::call_index(5)] - pub fn purchase(origin: OriginFor, price_limit: BalanceOf) -> DispatchResult { + pub fn purchase(origin: OriginFor, price_limit: BalanceOf) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; Self::do_purchase(who, price_limit)?; - Ok(()) + Ok(Pays::No.into()) } + /// Renew Bulk Coretime in the ongoing Sale or its prior Interlude Period. + /// + /// - `origin`: Must be a Signed origin with at least enough funds to pay the renewal price + /// of the core. + /// - `core`: The core which should be renewed. #[pallet::call_index(6)] - pub fn renew(origin: OriginFor, core: CoreIndex) -> DispatchResult { + pub fn renew(origin: OriginFor, core: CoreIndex) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; Self::do_renew(who, core)?; - Ok(()) + Ok(Pays::No.into()) } + /// Transfer a Bulk Coretime Region to a new owner. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region whose ownership should change. + /// - `new_owner`: The new owner for the Region. #[pallet::call_index(7)] pub fn transfer( origin: OriginFor, @@ -375,6 +428,12 @@ pub mod pallet { Ok(()) } + /// Split a Bulk Coretime Region into two non-overlapping Regions at a particular time into + /// the region. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which should be partitioned into two non-overlapping Regions. + /// - `pivot`: The offset in time into the Region at which to make the split. #[pallet::call_index(8)] pub fn partition( origin: OriginFor, @@ -386,6 +445,14 @@ pub mod pallet { Ok(()) } + /// Split a Bulk Coretime Region into two wholly-overlapping Regions with complementary + /// interlace masks which together make up the original Region's interlace mask. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which should become two interlaced Regions of incomplete + /// regularity. + /// - `pivot`: The interlace mask of on of the two new regions (the other it its partial + /// complement). #[pallet::call_index(9)] pub fn interlace( origin: OriginFor, @@ -397,42 +464,71 @@ pub mod pallet { Ok(()) } + /// Assign a Bulk Coretime Region to a task. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which should be assigned to the task. + /// - `task`: The task to assign. + /// - `finality`: Indication of whether this assignment is final (in which case it may be + /// eligible for renewal) or provisional (in which case it may be manipulated and/or + /// reassigned at a later stage). #[pallet::call_index(10)] pub fn assign( origin: OriginFor, region_id: RegionId, - target: TaskId, + task: TaskId, finality: Finality, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - Self::do_assign(region_id, Some(who), target, finality)?; - Ok(()) + Self::do_assign(region_id, Some(who), task, finality)?; + Ok(if finality == Finality::Final { Pays::No } else { Pays::Yes }.into()) } + /// Place a Bulk Coretime Region into the Instantaneous Coretime Pool. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which should be assigned to the Pool. + /// - `payee`: The account which is able to collect any revenue due for the usage of this + /// Coretime. #[pallet::call_index(11)] pub fn pool( origin: OriginFor, region_id: RegionId, payee: T::AccountId, finality: Finality, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; Self::do_pool(region_id, Some(who), payee, finality)?; - Ok(()) + Ok(if finality == Finality::Final { Pays::No } else { Pays::Yes }.into()) } + /// Claim the revenue owed from inclusion in the Instantaneous Coretime Pool. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which was assigned to the Pool. + /// - `max_timeslices`: The maximum number of timeslices which should be processed. This may + /// effect the weight of the call but should be ideally made equivalant to the length of + /// the Region `region_id`. If it is less than this, then further dispatches will be + /// required with the `region_id` which makes up any remainders of the region to be + /// collected. #[pallet::call_index(12)] #[pallet::weight(T::WeightInfo::claim_revenue(*max_timeslices))] pub fn claim_revenue( origin: OriginFor, region_id: RegionId, max_timeslices: Timeslice, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; Self::do_claim_revenue(region_id, max_timeslices)?; - Ok(()) + Ok(Pays::No.into()) } + /// Purchase credit for use in the Instantaneous Coretime Pool. + /// + /// - `origin`: Must be a Signed origin able to pay at least `amount`. + /// - `amount`: The amount of credit to purchase. + /// - `beneficiary`: The account on the Relay-chain which controls the credit (generally + /// this will be the collator's hot wallet). #[pallet::call_index(13)] pub fn purchase_credit( origin: OriginFor, @@ -444,6 +540,10 @@ pub mod pallet { Ok(()) } + /// Drop an expired Region from the chain. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region which has expired. #[pallet::call_index(14)] pub fn drop_region( origin: OriginFor, @@ -454,6 +554,10 @@ pub mod pallet { Ok(Pays::No.into()) } + /// Drop an expired Instantaneous Pool Contribution record from the chain. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The Region identifying the Pool Contribution which has expired. #[pallet::call_index(15)] pub fn drop_contribution( origin: OriginFor, @@ -464,6 +568,10 @@ pub mod pallet { Ok(Pays::No.into()) } + /// Drop an expired Instantaneous Pool History record from the chain. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `region_id`: The time of the Pool History record which has expired. #[pallet::call_index(16)] pub fn drop_history( origin: OriginFor, @@ -474,6 +582,10 @@ pub mod pallet { Ok(Pays::No.into()) } + /// Request a change to the number of cores available for scheduling work. + /// + /// - `origin`: Must be Root or pass `AdminOrigin`. + /// - `core_count`: The desired number of cores to be made available. #[pallet::call_index(17)] pub fn request_core_count(origin: OriginFor, core_count: CoreIndex) -> DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; From 1f6cac9c6612ee1a42e5794e2e5edc01c765bd90 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 14:26:26 +0100 Subject: [PATCH 036/131] Formatting --- client/cli/src/runner.rs | 2 +- client/network/src/discovery.rs | 4 +- client/network/src/protocol_controller.rs | 8 +- .../rpc-spec-v2/src/chain_head/chain_head.rs | 3 +- .../src/chain_head/chain_head_follow.rs | 4 +- .../src/chain_head/subscription/inner.rs | 4 +- client/service/src/lib.rs | 2 +- frame/broker/src/benchmarking.rs | 6 +- frame/broker/src/core_part.rs | 20 +- frame/broker/src/coretime_interface.rs | 21 +- frame/broker/src/dispatchable_impls.rs | 108 +++--- frame/broker/src/implementation.rs | 65 ++-- frame/broker/src/lib.rs | 52 +-- frame/broker/src/mock.rs | 36 +- frame/broker/src/nonfungible_impl.rs | 6 +- frame/broker/src/test_fungibles.rs | 166 +++++---- frame/broker/src/tests.rs | 345 +++++++++++++----- frame/broker/src/types.rs | 25 +- frame/broker/src/utils.rs | 29 +- frame/contracts/src/migration/v11.rs | 4 +- frame/glutton/src/lib.rs | 4 +- frame/support/procedural/src/benchmark.rs | 8 +- .../construct_runtime/expand/outer_enums.rs | 4 +- frame/support/src/storage/mod.rs | 4 +- frame/support/src/storage/types/value.rs | 4 +- frame/support/src/traits/dispatch.rs | 6 +- .../api/proc-macro/src/runtime_metadata.rs | 12 +- primitives/api/proc-macro/src/utils.rs | 4 +- .../src/multiply_by_rational_with_rounding.rs | 2 +- primitives/arithmetic/src/fixed_point.rs | 24 +- primitives/blockchain/src/backend.rs | 4 +- primitives/core/src/ed25519.rs | 8 +- primitives/core/src/sr25519.rs | 8 +- primitives/io/src/lib.rs | 4 +- utils/wasm-builder/src/lib.rs | 4 +- 35 files changed, 619 insertions(+), 391 deletions(-) diff --git a/client/cli/src/runner.rs b/client/cli/src/runner.rs index 7b534b37192ad..1b8db03c2713b 100644 --- a/client/cli/src/runner.rs +++ b/client/cli/src/runner.rs @@ -423,7 +423,7 @@ mod tests { }, ); - let Some(output) = output else { return } ; + let Some(output) = output else { return }; let stderr = dbg!(String::from_utf8(output.stderr).unwrap()); diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index b6cb29584658f..fa611253303db 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -548,7 +548,9 @@ impl NetworkBehaviour for DiscoveryBehaviour { addresses: &[Multiaddr], effective_role: Endpoint, ) -> Result, ConnectionDenied> { - let Some(peer_id) = maybe_peer else { return Ok(Vec::new()); }; + let Some(peer_id) = maybe_peer else { + return Ok(Vec::new()) + }; let mut list = self .permanent_addresses diff --git a/client/network/src/protocol_controller.rs b/client/network/src/protocol_controller.rs index 9a77881c63320..5b421e1485d69 100644 --- a/client/network/src/protocol_controller.rs +++ b/client/network/src/protocol_controller.rs @@ -658,9 +658,7 @@ impl ProtocolController { /// disconnected, `Ok(false)` if it wasn't found, `Err(PeerId)`, if the peer found, but not in /// connected state. fn drop_reserved_peer(&mut self, peer_id: &PeerId) -> Result { - let Some(state) = self.reserved_nodes.get_mut(peer_id) else { - return Ok(false) - }; + let Some(state) = self.reserved_nodes.get_mut(peer_id) else { return Ok(false) }; if let PeerState::Connected(direction) = state { trace!( @@ -678,9 +676,7 @@ impl ProtocolController { /// Try dropping the peer as a regular peer. Return `true` if the peer was found and /// disconnected, `false` if it wasn't found. fn drop_regular_peer(&mut self, peer_id: &PeerId) -> bool { - let Some(direction) = self.nodes.remove(peer_id) else { - return false - }; + let Some(direction) = self.nodes.remove(peer_id) else { return false }; trace!( target: LOG_TARGET, diff --git a/client/rpc-spec-v2/src/chain_head/chain_head.rs b/client/rpc-spec-v2/src/chain_head/chain_head.rs index 0f2d55f100929..0884646196021 100644 --- a/client/rpc-spec-v2/src/chain_head/chain_head.rs +++ b/client/rpc-spec-v2/src/chain_head/chain_head.rs @@ -162,7 +162,8 @@ where }, }; // Keep track of the subscription. - let Some(rx_stop) = self.subscriptions.insert_subscription(sub_id.clone(), with_runtime) else { + let Some(rx_stop) = self.subscriptions.insert_subscription(sub_id.clone(), with_runtime) + else { // Inserting the subscription can only fail if the JsonRPSee // generated a duplicate subscription ID. debug!(target: LOG_TARGET, "[follow][id={:?}] Subscription already accepted", sub_id); diff --git a/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs b/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs index cb6af8bd590b3..799978be532ae 100644 --- a/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs +++ b/client/rpc-spec-v2/src/chain_head/chain_head_follow.rs @@ -339,9 +339,7 @@ where let mut events = Vec::new(); // Nothing to be done if no finalized hashes are provided. - let Some(first_hash) = finalized_block_hashes.get(0) else { - return Ok(Default::default()) - }; + let Some(first_hash) = finalized_block_hashes.get(0) else { return Ok(Default::default()) }; // Find the parent header. let Some(first_header) = self.client.header(*first_hash)? else { diff --git a/client/rpc-spec-v2/src/chain_head/subscription/inner.rs b/client/rpc-spec-v2/src/chain_head/subscription/inner.rs index bdb14e8de7172..ba7f117f4fccd 100644 --- a/client/rpc-spec-v2/src/chain_head/subscription/inner.rs +++ b/client/rpc-spec-v2/src/chain_head/subscription/inner.rs @@ -328,9 +328,7 @@ impl> SubscriptionsInner { /// Remove the subscription ID with associated pinned blocks. pub fn remove_subscription(&mut self, sub_id: &str) { - let Some(mut sub) = self.subs.remove(sub_id) else { - return - }; + let Some(mut sub) = self.subs.remove(sub_id) else { return }; // The `Stop` event can be generated only once. sub.stop(); diff --git a/client/service/src/lib.rs b/client/service/src/lib.rs index 4a896ecc87263..e3feb45ee9fbc 100644 --- a/client/service/src/lib.rs +++ b/client/service/src/lib.rs @@ -237,7 +237,7 @@ pub async fn build_system_rpc_future< // Answer incoming RPC requests. let Some(req) = rpc_rx.next().await else { debug!("RPC requests stream has terminated, shutting down the system RPC future."); - return; + return }; match req { diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 9dcc6714eb65d..d0d33d8dee59e 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -42,9 +42,5 @@ mod benches { // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. - impl_benchmark_test_suite!( - Pallet, - crate::mock::new_test_ext(), - crate::mock::Test - ); + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); } diff --git a/frame/broker/src/core_part.rs b/frame/broker/src/core_part.rs index fba954871f2c9..21a39fe24022b 100644 --- a/frame/broker/src/core_part.rs +++ b/frame/broker/src/core_part.rs @@ -1,10 +1,12 @@ -use codec::{Encode, Decode, MaxEncodedLen}; +use codec::{Decode, Encode, MaxEncodedLen}; +use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; use scale_info::TypeInfo; use sp_core::RuntimeDebug; -use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. -#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive( + Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] pub struct CoreMask([u8; 10]); impl CoreMask { pub fn void() -> Self { @@ -48,7 +50,10 @@ impl CoreMask { impl From for CoreMask { fn from(x: u128) -> Self { let mut v = [0u8; 10]; - v.iter_mut().rev().fold(x, |a, i| { *i = a as u8; a >> 8 }); + v.iter_mut().rev().fold(x, |a, i| { + *i = a as u8; + a >> 8 + }); Self(v) } } @@ -161,9 +166,6 @@ mod tests { #[test] fn chunk_works() { - assert_eq!( - CoreMask::from_chunk(40, 60), - CoreMask::from(0x00000_00000_fffff_00000), - ); + assert_eq!(CoreMask::from_chunk(40, 60), CoreMask::from(0x00000_00000_fffff_00000),); } -} \ No newline at end of file +} diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 96a379e86ca08..e2bc7c3a24c57 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -1,4 +1,4 @@ -use codec::{Encode, MaxEncodedLen, Decode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::Parameter; use scale_info::TypeInfo; use sp_arithmetic::traits::AtLeast32BitUnsigned; @@ -14,7 +14,9 @@ pub type TaskId = u32; pub type PartsOf57600 = u16; /// An element to which a core can be assigned. -#[derive(Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive( + Encode, Decode, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] pub enum CoreAssignment { /// Core need not be used for anything. Idle, @@ -45,7 +47,9 @@ impl CoretimeInterface for () { type AccountId = (); type Balance = u64; type BlockNumber = u32; - fn latest() -> Self::BlockNumber { 0 } + fn latest() -> Self::BlockNumber { + 0 + } fn request_core_count(_count: CoreIndex) {} fn request_revenue_info_at(_when: Self::BlockNumber) {} fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} @@ -54,7 +58,12 @@ impl CoretimeInterface for () { _begin: Self::BlockNumber, _assignment: Vec<(CoreAssignment, PartsOf57600)>, _end_hint: Option, - ) {} - fn check_notify_core_count() -> Option { None } - fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } + ) { + } + fn check_notify_core_count() -> Option { + None + } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { + None + } } diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index a06d44bbdd5db..1e7e6cb4bde73 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -1,14 +1,11 @@ use super::*; -use CompletionStatus::{Complete, Partial}; -use sp_runtime::traits::Convert; use frame_support::{ - pallet_prelude::{*, DispatchResult}, - traits::{ - tokens::Preservation::Expendable, - fungible::Mutate, DefensiveResult, - } + pallet_prelude::{DispatchResult, *}, + traits::{fungible::Mutate, tokens::Preservation::Expendable, DefensiveResult}, }; -use sp_arithmetic::traits::{Zero, Saturating}; +use sp_arithmetic::traits::{Saturating, Zero}; +use sp_runtime::traits::Convert; +use CompletionStatus::{Complete, Partial}; impl Pallet { pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { @@ -16,9 +13,7 @@ impl Pallet { Ok(()) } - pub(crate) fn do_request_core_count( - core_count: CoreIndex, - ) -> DispatchResult { + pub(crate) fn do_request_core_count(core_count: CoreIndex) -> DispatchResult { T::Coretime::request_core_count(core_count); Ok(()) } @@ -109,7 +104,8 @@ impl Pallet { let status = Status::::get().ok_or(Error::::Uninitialized)?; let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; + let workload = + record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; ensure!(record.begin == sale.region_begin, Error::::WrongTime); ensure!(sale.first_core < status.core_count, Error::::Unavailable); @@ -162,7 +158,12 @@ impl Pallet { region.owner = new_owner; Regions::::insert(®ion_id, ®ion); let duration = region.end.saturating_sub(region_id.begin); - Self::deposit_event(Event::Transferred { region_id, old_owner, owner: region.owner, duration }); + Self::deposit_event(Event::Transferred { + region_id, + old_owner, + owner: region.owner, + duration, + }); Ok(()) } @@ -224,14 +225,16 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, finality)? { let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); + let mut workplan = Workplan::::get(&workplan_key).unwrap_or_default(); // Ensure no previous allocations exist. workplan.retain(|i| (i.part & region_id.part).is_void()); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Task(target), - }).is_ok() { + if workplan + .try_push(ScheduleItem { + part: region_id.part, + assignment: CoreAssignment::Task(target), + }) + .is_ok() + { Workplan::::insert(&workplan_key, &workplan); } @@ -240,19 +243,24 @@ impl Pallet { if let Some(price) = region.paid { let begin = region.end; let assigned = match AllowedRenewals::::get(region_id.core) { - Some(AllowedRenewalRecord { completion: Partial(w), begin: b, price: p }) - if begin == b && price == p => w, + Some(AllowedRenewalRecord { + completion: Partial(w), + begin: b, + price: p, + }) if begin == b && price == p => w, _ => CoreMask::void(), } | region_id.part; - let workload = if assigned.is_complete() { - Complete(workplan) - } else { - Partial(assigned) - }; + let workload = + if assigned.is_complete() { Complete(workplan) } else { Partial(assigned) }; let record = AllowedRenewalRecord { begin, price, completion: workload }; AllowedRenewals::::insert(region_id.core, &record); if let Some(workload) = record.completion.drain_complete() { - Self::deposit_event(Event::Renewable { core: region_id.core, price, begin, workload }); + Self::deposit_event(Event::Renewable { + core: region_id.core, + price, + begin, + workload, + }); } } } @@ -269,13 +277,12 @@ impl Pallet { ) -> Result<(), Error> { if let Some((region_id, region)) = Self::utilize(region_id, maybe_check_owner, finality)? { let workplan_key = (region_id.begin, region_id.core); - let mut workplan = Workplan::::get(&workplan_key) - .unwrap_or_default(); + let mut workplan = Workplan::::get(&workplan_key).unwrap_or_default(); let duration = region.end.saturating_sub(region_id.begin); - if workplan.try_push(ScheduleItem { - part: region_id.part, - assignment: CoreAssignment::Pool, - }).is_ok() { + if workplan + .try_push(ScheduleItem { part: region_id.part, assignment: CoreAssignment::Pool }) + .is_ok() + { Workplan::::insert(&workplan_key, &workplan); let size = region_id.part.count_ones() as i32; InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); @@ -290,20 +297,31 @@ impl Pallet { } // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. - pub(crate) fn do_claim_revenue(mut region: RegionId, max_timeslices: Timeslice) -> DispatchResult { - let mut contribution = InstaPoolContribution::::take(region) - .ok_or(Error::::UnknownContribution)?; + pub(crate) fn do_claim_revenue( + mut region: RegionId, + max_timeslices: Timeslice, + ) -> DispatchResult { + let mut contribution = + InstaPoolContribution::::take(region).ok_or(Error::::UnknownContribution)?; let contributed_parts = region.part.count_ones(); let mut payout = BalanceOf::::zero(); let last = region.begin + contribution.length.min(max_timeslices); for r in region.begin..last { - let mut pool_record = match InstaPoolHistory::::get(r) { Some(x) => x, None => continue }; - let total_payout = match pool_record.maybe_payout { Some(x) => x, None => break }; + let mut pool_record = match InstaPoolHistory::::get(r) { + Some(x) => x, + None => continue, + }; + let total_payout = match pool_record.maybe_payout { + Some(x) => x, + None => break, + }; region.begin = r; contribution.length.saturating_dec(); - payout.saturating_accrue(total_payout.saturating_mul(contributed_parts.into()) - / pool_record.total_contributions.into()); + payout.saturating_accrue( + total_payout.saturating_mul(contributed_parts.into()) / + pool_record.total_contributions.into(), + ); pool_record.total_contributions.saturating_reduce(contributed_parts); let remaining_payout = total_payout.saturating_sub(payout); @@ -313,12 +331,13 @@ impl Pallet { } else { InstaPoolHistory::::remove(region.begin); } - }; + } if contribution.length > 0 { InstaPoolContribution::::insert(region, &contribution); } - T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable).defensive_ok(); + T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable) + .defensive_ok(); Ok(()) } @@ -349,7 +368,8 @@ impl Pallet { pub(crate) fn do_drop_contribution(region_id: RegionId) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; - let contrib = InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + let contrib = + InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownRegion)?; let end = region_id.begin.saturating_add(contrib.length); ensure!(status.last_timeslice > end + config.contribution_timeout, Error::::StillValid); InstaPoolContribution::::remove(region_id); @@ -366,4 +386,4 @@ impl Pallet { } Ok(()) } -} \ No newline at end of file +} diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 845a026d0e530..85c4ec2b7c099 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -1,14 +1,18 @@ use super::*; -use CompletionStatus::Complete; -use sp_runtime::traits::{ConvertBack, AccountIdConversion}; use frame_support::{ - pallet_prelude::{*, DispatchResult}, + pallet_prelude::{DispatchResult, *}, traits::{ - tokens::{Precision::Exact, Preservation::Expendable, Fortitude::Polite}, - fungible::Balanced, OnUnbalanced, - } + fungible::Balanced, + tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, + OnUnbalanced, + }, }; -use sp_arithmetic::{traits::{Zero, SaturatedConversion, Saturating}, FixedPointNumber}; +use sp_arithmetic::{ + traits::{SaturatedConversion, Saturating, Zero}, + FixedPointNumber, +}; +use sp_runtime::traits::{AccountIdConversion, ConvertBack}; +use CompletionStatus::Complete; impl Pallet { /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is @@ -19,7 +23,9 @@ impl Pallet { ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); status.last_timeslice.saturating_inc(); - T::Coretime::request_revenue_info_at(T::TimeslicePeriod::get() * status.last_timeslice.into()); + T::Coretime::request_revenue_info_at( + T::TimeslicePeriod::get() * status.last_timeslice.into(), + ); let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let commit_timeslice = status.last_timeslice + config.advance_notice; @@ -48,7 +54,8 @@ impl Pallet { ) -> Option<()> { let now = frame_system::Pallet::::block_number(); - let pool_item = ScheduleItem { assignment: CoreAssignment::Pool, part: CoreMask::complete() }; + let pool_item = + ScheduleItem { assignment: CoreAssignment::Pool, part: CoreMask::complete() }; let just_pool = Schedule::truncate_from(vec![pool_item]); // Clean up the old sale - we need to use up any unused cores by putting them into the @@ -88,7 +95,8 @@ impl Pallet { let mut first_core = 0; let mut total_pooled: SignedPartCount = 0; for schedule in Reservations::::get().into_iter() { - let parts: u32 = schedule.iter() + let parts: u32 = schedule + .iter() .filter(|i| matches!(i.assignment, CoreAssignment::Pool)) .map(|i| i.part.count_ones()) .sum(); @@ -178,14 +186,19 @@ impl Pallet { } let mut pool_record = InstaPoolHistory::::get(timeslice).unwrap_or_default(); ensure!(pool_record.maybe_payout.is_none(), Error::::RevenueAlreadyKnown); - ensure!(pool_record.total_contributions >= pool_record.system_contributions, Error::::InvalidContributions); + ensure!( + pool_record.total_contributions >= pool_record.system_contributions, + Error::::InvalidContributions + ); ensure!(pool_record.total_contributions > 0, Error::::InvalidContributions); // Payout system InstaPool Cores. - let system_payout = amount.saturating_mul(pool_record.system_contributions.into()) - / pool_record.total_contributions.into(); + let system_payout = amount.saturating_mul(pool_record.system_contributions.into()) / + pool_record.total_contributions.into(); let _ = Self::charge(&Self::account_id(), system_payout); - pool_record.total_contributions.saturating_reduce(pool_record.system_contributions); + pool_record + .total_contributions + .saturating_reduce(pool_record.system_contributions); pool_record.system_contributions = 0; amount.saturating_reduce(system_payout); @@ -211,7 +224,11 @@ impl Pallet { (latest / timeslice_period).saturated_into() } - pub(crate) fn process_timeslice(timeslice: Timeslice, status: &mut StatusRecord, _config: &ConfigRecordOf) { + pub(crate) fn process_timeslice( + timeslice: Timeslice, + status: &mut StatusRecord, + _config: &ConfigRecordOf, + ) { Self::process_pool(timeslice, status); let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); for core in 0..status.core_count { @@ -222,7 +239,8 @@ impl Pallet { fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); status.pool_size = (status.pool_size as i32).saturating_add(pool_io.total) as u32; - status.system_pool_size = (status.system_pool_size as i32).saturating_add(pool_io.system) as u32; + status.system_pool_size = + (status.system_pool_size as i32).saturating_add(pool_io.system) as u32; let record = InstaPoolHistoryRecord { total_contributions: status.pool_size, system_contributions: status.system_pool_size, @@ -258,12 +276,13 @@ impl Pallet { intermediate.push((CoreAssignment::Idle, 80 - total_used)); } intermediate.sort(); - let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = Vec::with_capacity(intermediate.len()); + let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = + Vec::with_capacity(intermediate.len()); for i in intermediate.into_iter() { if let Some(ref mut last) = assignment.last_mut() { if last.0 == i.0 { last.1 += i.1; - continue; + continue } } assignment.push(i); @@ -272,7 +291,9 @@ impl Pallet { } pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { - T::OnRevenue::on_unbalanced(T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?); + T::OnRevenue::on_unbalanced(T::Currency::withdraw( + &who, amount, Exact, Expendable, Polite, + )?); Ok(()) } @@ -313,9 +334,9 @@ impl Pallet { return Ok(None) } } else { - Workplan::::mutate_extant((region_id.begin, region_id.core), |p| + Workplan::::mutate_extant((region_id.begin, region_id.core), |p| { p.retain(|i| (i.part & region_id.part).is_void()) - ); + }); } if finality == Finality::Provisional { Regions::::insert(®ion_id, ®ion); @@ -323,4 +344,4 @@ impl Pallet { Ok(Some((region_id, region))) } -} \ No newline at end of file +} diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 881c9b4ac8870..e3a612801c859 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -20,18 +20,18 @@ pub use pallet::*; -mod mock; -mod tests; +mod adapt_price; mod benchmarking; -mod test_fungibles; mod core_part; -mod types; mod coretime_interface; -mod utils; -mod implementation; mod dispatchable_impls; +mod implementation; +mod mock; mod nonfungible_impl; -mod adapt_price; +mod test_fungibles; +mod tests; +mod types; +mod utils; pub mod weights; pub use weights::WeightInfo; @@ -47,12 +47,15 @@ pub use utils::*; pub mod pallet { use super::*; use frame_support::{ - pallet_prelude::{*, DispatchResult, DispatchResultWithPostInfo}, - traits::{fungible::{Credit, Mutate, Balanced}, OnUnbalanced, EnsureOrigin}, + pallet_prelude::{DispatchResult, DispatchResultWithPostInfo, *}, + traits::{ + fungible::{Balanced, Credit, Mutate}, + EnsureOrigin, OnUnbalanced, + }, PalletId, }; use frame_system::pallet_prelude::*; - use sp_runtime::traits::{ConvertBack, Convert}; + use sp_runtime::traits::{Convert, ConvertBack}; #[pallet::pallet] pub struct Pallet(_); @@ -82,7 +85,8 @@ pub mod pallet { /// Reversible conversion from local balance to Relay-chain balance. This will typically be /// the `Identity`, but provided just in case the chains use different representations. - type ConvertBalance: Convert, RelayBalanceOf> + ConvertBack, RelayBalanceOf>; + type ConvertBalance: Convert, RelayBalanceOf> + + ConvertBack, RelayBalanceOf>; /// Identifier from which the internal Pot is generated. #[pallet::constant] @@ -123,7 +127,8 @@ pub mod pallet { /// Records of allowed renewals. #[pallet::storage] - pub type AllowedRenewals = StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; + pub type AllowedRenewals = + StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; /// The current (unassigned) Regions. #[pallet::storage] @@ -131,7 +136,8 @@ pub mod pallet { /// The work we plan on having each core do at a particular time in the future. #[pallet::storage] - pub type Workplan = StorageMap<_, Twox64Concat, (Timeslice, CoreIndex), Schedule, OptionQuery>; + pub type Workplan = + StorageMap<_, Twox64Concat, (Timeslice, CoreIndex), Schedule, OptionQuery>; /// The current workload of each core. This gets updated with workplan as timeslices pass. #[pallet::storage] @@ -139,7 +145,8 @@ pub mod pallet { /// Record of a single contribution to the Instantaneous Coretime Pool. #[pallet::storage] - pub type InstaPoolContribution = StorageMap<_, Blake2_128Concat, RegionId, ContributionRecordOf, OptionQuery>; + pub type InstaPoolContribution = + StorageMap<_, Blake2_128Concat, RegionId, ContributionRecordOf, OptionQuery>; /// Record of Coretime entering or leaving the Instantaneous Coretime Pool. #[pallet::storage] @@ -147,7 +154,8 @@ pub mod pallet { /// Total InstaPool rewards for each Timeslice and the number of core parts which contributed. #[pallet::storage] - pub type InstaPoolHistory = StorageMap<_, Blake2_128Concat, Timeslice, InstaPoolHistoryRecordOf>; + pub type InstaPoolHistory = + StorageMap<_, Blake2_128Concat, Timeslice, InstaPoolHistoryRecordOf>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -359,8 +367,8 @@ pub mod pallet { /// /// - `origin`: Must be Root or pass `AdminOrigin`. /// - `task`: The workload which should be placed on a core. - /// - `until`: The timeslice now earlier than which `task` should be placed as a workload - /// on a core. + /// - `until`: The timeslice now earlier than which `task` should be placed as a workload on + /// a core. #[pallet::call_index(3)] pub fn set_lease( origin: OriginFor, @@ -394,7 +402,10 @@ pub mod pallet { /// of Bulk Coretime. /// - `price_limit`: An amount no more than which should be paid. #[pallet::call_index(5)] - pub fn purchase(origin: OriginFor, price_limit: BalanceOf) -> DispatchResultWithPostInfo { + pub fn purchase( + origin: OriginFor, + price_limit: BalanceOf, + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; Self::do_purchase(who, price_limit)?; Ok(Pays::No.into()) @@ -573,10 +584,7 @@ pub mod pallet { /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. /// - `region_id`: The time of the Pool History record which has expired. #[pallet::call_index(16)] - pub fn drop_history( - origin: OriginFor, - when: Timeslice, - ) -> DispatchResultWithPostInfo { + pub fn drop_history(origin: OriginFor, when: Timeslice) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; Self::do_drop_history(when)?; Ok(Pays::No.into()) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 85ce724a3b2e1..a99c3ea16fc65 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -17,17 +17,24 @@ #![cfg(test)] -use crate::*; +use crate::{test_fungibles::TestFungibles, *}; +use frame_support::{ + assert_ok, ensure, parameter_types, + traits::{ + fungible::{Balanced, Credit, Inspect, ItemOf, Mutate}, + nonfungible::Inspect as NftInspect, + Hooks, OnUnbalanced, + }, + PalletId, +}; use frame_system::EnsureNever; -use sp_std::collections::btree_map::BTreeMap; -use frame_support::{parameter_types, traits::{Hooks, nonfungible::{Inspect as NftInspect}, fungible::{ItemOf, Mutate, Inspect, Credit, Balanced}, OnUnbalanced}, assert_ok, PalletId, ensure}; use sp_arithmetic::Perbill; -use sp_core::{H256, ConstU64, ConstU16, ConstU32}; +use sp_core::{ConstU16, ConstU32, ConstU64, H256}; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup, Identity}, + traits::{BlakeTwo256, Identity, IdentityLookup}, }; -use crate::test_fungibles::TestFungibles; +use sp_std::collections::btree_map::BTreeMap; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -82,7 +89,7 @@ pub enum CoretimeTraceItem { } use CoretimeTraceItem::*; -parameter_types!{ +parameter_types! { pub static CoretimeTrace: Vec<(u32, CoretimeTraceItem)> = Default::default(); pub static CoretimeCredit: BTreeMap = Default::default(); pub static CoretimeSpending: Vec<(u32, u64)> = Default::default(); @@ -98,13 +105,24 @@ impl CoretimeInterface for TestCoretimeProvider { type AccountId = u64; type Balance = u64; type BlockNumber = u32; - fn latest() -> Self::BlockNumber { System::block_number() as u32 } + fn latest() -> Self::BlockNumber { + System::block_number() as u32 + } fn request_core_count(count: CoreIndex) { NotifyCoreCount::mutate(|s| s.insert(0, count)); } fn request_revenue_info_at(when: Self::BlockNumber) { let mut total = 0; - CoretimeSpending::mutate(|s| s.retain(|(n, a)| if *n < when { total += a; false } else { true })); + CoretimeSpending::mutate(|s| { + s.retain(|(n, a)| { + if *n < when { + total += a; + false + } else { + true + } + }) + }); NotifyRevenueInfo::mutate(|s| s.insert(0, (when, total))); } fn credit_account(who: Self::AccountId, amount: Self::Balance) { diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index a41d3e3443320..e4537a6da5684 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -1,9 +1,7 @@ use super::*; use frame_support::{ - pallet_prelude::{*, DispatchResult}, - traits::{ - nonfungible::{Inspect, Transfer}, - } + pallet_prelude::{DispatchResult, *}, + traits::nonfungible::{Inspect, Transfer}, }; impl Inspect for Pallet { diff --git a/frame/broker/src/test_fungibles.rs b/frame/broker/src/test_fungibles.rs index 84c149b99d971..f6ac5a49dedd2 100644 --- a/frame/broker/src/test_fungibles.rs +++ b/frame/broker/src/test_fungibles.rs @@ -15,16 +15,21 @@ // See the License for the specific language governing permissions and // limitations under the License. +use codec::{Decode, Encode}; use frame_support::{ parameter_types, - traits::{fungibles::{self, Dust}, tokens::{self, Preservation, Fortitude, Provenance, DepositConsequence, WithdrawConsequence}} + traits::{ + fungibles::{self, Dust}, + tokens::{ + self, DepositConsequence, Fortitude, Preservation, Provenance, WithdrawConsequence, + }, + }, }; use scale_info::TypeInfo; use sp_arithmetic::traits::Zero; +use sp_core::{Get, TypedGet}; use sp_runtime::{DispatchError, DispatchResult}; use sp_std::collections::btree_map::BTreeMap; -use codec::{Encode, Decode}; -use sp_core::{TypedGet, Get}; parameter_types! { static TestAssetOf: BTreeMap<(u32, Vec), Vec> = Default::default(); @@ -33,15 +38,16 @@ parameter_types! { } pub struct TestFungibles( - core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance, HoldReason)> + core::marker::PhantomData<(Instance, AccountId, AssetId, MinimumBalance, HoldReason)>, ); impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason, -> fungibles::Inspect for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, + > fungibles::Inspect + for TestFungibles where MinimumBalance::Type: tokens::Balance, { @@ -49,9 +55,10 @@ where type Balance = MinimumBalance::Type; fn total_issuance(asset: Self::AssetId) -> Self::Balance { - TestAssetOf::get().get(&(Instance::get(), asset.encode())) - .and_then(|data| Decode::decode(&mut &data[..]).ok()) - .unwrap_or_default() + TestAssetOf::get() + .get(&(Instance::get(), asset.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() } fn active_issuance(asset: Self::AssetId) -> Self::Balance { @@ -64,9 +71,10 @@ where } fn total_balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { - TestBalanceOf::get().get(&(Instance::get(), asset.encode(), who.encode())) - .and_then(|data| Decode::decode(&mut &data[..]).ok()) - .unwrap_or_default() + TestBalanceOf::get() + .get(&(Instance::get(), asset.encode(), who.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() } fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance { @@ -89,10 +97,10 @@ where _provenance: Provenance, ) -> DepositConsequence { if !Self::asset_exists(asset) { - return DepositConsequence::UnknownAsset; + return DepositConsequence::UnknownAsset } if amount + Self::balance(asset, who) < Self::minimum_balance(asset) { - return DepositConsequence::BelowMinimum; + return DepositConsequence::BelowMinimum } DepositConsequence::Success } @@ -102,11 +110,12 @@ where who: &AccountId, amount: Self::Balance, ) -> WithdrawConsequence { - if Self::reducible_balance(asset, who, Preservation::Expendable, Fortitude::Polite) < amount { - return WithdrawConsequence::BalanceLow; + if Self::reducible_balance(asset, who, Preservation::Expendable, Fortitude::Polite) < amount + { + return WithdrawConsequence::BalanceLow } if Self::total_balance(asset, who) < Self::minimum_balance(asset) + amount { - return WithdrawConsequence::WouldDie; + return WithdrawConsequence::WouldDie } WithdrawConsequence::Success } @@ -117,12 +126,13 @@ where } impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason, -> fungibles::Unbalanced for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, + > fungibles::Unbalanced + for TestFungibles where MinimumBalance::Type: tokens::Balance, { @@ -157,23 +167,26 @@ where } impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason, -> fungibles::Mutate for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, + > fungibles::Mutate + for TestFungibles where MinimumBalance::Type: tokens::Balance, -{} +{ +} impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason, -> fungibles::Balanced for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason, + > fungibles::Balanced + for TestFungibles where MinimumBalance::Type: tokens::Balance, { @@ -182,12 +195,13 @@ where } impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason: Encode + Decode + TypeInfo + 'static, -> fungibles::InspectHold for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, + > fungibles::InspectHold + for TestFungibles where MinimumBalance::Type: tokens::Balance, { @@ -196,7 +210,8 @@ where fn total_balance_on_hold(asset: Self::AssetId, who: &AccountId) -> Self::Balance { let asset = asset.encode(); let who = who.encode(); - TestHoldOf::get().iter() + TestHoldOf::get() + .iter() .filter(|(k, _)| k.0 == Instance::get() && k.1 == asset && k.2 == who) .filter_map(|(_, b)| Self::Balance::decode(&mut &b[..]).ok()) .fold(Zero::zero(), |a, i| a + i) @@ -207,19 +222,21 @@ where reason: &Self::Reason, who: &AccountId, ) -> Self::Balance { - TestHoldOf::get().get(&(Instance::get(), asset.encode(), who.encode(), reason.encode())) - .and_then(|data| Decode::decode(&mut &data[..]).ok()) - .unwrap_or_default() + TestHoldOf::get() + .get(&(Instance::get(), asset.encode(), who.encode(), reason.encode())) + .and_then(|data| Decode::decode(&mut &data[..]).ok()) + .unwrap_or_default() } } impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason: Encode + Decode + TypeInfo + 'static, -> fungibles::UnbalancedHold for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, + > fungibles::UnbalancedHold + for TestFungibles where MinimumBalance::Type: tokens::Balance, { @@ -230,30 +247,37 @@ where amount: Self::Balance, ) -> DispatchResult { let mut th = TestHoldOf::get(); - th.insert((Instance::get(), asset.encode(), who.encode(), reason.encode()), amount.encode()); + th.insert( + (Instance::get(), asset.encode(), who.encode(), reason.encode()), + amount.encode(), + ); TestHoldOf::set(th); Ok(()) } } impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason: Encode + Decode + TypeInfo + 'static, -> fungibles::MutateHold for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, + > fungibles::MutateHold + for TestFungibles where MinimumBalance::Type: tokens::Balance, -{} +{ +} impl< - Instance: Get, - AccountId: Encode, - AssetId: tokens::AssetId + Copy, - MinimumBalance: TypedGet, - HoldReason: Encode + Decode + TypeInfo + 'static, -> fungibles::BalancedHold for TestFungibles + Instance: Get, + AccountId: Encode, + AssetId: tokens::AssetId + Copy, + MinimumBalance: TypedGet, + HoldReason: Encode + Decode + TypeInfo + 'static, + > fungibles::BalancedHold + for TestFungibles where MinimumBalance::Type: tokens::Balance, -{} \ No newline at end of file +{ +} diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index fd26b6f86f95b..0126c4160ece9 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,8 +17,11 @@ #![cfg(test)] -use crate::{*, mock::*, core_part::*}; -use frame_support::{assert_noop, assert_ok, traits::nonfungible::{Transfer, Inspect as NftInspect}}; +use crate::{core_part::*, mock::*, *}; +use frame_support::{ + assert_noop, assert_ok, + traits::nonfungible::{Inspect as NftInspect, Transfer}, +}; use CoreAssignment::*; use CoretimeTraceItem::*; use Finality::*; @@ -55,7 +58,10 @@ fn permanent_is_not_reassignable() { assert_noop!(Broker::do_assign(region, Some(1), 1002, Final), Error::::UnknownRegion); assert_noop!(Broker::do_pool(region, Some(1), 1002, Final), Error::::UnknownRegion); assert_noop!(Broker::do_partition(region, Some(1), 1), Error::::UnknownRegion); - assert_noop!(Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)), Error::::UnknownRegion); + assert_noop!( + Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)), + Error::::UnknownRegion + ); }); } @@ -67,20 +73,35 @@ fn provisional_is_reassignable() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_assign(region, Some(1), 1001, Provisional)); let (region1, region) = Broker::do_partition(region, Some(1), 1).unwrap(); - let (region2, region3) = Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)).unwrap(); + let (region2, region3) = + Broker::do_interlace(region, Some(1), CoreMask::from_chunk(0, 40)).unwrap(); assert_ok!(Broker::do_pool(region1, Some(1), 1, Provisional)); assert_ok!(Broker::do_assign(region2, Some(1), 1002, Provisional)); assert_ok!(Broker::do_assign(region3, Some(1), 1003, Provisional)); advance_to(8); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Pool, 57600), - ], end_hint: None }), - (8, AssignCore { core: 0, begin: 10, assignment: vec![ - (Task(1002), 28800), - (Task(1003), 28800), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Pool, 57600),], + end_hint: None + } + ), + ( + 8, + AssignCore { + core: 0, + begin: 10, + assignment: vec![(Task(1002), 28800), (Task(1003), 28800),], + end_hint: None + } + ), + ] + ); }); } @@ -100,7 +121,8 @@ fn nft_metadata_works() { assert_ok!(Broker::do_transfer(region, None, 42)); let (_, region) = Broker::do_partition(region, None, 2).unwrap(); - let (region, _) = Broker::do_interlace(region, None, 0x00000_fffff_fffff_00000.into()).unwrap(); + let (region, _) = + Broker::do_interlace(region, None, 0x00000_fffff_fffff_00000.into()).unwrap(); assert_eq!(attribute::(region, b"begin"), 6); assert_eq!(attribute::(region, b"length"), 1); assert_eq!(attribute::(region, b"end"), 7); @@ -129,17 +151,38 @@ fn migration_works() { assert_eq!(balance(1), 900); advance_to(18); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1000), 57600), - ], end_hint: None }), - (12, AssignCore { core: 0, begin: 14, assignment: vec![ - (Task(1000), 57600), - ], end_hint: None }), - (18, AssignCore { core: 0, begin: 20, assignment: vec![ - (Task(1000), 57600), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1000), 57600),], + end_hint: None + } + ), + ( + 12, + AssignCore { + core: 0, + begin: 14, + assignment: vec![(Task(1000), 57600),], + end_hint: None + } + ), + ( + 18, + AssignCore { + core: 0, + begin: 20, + assignment: vec![(Task(1000), 57600),], + end_hint: None + } + ), + ] + ); }); } @@ -193,7 +236,8 @@ fn instapool_partial_core_payouts_work() { assert_ok!(Broker::do_start_sales(100, 2)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region2) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); + let (region1, region2) = + Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); assert_ok!(Broker::do_pool(region1, None, 2, Final)); assert_ok!(Broker::do_pool(region2, None, 3, Final)); assert_ok!(Broker::do_purchase_credit(1, 40, 1)); @@ -222,16 +266,29 @@ fn initialize_with_system_paras_works() { assert_ok!(Broker::do_reserve(Schedule::truncate_from(items))); assert_ok!(Broker::do_start_sales(100, 2)); advance_to(10); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1), 57600), - ], end_hint: None }), - (6, AssignCore { core: 1, begin: 8, assignment: vec![ - (Task(2), 28800), - (Task(3), 14400), - (Task(4), 14400), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1), 57600),], + end_hint: None + } + ), + ( + 6, + AssignCore { + core: 1, + begin: 8, + assignment: vec![(Task(2), 28800), (Task(3), 14400), (Task(4), 14400),], + end_hint: None + } + ), + ] + ); }); } @@ -243,14 +300,41 @@ fn initialize_with_leased_slots_works() { assert_ok!(Broker::do_start_sales(100, 2)); advance_to(18); let end_hint = None; - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ (Task(1000), 57600), ], end_hint }), - (6, AssignCore { core: 1, begin: 8, assignment: vec![ (Task(1001), 57600), ], end_hint }), - (12, AssignCore { core: 0, begin: 14, assignment: vec![ (Task(1001), 57600), ], end_hint }), - (12, AssignCore { core: 1, begin: 14, assignment: vec![ (Pool, 57600), ], end_hint }), - (18, AssignCore { core: 0, begin: 20, assignment: vec![ (Pool, 57600), ], end_hint }), - (18, AssignCore { core: 1, begin: 20, assignment: vec![ (Pool, 57600), ], end_hint }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1000), 57600),], + end_hint + } + ), + ( + 6, + AssignCore { + core: 1, + begin: 8, + assignment: vec![(Task(1001), 57600),], + end_hint + } + ), + ( + 12, + AssignCore { + core: 0, + begin: 14, + assignment: vec![(Task(1001), 57600),], + end_hint + } + ), + (12, AssignCore { core: 1, begin: 14, assignment: vec![(Pool, 57600),], end_hint }), + (18, AssignCore { core: 0, begin: 20, assignment: vec![(Pool, 57600),], end_hint }), + (18, AssignCore { core: 1, begin: 20, assignment: vec![(Pool, 57600),], end_hint }), + ] + ); }); } @@ -262,11 +346,18 @@ fn purchase_works() { let region = Broker::do_purchase(1, u64::max_value()).unwrap(); assert_ok!(Broker::do_assign(region, None, 1000, Final)); advance_to(6); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1000), 57600), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1000), 57600),], + end_hint: None + } + ),] + ); }); } @@ -282,17 +373,38 @@ fn partition_works() { assert_ok!(Broker::do_assign(region2, None, 1002, Final)); assert_ok!(Broker::do_assign(region3, None, 1003, Final)); advance_to(10); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1001), 57600), - ], end_hint: None }), - (8, AssignCore { core: 0, begin: 10, assignment: vec![ - (Task(1002), 57600), - ], end_hint: None }), - (10, AssignCore { core: 0, begin: 12, assignment: vec![ - (Task(1003), 57600), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1001), 57600),], + end_hint: None + } + ), + ( + 8, + AssignCore { + core: 0, + begin: 10, + assignment: vec![(Task(1002), 57600),], + end_hint: None + } + ), + ( + 10, + AssignCore { + core: 0, + begin: 12, + assignment: vec![(Task(1003), 57600),], + end_hint: None + } + ), + ] + ); }); } @@ -302,19 +414,26 @@ fn interlace_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 30)).unwrap(); - let (region2, region3) =Broker::do_interlace(region, None, CoreMask::from_chunk(30, 60)).unwrap(); + let (region1, region) = + Broker::do_interlace(region, None, CoreMask::from_chunk(0, 30)).unwrap(); + let (region2, region3) = + Broker::do_interlace(region, None, CoreMask::from_chunk(30, 60)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); assert_ok!(Broker::do_assign(region2, None, 1002, Final)); assert_ok!(Broker::do_assign(region3, None, 1003, Final)); advance_to(10); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1001), 21600), - (Task(1002), 21600), - (Task(1003), 14400), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1001), 21600), (Task(1002), 21600), (Task(1003), 14400),], + end_hint: None + } + ),] + ); }); } @@ -324,7 +443,8 @@ fn interlace_then_partition_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); - let (region1, region2) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); + let (region1, region2) = + Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); let (region1, region3) = Broker::do_partition(region1, None, 1).unwrap(); let (region2, region4) = Broker::do_partition(region2, None, 2).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); @@ -332,20 +452,38 @@ fn interlace_then_partition_works() { assert_ok!(Broker::do_assign(region3, None, 1003, Final)); assert_ok!(Broker::do_assign(region4, None, 1004, Final)); advance_to(10); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1001), 14400), - (Task(1002), 43200), - ], end_hint: None }), - (8, AssignCore { core: 0, begin: 10, assignment: vec![ - (Task(1002), 43200), - (Task(1003), 14400), - ], end_hint: None }), - (10, AssignCore { core: 0, begin: 12, assignment: vec![ - (Task(1003), 14400), - (Task(1004), 43200), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1001), 14400), (Task(1002), 43200),], + end_hint: None + } + ), + ( + 8, + AssignCore { + core: 0, + begin: 10, + assignment: vec![(Task(1002), 43200), (Task(1003), 14400),], + end_hint: None + } + ), + ( + 10, + AssignCore { + core: 0, + begin: 12, + assignment: vec![(Task(1003), 14400), (Task(1004), 43200),], + end_hint: None + } + ), + ] + ); }); } @@ -356,22 +494,37 @@ fn partition_then_interlace_works() { advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); let (region1, region2) = Broker::do_partition(region, None, 1).unwrap(); - let (region1, region3) = Broker::do_interlace(region1, None, CoreMask::from_chunk(0, 20)).unwrap(); - let (region2, region4) = Broker::do_interlace(region2, None, CoreMask::from_chunk(0, 30)).unwrap(); + let (region1, region3) = + Broker::do_interlace(region1, None, CoreMask::from_chunk(0, 20)).unwrap(); + let (region2, region4) = + Broker::do_interlace(region2, None, CoreMask::from_chunk(0, 30)).unwrap(); assert_ok!(Broker::do_assign(region1, None, 1001, Final)); assert_ok!(Broker::do_assign(region2, None, 1002, Final)); assert_ok!(Broker::do_assign(region3, None, 1003, Final)); assert_ok!(Broker::do_assign(region4, None, 1004, Final)); advance_to(10); - assert_eq!(CoretimeTrace::get(), vec![ - (6, AssignCore { core: 0, begin: 8, assignment: vec![ - (Task(1001), 14400), - (Task(1003), 43200), - ], end_hint: None }), - (8, AssignCore { core: 0, begin: 10, assignment: vec![ - (Task(1002), 21600), - (Task(1004), 36000), - ], end_hint: None }), - ]); + assert_eq!( + CoretimeTrace::get(), + vec![ + ( + 6, + AssignCore { + core: 0, + begin: 8, + assignment: vec![(Task(1001), 14400), (Task(1003), 43200),], + end_hint: None + } + ), + ( + 8, + AssignCore { + core: 0, + begin: 10, + assignment: vec![(Task(1002), 21600), (Task(1004), 36000),], + end_hint: None + } + ), + ] + ); }); } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 3816ebe52c4a1..15ea5e003d3cd 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,8 +1,8 @@ -use crate::{Config, CoretimeInterface, CoreIndex, CoreMask, CoreAssignment, TaskId}; -use codec::{Encode, Decode, MaxEncodedLen}; -use scale_info::TypeInfo; +use crate::{Config, CoreAssignment, CoreIndex, CoreMask, CoretimeInterface, TaskId}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::fungible::Inspect; use frame_system::Config as SConfig; +use scale_info::TypeInfo; use sp_arithmetic::Perbill; use sp_core::{ConstU32, RuntimeDebug}; use sp_runtime::BoundedVec; @@ -41,11 +41,7 @@ pub struct RegionId { } impl From for RegionId { fn from(x: u128) -> Self { - Self { - begin: (x >> 96) as u32, - core: (x >> 80) as u16, - part: x.into(), - } + Self { begin: (x >> 96) as u32, core: (x >> 80) as u16, part: x.into() } } } impl From for u128 { @@ -168,7 +164,9 @@ pub struct StatusRecord { } /// A record of flux in the InstaPool. -#[derive(Encode, Decode, Clone, Copy, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive( + Encode, Decode, Clone, Copy, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] pub struct PoolIoRecord { /// The total change of the pool, measured in Regularity Parts. pub total: SignedPartCount, @@ -206,10 +204,7 @@ pub struct SaleInfoRecord { /// Number of cores which have been sold; never more than cores_offered. pub cores_sold: CoreIndex, } -pub type SaleInfoRecordOf = SaleInfoRecord< - BalanceOf, - ::BlockNumber, ->; +pub type SaleInfoRecordOf = SaleInfoRecord, ::BlockNumber>; /// Record for Polkadot Core reservations (generally tasked with the maintenance of System /// Chains). @@ -250,6 +245,4 @@ pub struct ConfigRecord { /// The duration by which rewards for contributions to the InstaPool must be collected. pub contribution_timeout: Timeslice, } -pub type ConfigRecordOf = ConfigRecord< - ::BlockNumber, ->; +pub type ConfigRecordOf = ConfigRecord<::BlockNumber>; diff --git a/frame/broker/src/utils.rs b/frame/broker/src/utils.rs index 3a473f196300e..17eba5bef7d63 100644 --- a/frame/broker/src/utils.rs +++ b/frame/broker/src/utils.rs @@ -1,14 +1,21 @@ use sp_arithmetic::traits::Bounded; -pub fn lerp, S: TryInto + TryFrom + Bounded>(v: T, a: T, d: T, x: S, y: S) -> Option { - use sp_arithmetic::{Rounding::NearestPrefUp, helpers_128bit::multiply_by_rational_with_rounding}; - let v: u128 = v.try_into().ok()?; - let a: u128 = a.try_into().ok()?; - let d: u128 = d.try_into().ok()?; - let r: u128 = x.try_into().ok()?; - let s: u128 = y.try_into().ok()?; - let rsd = r.max(s) - r.min(s); - let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; - if r < s { r + td } else { r - td }.try_into().ok() +pub fn lerp, S: TryInto + TryFrom + Bounded>( + v: T, + a: T, + d: T, + x: S, + y: S, +) -> Option { + use sp_arithmetic::{ + helpers_128bit::multiply_by_rational_with_rounding, Rounding::NearestPrefUp, + }; + let v: u128 = v.try_into().ok()?; + let a: u128 = a.try_into().ok()?; + let d: u128 = d.try_into().ok()?; + let r: u128 = x.try_into().ok()?; + let s: u128 = y.try_into().ok()?; + let rsd = r.max(s) - r.min(s); + let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; + if r < s { r + td } else { r - td }.try_into().ok() } - diff --git a/frame/contracts/src/migration/v11.rs b/frame/contracts/src/migration/v11.rs index 67740cfaf6c80..8123d73aee560 100644 --- a/frame/contracts/src/migration/v11.rs +++ b/frame/contracts/src/migration/v11.rs @@ -80,7 +80,9 @@ impl MigrationStep for Migration { } fn step(&mut self) -> (IsFinished, Weight) { - let Some(old_queue) = old::DeletionQueue::::take() else { return (IsFinished::Yes, Weight::zero()) }; + let Some(old_queue) = old::DeletionQueue::::take() else { + return (IsFinished::Yes, Weight::zero()) + }; let len = old_queue.len(); log::debug!( diff --git a/frame/glutton/src/lib.rs b/frame/glutton/src/lib.rs index e3a1685d54f65..d4a955144f94c 100644 --- a/frame/glutton/src/lib.rs +++ b/frame/glutton/src/lib.rs @@ -270,7 +270,7 @@ pub mod pallet { /// Tries to come as close to the limit as possible. pub(crate) fn waste_at_most_proof_size(meter: &mut WeightMeter) { let Ok(n) = Self::calculate_proof_size_iters(&meter) else { - return; + return }; meter.defensive_saturating_accrue(T::WeightInfo::waste_proof_size_some(n)); @@ -302,7 +302,7 @@ pub mod pallet { /// Tries to come as close to the limit as possible. pub(crate) fn waste_at_most_ref_time(meter: &mut WeightMeter) { let Ok(n) = Self::calculate_ref_time_iters(&meter) else { - return; + return }; meter.defensive_saturating_accrue(T::WeightInfo::waste_ref_time_iter(n)); diff --git a/frame/support/procedural/src/benchmark.rs b/frame/support/procedural/src/benchmark.rs index 18d672b9b0508..76dbe0bcf9afb 100644 --- a/frame/support/procedural/src/benchmark.rs +++ b/frame/support/procedural/src/benchmark.rs @@ -166,11 +166,11 @@ fn ensure_valid_return_type(item_fn: &ItemFn) -> Result<()> { if let ReturnType::Type(_, typ) = &item_fn.sig.output { let non_unit = |span| return Err(Error::new(span, "expected `()`")); let Type::Path(TypePath { path, qself: _ }) = &**typ else { - return Err(Error::new( + return Err(Error::new( typ.span(), "Only `Result<(), BenchmarkError>` or a blank return type is allowed on benchmark function definitions", )) - }; + }; let seg = path .segments .last() @@ -780,7 +780,9 @@ fn expand_benchmark( let call_name = match *expr_call.func { Expr::Path(expr_path) => { // normal function call - let Some(segment) = expr_path.path.segments.last() else { return call_err(); }; + let Some(segment) = expr_path.path.segments.last() else { + return call_err() + }; segment.ident.to_string() }, Expr::Infer(_) => { diff --git a/frame/support/procedural/src/construct_runtime/expand/outer_enums.rs b/frame/support/procedural/src/construct_runtime/expand/outer_enums.rs index 544f63be2bfa1..b78360d5fc052 100644 --- a/frame/support/procedural/src/construct_runtime/expand/outer_enums.rs +++ b/frame/support/procedural/src/construct_runtime/expand/outer_enums.rs @@ -100,9 +100,7 @@ pub fn expand_outer_enum( let enum_name_ident = Ident::new(enum_ty.struct_name(), Span::call_site()); for pallet_decl in pallet_decls { - let Some(pallet_entry) = pallet_decl.find_part(enum_name_str) else { - continue - }; + let Some(pallet_entry) = pallet_decl.find_part(enum_name_str) else { continue }; let path = &pallet_decl.path; let pallet_name = &pallet_decl.name; diff --git a/frame/support/src/storage/mod.rs b/frame/support/src/storage/mod.rs index 57d31dade6dcd..d4f3c262aca00 100644 --- a/frame/support/src/storage/mod.rs +++ b/frame/support/src/storage/mod.rs @@ -113,9 +113,7 @@ pub trait StorageValue { /// Mutate the value under a key if the value already exists. Do nothing and return the default /// value if not. - fn mutate_extant R>( - f: F, - ) -> R { + fn mutate_extant R>(f: F) -> R { Self::mutate_exists(|maybe_v| match maybe_v { Some(ref mut value) => f(value), None => R::default(), diff --git a/frame/support/src/storage/types/value.rs b/frame/support/src/storage/types/value.rs index 509ede67c976a..58ebd85d28179 100644 --- a/frame/support/src/storage/types/value.rs +++ b/frame/support/src/storage/types/value.rs @@ -136,9 +136,7 @@ where } /// Mutate the value under a key iff it exists. Do nothing and return the default value if not. - pub fn mutate_extant R>( - f: F, - ) -> R { + pub fn mutate_extant R>(f: F) -> R { >::mutate_extant(f) } diff --git a/frame/support/src/traits/dispatch.rs b/frame/support/src/traits/dispatch.rs index 53d66cd056463..d0cedb708cf1d 100644 --- a/frame/support/src/traits/dispatch.rs +++ b/frame/support/src/traits/dispatch.rs @@ -39,7 +39,8 @@ pub trait EnsureOrigin { /// The same as `ensure_origin` except that Root origin will always pass. This can only be /// used if `Success` has a sensible impl of `Default` since that will be used in the result. - fn ensure_origin_or_root(o: OuterOrigin) -> Result, BadOrigin> where + fn ensure_origin_or_root(o: OuterOrigin) -> Result, BadOrigin> + where OuterOrigin: OriginTrait, { if o.caller().is_root() { @@ -54,7 +55,8 @@ pub trait EnsureOrigin { /// The same as `try_origin` except that Root origin will always pass. This can only be /// used if `Success` has a sensible impl of `Default` since that will be used in the result. - fn try_origin_or_root(o: OuterOrigin) -> Result, OuterOrigin> where + fn try_origin_or_root(o: OuterOrigin) -> Result, OuterOrigin> + where OuterOrigin: OriginTrait, { if o.caller().is_root() { diff --git a/primitives/api/proc-macro/src/runtime_metadata.rs b/primitives/api/proc-macro/src/runtime_metadata.rs index 458248cbd3d16..8dd88e2ef702b 100644 --- a/primitives/api/proc-macro/src/runtime_metadata.rs +++ b/primitives/api/proc-macro/src/runtime_metadata.rs @@ -88,9 +88,7 @@ pub fn generate_decl_runtime_metadata(decl: &ItemTrait) -> TokenStream2 { let mut where_clause = Vec::new(); for item in &decl.items { // Collect metadata for methods only. - let syn::TraitItem::Fn(method) = item else { - continue - }; + let syn::TraitItem::Fn(method) = item else { continue }; // Collect metadata only for the latest methods. let is_changed_in = @@ -103,9 +101,7 @@ pub fn generate_decl_runtime_metadata(decl: &ItemTrait) -> TokenStream2 { let signature = &method.sig; for input in &signature.inputs { // Exclude `self` from metadata collection. - let syn::FnArg::Typed(typed) = input else { - continue - }; + let syn::FnArg::Typed(typed) = input else { continue }; let pat = &typed.pat; let name = quote!(#pat).to_string(); @@ -153,9 +149,7 @@ pub fn generate_decl_runtime_metadata(decl: &ItemTrait) -> TokenStream2 { // The trait generics where already extended with `Block: BlockT`. let mut generics = decl.generics.clone(); for generic_param in generics.params.iter_mut() { - let syn::GenericParam::Type(ty) = generic_param else { - continue - }; + let syn::GenericParam::Type(ty) = generic_param else { continue }; // Default type parameters are not allowed in functions. ty.eq_token = None; diff --git a/primitives/api/proc-macro/src/utils.rs b/primitives/api/proc-macro/src/utils.rs index 7b580ee6f099e..c9389154bbf40 100644 --- a/primitives/api/proc-macro/src/utils.rs +++ b/primitives/api/proc-macro/src/utils.rs @@ -266,9 +266,7 @@ pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec { attrs .iter() .filter_map(|attr| { - let syn::Meta::NameValue(meta) = &attr.meta else { - return None - }; + let syn::Meta::NameValue(meta) = &attr.meta else { return None }; let Ok(lit) = syn::parse2::(meta.value.to_token_stream()) else { unreachable!("non-lit doc attribute values do not exist"); }; diff --git a/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs b/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs index e9a3208a738ef..53f950dff069f 100644 --- a/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs +++ b/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs @@ -53,7 +53,7 @@ where N: MultiplyRational + Into + Copy + core::fmt::Debug, { let Some(got) = f.multiply_rational(n, d, r) else { - return; + return }; let (ae, be, ce) = diff --git a/primitives/arithmetic/src/fixed_point.rs b/primitives/arithmetic/src/fixed_point.rs index 370e8d7267b0d..12a822bc3393b 100644 --- a/primitives/arithmetic/src/fixed_point.rs +++ b/primitives/arithmetic/src/fixed_point.rs @@ -52,17 +52,19 @@ pub trait FixedPointOperand: { } -impl - + UniqueSaturatedInto - + TryFrom - + CheckedNeg -> FixedPointOperand for T {} +impl< + T: Copy + + Clone + + Bounded + + Zero + + Saturating + + PartialOrd + + UniqueSaturatedInto + + TryFrom + + CheckedNeg, + > FixedPointOperand for T +{ +} /// Something that implements a decimal fixed point number. /// diff --git a/primitives/blockchain/src/backend.rs b/primitives/blockchain/src/backend.rs index e9278be1d5d3c..8208f9128e714 100644 --- a/primitives/blockchain/src/backend.rs +++ b/primitives/blockchain/src/backend.rs @@ -196,9 +196,7 @@ pub trait Backend: base_hash: Block::Hash, import_lock: &RwLock<()>, ) -> Result> { - let Some(base_header) = self.header(base_hash)? else { - return Ok(None) - }; + let Some(base_header) = self.header(base_hash)? else { return Ok(None) }; let leaves = { // ensure no blocks are imported during this code block. diff --git a/primitives/core/src/ed25519.rs b/primitives/core/src/ed25519.rs index ba947990e1c0b..de085e590b996 100644 --- a/primitives/core/src/ed25519.rs +++ b/primitives/core/src/ed25519.rs @@ -422,12 +422,8 @@ impl TraitPair for Pair { /// /// Returns true if the signature is good. fn verify>(sig: &Self::Signature, message: M, public: &Self::Public) -> bool { - let Ok(public) = VerificationKey::try_from(public.as_slice()) else { - return false - }; - let Ok(signature) = ed25519_zebra::Signature::try_from(sig.as_ref()) else { - return false - }; + let Ok(public) = VerificationKey::try_from(public.as_slice()) else { return false }; + let Ok(signature) = ed25519_zebra::Signature::try_from(sig.as_ref()) else { return false }; public.verify(&signature, message.as_ref()).is_ok() } diff --git a/primitives/core/src/sr25519.rs b/primitives/core/src/sr25519.rs index 963ca1c3fedc3..36c1c3251488c 100644 --- a/primitives/core/src/sr25519.rs +++ b/primitives/core/src/sr25519.rs @@ -505,12 +505,8 @@ impl TraitPair for Pair { } fn verify>(sig: &Self::Signature, message: M, pubkey: &Self::Public) -> bool { - let Ok(signature) = schnorrkel::Signature::from_bytes(sig.as_ref()) else { - return false - }; - let Ok(public) = PublicKey::from_bytes(pubkey.as_ref()) else { - return false - }; + let Ok(signature) = schnorrkel::Signature::from_bytes(sig.as_ref()) else { return false }; + let Ok(public) = PublicKey::from_bytes(pubkey.as_ref()) else { return false }; public.verify_simple(SIGNING_CTX, message.as_ref(), &signature).is_ok() } diff --git a/primitives/io/src/lib.rs b/primitives/io/src/lib.rs index 750b5d5924637..bd20ee0c917aa 100644 --- a/primitives/io/src/lib.rs +++ b/primitives/io/src/lib.rs @@ -776,9 +776,7 @@ pub trait Crypto { return false }; - let Ok(sig) = ed25519_dalek::Signature::from_bytes(&sig.0) else { - return false - }; + let Ok(sig) = ed25519_dalek::Signature::from_bytes(&sig.0) else { return false }; public_key.verify(msg, &sig).is_ok() } else { diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 8405b5a0bda9e..1f3e919823e8a 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -222,7 +222,9 @@ fn get_rustup_command() -> Option { continue } - let Some(cargo_version) = cmd.version() else { continue; }; + let Some(cargo_version) = cmd.version() else { + continue + }; versions.push((cargo_version, rustup_version.to_string())); } From 140b2c582de98f6aa8d19b8a1fb73a637d4738d0 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:03:25 +0100 Subject: [PATCH 037/131] Advance notice period is in RC blocks, not timeslices --- frame/broker/src/coretime_interface.rs | 3 +- frame/broker/src/dispatchable_impls.rs | 9 ++- frame/broker/src/implementation.rs | 96 +++++++++++++++----------- frame/broker/src/mock.rs | 2 +- frame/broker/src/tests.rs | 6 +- frame/broker/src/types.rs | 12 ++-- 6 files changed, 70 insertions(+), 58 deletions(-) diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index e2bc7c3a24c57..a45e7a766ba5e 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -3,6 +3,7 @@ use frame_support::Parameter; use scale_info::TypeInfo; use sp_arithmetic::traits::AtLeast32BitUnsigned; use sp_core::RuntimeDebug; +use sp_std::fmt::Debug; /// Index of a Polkadot Core. pub type CoreIndex = u16; @@ -29,7 +30,7 @@ pub enum CoreAssignment { pub trait CoretimeInterface { type AccountId: Parameter; type Balance; - type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode; + type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode + Decode + MaxEncodedLen + Debug; fn latest() -> Self::BlockNumber; fn request_core_count(count: CoreIndex); fn request_revenue_info_at(when: Self::BlockNumber); diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 1e7e6cb4bde73..5bb1518dfc1bd 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -45,13 +45,14 @@ impl Pallet { core_count: CoreIndex, ) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + let commit_timeslice = Self::latest_timeslice_ready_to_commit(&config); let status = StatusRecord { core_count, pool_size: 0, - last_timeslice: Self::current_timeslice(), + last_committed_timeslice: commit_timeslice.saturating_sub(1), system_pool_size: 0, + last_timeslice: Self::current_timeslice(), }; - let commit_timeslice = status.last_timeslice + config.advance_notice; let now = frame_system::Pallet::::block_number(); let dummy_sale = SaleInfoRecord { sale_start: now, @@ -353,11 +354,9 @@ impl Pallet { } pub(crate) fn do_drop_region(region_id: RegionId) -> DispatchResult { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - let next_commit_timeslice = status.last_timeslice + config.advance_notice + 1; - ensure!(next_commit_timeslice >= region.end, Error::::StillValid); + ensure!(status.last_committed_timeslice >= region.end, Error::::StillValid); Regions::::remove(®ion_id); let duration = region.end.saturating_sub(region_id.begin); diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 85c4ec2b7c099..9f8d882d46227 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -4,7 +4,7 @@ use frame_support::{ traits::{ fungible::Balanced, tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, - OnUnbalanced, + OnUnbalanced, Defensive, }, }; use sp_arithmetic::{ @@ -15,32 +15,63 @@ use sp_runtime::traits::{AccountIdConversion, ConvertBack}; use CompletionStatus::Complete; impl Pallet { + pub fn current_timeslice() -> Timeslice { + let latest = T::Coretime::latest(); + let timeslice_period = T::TimeslicePeriod::get(); + (latest / timeslice_period).saturated_into() + } + + pub fn latest_timeslice_ready_to_commit(config: &ConfigRecordOf) -> Timeslice { + let latest = T::Coretime::latest(); + let advanced = latest.saturating_add(config.advance_notice); + let timeslice_period = T::TimeslicePeriod::get(); + (advanced / timeslice_period).saturated_into() + } + + pub fn next_timeslice_to_commit(config: &ConfigRecordOf, status: &StatusRecord) -> Option { + if status.last_committed_timeslice < Self::latest_timeslice_ready_to_commit(config) { + Some(status.last_committed_timeslice + 1) + } else { + None + } + } + /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is /// less than `Self::current_timeslice`. pub(crate) fn do_tick() -> DispatchResult { let mut status = Status::::get().ok_or(Error::::Uninitialized)?; - let current_timeslice = Self::current_timeslice(); - ensure!(status.last_timeslice < current_timeslice, Error::::NothingToDo); - status.last_timeslice.saturating_inc(); + let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - T::Coretime::request_revenue_info_at( - T::TimeslicePeriod::get() * status.last_timeslice.into(), - ); + Self::process_core_count(); + let _ = Self::process_revenue().defensive(); - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; - let commit_timeslice = status.last_timeslice + config.advance_notice; + if let Some(commit_timeslice) = Self::next_timeslice_to_commit(&config, &status) { + status.last_committed_timeslice = commit_timeslice; + if let Some(sale) = SaleInfo::::get() { + if commit_timeslice >= sale.region_begin { + // Sale can be rotated. + Self::rotate_sale(sale, &config, &status); + } + } - if let Some(sale) = SaleInfo::::get() { - if commit_timeslice >= sale.region_begin { - // Sale can be rotated. - Self::rotate_sale(sale, &config, &status); + Self::process_pool(commit_timeslice, &mut status); + + let timeslice_period = T::TimeslicePeriod::get(); + let rc_begin = RelayBlockNumberOf::::from(commit_timeslice) * timeslice_period; + for core in 0..status.core_count { + Self::process_core_schedule(commit_timeslice, rc_begin, core); } } - Self::process_timeslice(commit_timeslice, &mut status, &config); - Self::process_core_count()?; - Self::process_revenue()?; + + let current_timeslice = Self::current_timeslice(); + if status.last_timeslice < current_timeslice { + let rc_block = T::TimeslicePeriod::get() * current_timeslice.into(); + T::Coretime::request_revenue_info_at(rc_block); + status.last_timeslice.saturating_inc(); + } Status::::put(&status); + Ok(()) } @@ -168,12 +199,12 @@ impl Pallet { T::PalletId::get().into_account_truncating() } - fn process_core_count() -> Result { + fn process_core_count() -> bool { if let Some(new_count) = T::Coretime::check_notify_core_count() { Status::::mutate_extant(|c| c.core_count = new_count); - return Ok(true) + return true } - Ok(false) + false } fn process_revenue() -> Result { @@ -188,7 +219,7 @@ impl Pallet { ensure!(pool_record.maybe_payout.is_none(), Error::::RevenueAlreadyKnown); ensure!( pool_record.total_contributions >= pool_record.system_contributions, - Error::::InvalidContributions + Error::::InvalidContributions, ); ensure!(pool_record.total_contributions > 0, Error::::InvalidContributions); @@ -218,24 +249,6 @@ impl Pallet { .unwrap_or(sale.start_price) } - pub fn current_timeslice() -> Timeslice { - let latest = T::Coretime::latest(); - let timeslice_period = T::TimeslicePeriod::get(); - (latest / timeslice_period).saturated_into() - } - - pub(crate) fn process_timeslice( - timeslice: Timeslice, - status: &mut StatusRecord, - _config: &ConfigRecordOf, - ) { - Self::process_pool(timeslice, status); - let rc_begin = RelayBlockNumberOf::::from(timeslice) * T::TimeslicePeriod::get(); - for core in 0..status.core_count { - Self::process_core_schedule(timeslice, rc_begin, core); - } - } - fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); status.pool_size = (status.pool_size as i32).saturating_add(pool_io.total) as u32; @@ -315,7 +328,6 @@ impl Pallet { maybe_check_owner: Option, finality: Finality, ) -> Result)>, Error> { - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; @@ -325,9 +337,9 @@ impl Pallet { Regions::::remove(®ion_id); - let last_commit_timeslice = status.last_timeslice + config.advance_notice; - if region_id.begin <= last_commit_timeslice { - region_id.begin = last_commit_timeslice + 1; + let last_committed_timeslice = status.last_committed_timeslice; + if region_id.begin <= last_committed_timeslice { + region_id.begin = last_committed_timeslice + 1; if region_id.begin >= region.end { let duration = region.end.saturating_sub(region_id.begin); Self::deposit_event(Event::Dropped { region_id, duration }); diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index a99c3ea16fc65..546d558ff2204 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -236,7 +236,7 @@ pub struct TestExt(ConfigRecordOf); impl TestExt { pub fn new() -> Self { Self(ConfigRecord { - advance_notice: 1, + advance_notice: 2, interlude_length: 1, leadin_length: 1, ideal_bulk_proportion: Default::default(), diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 0126c4160ece9..66e74f18d202a 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -219,7 +219,7 @@ fn instapool_payouts_work() { assert_ok!(Broker::do_purchase_credit(1, 20, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 10)); - advance_to(10); + advance_to(11); assert_eq!(pot(), 14); assert_eq!(revenue(), 106); assert_ok!(Broker::do_claim_revenue(region, 100)); @@ -243,13 +243,13 @@ fn instapool_partial_core_payouts_work() { assert_ok!(Broker::do_purchase_credit(1, 40, 1)); advance_to(8); assert_ok!(TestCoretimeProvider::spend_instantaneous(1, 40)); - advance_to(10); + advance_to(11); assert_ok!(Broker::do_claim_revenue(region1, 100)); assert_ok!(Broker::do_claim_revenue(region2, 100)); - assert_eq!(pot(), 0); assert_eq!(revenue(), 120); assert_eq!(balance(2), 5); assert_eq!(balance(3), 15); + assert_eq!(pot(), 0); }); } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 15ea5e003d3cd..c06f3bed98249 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -157,9 +157,9 @@ pub struct StatusRecord { /// The current amount of the Instantaneous Coretime Pool which is provided by the Polkadot /// System, rather than provided as a result of privately operated Coretime. pub system_pool_size: PartCount, - /// The last (Relay-chain) timeslice which we processed for (this processing is generally - /// done some number of timeslices in advance of actual Relay-chain execution to make up - /// for latencies and any needed Relay-side preparations). + /// The last (Relay-chain) timeslice which we committed to the Relay-chain. + pub last_committed_timeslice: Timeslice, + /// The timeslice of the last time we ticked. pub last_timeslice: Timeslice, } @@ -224,10 +224,10 @@ pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; /// Configuration of this pallet. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct ConfigRecord { +pub struct ConfigRecord { /// The number of timeslices in advance which scheduling should be fixed and the /// `Coretime::assign` API used to inform the Relay-chain. - pub advance_notice: Timeslice, + pub advance_notice: RelayBlockNumber, /// The length in blocks of the Interlude Period for forthcoming sales. pub interlude_length: BlockNumber, /// The length in blocks of the Leadin Period for forthcoming sales. @@ -245,4 +245,4 @@ pub struct ConfigRecord { /// The duration by which rewards for contributions to the InstaPool must be collected. pub contribution_timeout: Timeslice, } -pub type ConfigRecordOf = ConfigRecord<::BlockNumber>; +pub type ConfigRecordOf = ConfigRecord<::BlockNumber, RelayBlockNumberOf>; From d4b6baded767d0dcb91c697dc2fda4d8415c8397 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:03:49 +0100 Subject: [PATCH 038/131] Docs --- frame/broker/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index c06f3bed98249..e161fc041cafc 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -225,7 +225,7 @@ pub type LeasesRecordOf = LeasesRecord<::MaxLeasedCores>; /// Configuration of this pallet. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ConfigRecord { - /// The number of timeslices in advance which scheduling should be fixed and the + /// The number of Relay-chain blocks in advance which scheduling should be fixed and the /// `Coretime::assign` API used to inform the Relay-chain. pub advance_notice: RelayBlockNumber, /// The length in blocks of the Interlude Period for forthcoming sales. From 197c1e110e53b5e5e82855d9ed536b36e16dae64 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:03:54 +0100 Subject: [PATCH 039/131] Formatting --- client/network/src/discovery.rs | 4 +--- frame/broker/src/coretime_interface.rs | 8 +++++++- frame/broker/src/implementation.rs | 7 +++++-- frame/glutton/src/lib.rs | 8 ++------ frame/support/procedural/src/benchmark.rs | 4 +--- .../fuzzer/src/multiply_by_rational_with_rounding.rs | 4 +--- utils/wasm-builder/src/lib.rs | 4 +--- 7 files changed, 18 insertions(+), 21 deletions(-) diff --git a/client/network/src/discovery.rs b/client/network/src/discovery.rs index fa611253303db..d9fad53844346 100644 --- a/client/network/src/discovery.rs +++ b/client/network/src/discovery.rs @@ -548,9 +548,7 @@ impl NetworkBehaviour for DiscoveryBehaviour { addresses: &[Multiaddr], effective_role: Endpoint, ) -> Result, ConnectionDenied> { - let Some(peer_id) = maybe_peer else { - return Ok(Vec::new()) - }; + let Some(peer_id) = maybe_peer else { return Ok(Vec::new()) }; let mut list = self .permanent_addresses diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index a45e7a766ba5e..1e5ebd34694c5 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -30,7 +30,13 @@ pub enum CoreAssignment { pub trait CoretimeInterface { type AccountId: Parameter; type Balance; - type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo + Encode + Decode + MaxEncodedLen + Debug; + type BlockNumber: AtLeast32BitUnsigned + + Copy + + TypeInfo + + Encode + + Decode + + MaxEncodedLen + + Debug; fn latest() -> Self::BlockNumber; fn request_core_count(count: CoreIndex); fn request_revenue_info_at(when: Self::BlockNumber); diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 9f8d882d46227..dea833c21ec65 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -4,7 +4,7 @@ use frame_support::{ traits::{ fungible::Balanced, tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, - OnUnbalanced, Defensive, + Defensive, OnUnbalanced, }, }; use sp_arithmetic::{ @@ -28,7 +28,10 @@ impl Pallet { (advanced / timeslice_period).saturated_into() } - pub fn next_timeslice_to_commit(config: &ConfigRecordOf, status: &StatusRecord) -> Option { + pub fn next_timeslice_to_commit( + config: &ConfigRecordOf, + status: &StatusRecord, + ) -> Option { if status.last_committed_timeslice < Self::latest_timeslice_ready_to_commit(config) { Some(status.last_committed_timeslice + 1) } else { diff --git a/frame/glutton/src/lib.rs b/frame/glutton/src/lib.rs index d4a955144f94c..d0f1be0f19ea1 100644 --- a/frame/glutton/src/lib.rs +++ b/frame/glutton/src/lib.rs @@ -269,9 +269,7 @@ pub mod pallet { /// /// Tries to come as close to the limit as possible. pub(crate) fn waste_at_most_proof_size(meter: &mut WeightMeter) { - let Ok(n) = Self::calculate_proof_size_iters(&meter) else { - return - }; + let Ok(n) = Self::calculate_proof_size_iters(&meter) else { return }; meter.defensive_saturating_accrue(T::WeightInfo::waste_proof_size_some(n)); @@ -301,9 +299,7 @@ pub mod pallet { /// /// Tries to come as close to the limit as possible. pub(crate) fn waste_at_most_ref_time(meter: &mut WeightMeter) { - let Ok(n) = Self::calculate_ref_time_iters(&meter) else { - return - }; + let Ok(n) = Self::calculate_ref_time_iters(&meter) else { return }; meter.defensive_saturating_accrue(T::WeightInfo::waste_ref_time_iter(n)); let clobber = Self::waste_ref_time_iter(vec![0u8; 64], n); diff --git a/frame/support/procedural/src/benchmark.rs b/frame/support/procedural/src/benchmark.rs index 76dbe0bcf9afb..9f28e7129d2e1 100644 --- a/frame/support/procedural/src/benchmark.rs +++ b/frame/support/procedural/src/benchmark.rs @@ -780,9 +780,7 @@ fn expand_benchmark( let call_name = match *expr_call.func { Expr::Path(expr_path) => { // normal function call - let Some(segment) = expr_path.path.segments.last() else { - return call_err() - }; + let Some(segment) = expr_path.path.segments.last() else { return call_err() }; segment.ident.to_string() }, Expr::Infer(_) => { diff --git a/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs b/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs index 53f950dff069f..5f3f675c971f2 100644 --- a/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs +++ b/primitives/arithmetic/fuzzer/src/multiply_by_rational_with_rounding.rs @@ -52,9 +52,7 @@ fn check(f: N, n: N, d: N, r: Rounding) where N: MultiplyRational + Into + Copy + core::fmt::Debug, { - let Some(got) = f.multiply_rational(n, d, r) else { - return - }; + let Some(got) = f.multiply_rational(n, d, r) else { return }; let (ae, be, ce) = (Fraction::from(f.into()), Fraction::from(n.into()), Fraction::from(d.into())); diff --git a/utils/wasm-builder/src/lib.rs b/utils/wasm-builder/src/lib.rs index 1f3e919823e8a..c9011f97be711 100644 --- a/utils/wasm-builder/src/lib.rs +++ b/utils/wasm-builder/src/lib.rs @@ -222,9 +222,7 @@ fn get_rustup_command() -> Option { continue } - let Some(cargo_version) = cmd.version() else { - continue - }; + let Some(cargo_version) = cmd.version() else { continue }; versions.push((cargo_version, rustup_version.to_string())); } From 0f6450eb8d4501d29cbdcbf96f799bb691584864 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:04:35 +0100 Subject: [PATCH 040/131] Docs --- frame/broker/src/types.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index e161fc041cafc..066a5ec9ed987 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -214,7 +214,9 @@ pub type ReservationsRecordOf = ReservationsRecord<::MaxReserved /// Information on a single legacy lease. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct LeaseRecordItem { + /// The timeslice until the lease is valid. pub until: Timeslice, + /// The task which the lease is for. pub task: TaskId, } From 3cc1d83f14fc9ab38c094cad6bf6d3c97e7052bf Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:05:02 +0100 Subject: [PATCH 041/131] Missing file --- frame/broker/src/adapt_price.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 frame/broker/src/adapt_price.rs diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs new file mode 100644 index 0000000000000..90f5f3b25cf34 --- /dev/null +++ b/frame/broker/src/adapt_price.rs @@ -0,0 +1,23 @@ +use crate::CoreIndex; +use sp_arithmetic::{traits::One, FixedU64}; + +pub trait AdaptPrice { + fn adapt_price(sold: CoreIndex, target: CoreIndex, max: CoreIndex) -> FixedU64; +} + +impl AdaptPrice for () { + fn adapt_price(_: CoreIndex, _: CoreIndex, _: CoreIndex) -> FixedU64 { + FixedU64::one() + } +} + +pub struct Linear; +impl AdaptPrice for Linear { + fn adapt_price(sold: CoreIndex, target: CoreIndex, max: CoreIndex) -> FixedU64 { + if sold < target { + FixedU64::from_rational(sold.into(), target.into()) + } else { + FixedU64::one() + FixedU64::from_rational((sold - target).into(), (max - target).into()) + } + } +} From 8ff28b9eec6fe1fd7c515667662da951456f1be7 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 16:32:43 +0100 Subject: [PATCH 042/131] Added some events --- frame/broker/src/dispatchable_impls.rs | 13 ++++++---- frame/broker/src/implementation.rs | 5 ++-- frame/broker/src/lib.rs | 33 ++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 5bb1518dfc1bd..19cebd124d1b3 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -15,20 +15,25 @@ impl Pallet { pub(crate) fn do_request_core_count(core_count: CoreIndex) -> DispatchResult { T::Coretime::request_core_count(core_count); + Self::deposit_event(Event::::CoreCountRequested { core_count }); Ok(()) } - pub(crate) fn do_reserve(schedule: Schedule) -> DispatchResult { + pub(crate) fn do_reserve(workload: Schedule) -> DispatchResult { let mut r = Reservations::::get(); - r.try_push(schedule).map_err(|_| Error::::TooManyReservations)?; + let index = r.len() as u32; + r.try_push(workload.clone()).map_err(|_| Error::::TooManyReservations)?; Reservations::::put(r); + Self::deposit_event(Event::::ReservationMade { index, workload }); Ok(()) } - pub(crate) fn do_unreserve(item_index: u32) -> DispatchResult { + pub(crate) fn do_unreserve(index: u32) -> DispatchResult { let mut r = Reservations::::get(); - r.remove(item_index as usize); + ensure!(index < r.len() as u32, Error::::UnknownReservation); + let workload = r.remove(index as usize); Reservations::::put(r); + Self::deposit_event(Event::::ReservationCancelled { index, workload }); Ok(()) } diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index dea833c21ec65..ee7be43f74880 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -203,8 +203,9 @@ impl Pallet { } fn process_core_count() -> bool { - if let Some(new_count) = T::Coretime::check_notify_core_count() { - Status::::mutate_extant(|c| c.core_count = new_count); + if let Some(core_count) = T::Coretime::check_notify_core_count() { + Status::::mutate_extant(|c| c.core_count = core_count); + Self::deposit_event(Event::::CoreCountChanged { core_count }); return true } false diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index e3a612801c859..32f7ec05dec63 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -249,6 +249,30 @@ pub mod pallet { /// The duration of the Region. duration: Timeslice, }, + /// A new number of cores has been requested. + CoreCountRequested { + /// The number of cores requested. + core_count: CoreIndex, + }, + /// The number of cores available for scheduling has changed. + CoreCountChanged { + /// The new number of cores available for scheduling. + core_count: CoreIndex, + }, + /// There is a new reservation for a workload. + ReservationMade { + /// The index of the reservation. + index: u32, + /// The workload of the reservation. + workload: Schedule, + }, + /// A reservation for a workload has been cancelled. + ReservationCancelled { + /// The index of the reservation which was cancelled. + index: u32, + /// The workload of the now cancelled reservation. + workload: Schedule, + }, } #[pallet::error] @@ -311,6 +335,8 @@ pub mod pallet { StillValid, /// The history item does not exist. NoHistory, + /// No reservation of the given index exists. + UnknownReservation, } #[pallet::hooks] @@ -349,10 +375,13 @@ pub mod pallet { Ok(Pays::No.into()) } - /// Cancel a reserved workload. + /// Cancel a reservation for a workload. /// /// - `origin`: Must be Root or pass `AdminOrigin`. - /// - `item_index`: The index of the reservation. + /// - `item_index`: The index of the reservation. Usually this will also be the index of the + /// core on which the reservation has been scheduled. However, it is possible that if + /// other cores are reserved or unreserved in the same sale rotation that they won't + /// correspond, so it's better to look up the core properly in the `Reservations` storage. #[pallet::call_index(2)] pub fn unreserve(origin: OriginFor, item_index: u32) -> DispatchResultWithPostInfo { T::AdminOrigin::ensure_origin_or_root(origin)?; From 633ab28e6fadd59993cd0d6a0cb2b071bf8c2872 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 17:09:12 +0100 Subject: [PATCH 043/131] Events for all dispatchables --- frame/broker/src/dispatchable_impls.rs | 40 +++++++++++---- frame/broker/src/implementation.rs | 2 +- frame/broker/src/lib.rs | 71 +++++++++++++++++++++++--- 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 19cebd124d1b3..8c1c7e941352c 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -42,6 +42,7 @@ impl Pallet { r.try_push(LeaseRecordItem { until, task }) .map_err(|_| Error::::TooManyLeases)?; Leases::::put(r); + Self::deposit_event(Event::::Leased { until, task }); Ok(()) } @@ -72,6 +73,7 @@ impl Pallet { cores_offered: 0, cores_sold: 0, }; + Self::deposit_event(Event::::SalesStarted { reserve_price, core_count }); Self::rotate_sale(dummy_sale, &config, &status); Status::::put(&status); Ok(()) @@ -311,9 +313,14 @@ impl Pallet { InstaPoolContribution::::take(region).ok_or(Error::::UnknownContribution)?; let contributed_parts = region.part.count_ones(); + Self::deposit_event(Event::RevenueClaimBegun { region, max_timeslices }); + let mut payout = BalanceOf::::zero(); let last = region.begin + contribution.length.min(max_timeslices); for r in region.begin..last { + region.begin = r + 1; + contribution.length.saturating_dec(); + let mut pool_record = match InstaPoolHistory::::get(r) { Some(x) => x, None => continue, @@ -322,20 +329,21 @@ impl Pallet { Some(x) => x, None => break, }; - region.begin = r; - contribution.length.saturating_dec(); - payout.saturating_accrue( - total_payout.saturating_mul(contributed_parts.into()) / - pool_record.total_contributions.into(), - ); + let p = total_payout.saturating_mul(contributed_parts.into()) / + pool_record.total_contributions.into(); + + payout.saturating_accrue(p); pool_record.total_contributions.saturating_reduce(contributed_parts); let remaining_payout = total_payout.saturating_sub(payout); if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { pool_record.maybe_payout = Some(remaining_payout); - InstaPoolHistory::::insert(region.begin, &pool_record); + InstaPoolHistory::::insert(r, &pool_record); } else { - InstaPoolHistory::::remove(region.begin); + InstaPoolHistory::::remove(r); + } + if !p.is_zero() { + Self::deposit_event(Event::RevenueClaimItem { when: r, amount: p }); } } @@ -344,6 +352,12 @@ impl Pallet { } T::Currency::transfer(&Self::account_id(), &contribution.payee, payout, Expendable) .defensive_ok(); + let next = if last < region.begin + contribution.length { Some(region) } else { None }; + Self::deposit_event(Event::RevenueClaimPaid { + who: contribution.payee, + amount: payout, + next, + }); Ok(()) } @@ -353,8 +367,9 @@ impl Pallet { beneficiary: RelayAccountIdOf, ) -> DispatchResult { T::Currency::transfer(&who, &Self::account_id(), amount, Expendable)?; - let amount = T::ConvertBalance::convert(amount); - T::Coretime::credit_account(beneficiary, amount); + let rc_amount = T::ConvertBalance::convert(amount); + T::Coretime::credit_account(beneficiary.clone(), rc_amount); + Self::deposit_event(Event::::CreditPurchased { who, beneficiary, amount }); Ok(()) } @@ -365,7 +380,7 @@ impl Pallet { Regions::::remove(®ion_id); let duration = region.end.saturating_sub(region_id.begin); - Self::deposit_event(Event::Dropped { region_id, duration }); + Self::deposit_event(Event::RegionDropped { region_id, duration }); Ok(()) } @@ -377,6 +392,7 @@ impl Pallet { let end = region_id.begin.saturating_add(contrib.length); ensure!(status.last_timeslice > end + config.contribution_timeout, Error::::StillValid); InstaPoolContribution::::remove(region_id); + Self::deposit_event(Event::ContributionDropped { region_id }); Ok(()) } @@ -388,6 +404,8 @@ impl Pallet { if let Some(payout) = record.maybe_payout { let _ = Self::charge(&Self::account_id(), payout); } + let revenue = record.maybe_payout.unwrap_or_default(); + Self::deposit_event(Event::HistoryDropped { when, revenue }); Ok(()) } } diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index ee7be43f74880..f7759a2f992c7 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -346,7 +346,7 @@ impl Pallet { region_id.begin = last_committed_timeslice + 1; if region_id.begin >= region.end { let duration = region.end.saturating_sub(region_id.begin); - Self::deposit_event(Event::Dropped { region_id, duration }); + Self::deposit_event(Event::RegionDropped { region_id, duration }); return Ok(None) } } else { diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 32f7ec05dec63..c192bbfeeda2e 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -242,13 +242,6 @@ pub mod pallet { /// The duration of the Region. duration: Timeslice, }, - /// A Region has been dropped due to being out of date. - Dropped { - /// The Region which no longer exists. - region_id: RegionId, - /// The duration of the Region. - duration: Timeslice, - }, /// A new number of cores has been requested. CoreCountRequested { /// The number of cores requested. @@ -273,6 +266,70 @@ pub mod pallet { /// The workload of the now cancelled reservation. workload: Schedule, }, + /// A new lease has been created. + Leased { + /// The task to which a core will be assigned + task: TaskId, + /// The timeslice contained in the sale period after which this lease will + /// self-terminate (and therefore the earliest timeslice at which the lease may no + /// longer apply). + until: Timeslice, + }, + /// The sale rotation has been started and a new sale is imminent. + SalesStarted { + /// The nominal price of an Region of Bulk Coretime. + reserve_price: BalanceOf, + /// The maximum number of cores which this pallet will attempt to assign. + core_count: CoreIndex, + }, + /// The act of claiming revenue has begun. + RevenueClaimBegun { + /// The region to be claimed for. + region: RegionId, + /// The maximum number of timeslices which should be searched for claimed. + max_timeslices: Timeslice, + }, + /// A particular timeslice has a non-zero claim. + RevenueClaimItem { + /// The timeslice whose claim is being processed. + when: Timeslice, + /// The amount which was claimed at this timeslice. + amount: BalanceOf, + }, + RevenueClaimPaid { + /// The account to whom revenue has been paid. + who: T::AccountId, + /// The total amount of revenue claimed and paid. + amount: BalanceOf, + /// The next region which should be claimed for the continuation of this contribution. + next: Option, + }, + /// Some Instantaneous Coretime Pool credit has been purchased. + CreditPurchased { + /// The account which purchased the credit. + who: T::AccountId, + /// The Relay-chain account to which the credit will be made. + beneficiary: RelayAccountIdOf, + /// The amount of credit purchased. + amount: BalanceOf, + }, + /// A Region has been dropped due to being out of date. + RegionDropped { + /// The Region which no longer exists. + region_id: RegionId, + /// The duration of the Region. + duration: Timeslice, + }, + ContributionDropped { + /// The Region whose contribution is no longer exists. + region_id: RegionId, + }, + HistoryDropped { + /// The timeslice whose history is no longer available. + when: Timeslice, + /// The amount of revenue the system has taken. + revenue: BalanceOf, + }, } #[pallet::error] From ea7de69997a2b3a7cadb619f34d936c077c9e72c Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 17:11:13 +0100 Subject: [PATCH 044/131] Remove benchmark --- frame/broker/src/benchmarking.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index d0d33d8dee59e..8135bd6b9f4c2 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -26,20 +26,6 @@ use frame_system::RawOrigin; mod benches { use super::*; - /// Benchmarks the slowest path of `change_value`. - #[benchmark] - fn change_value() -> Result<(), BenchmarkError> { - let caller: T::AccountId = whitelisted_caller(); - - // You can mock the storage here: - DummyValue::::put(1); - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), 9); - - Ok(()) - } - // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); From 96102a3c516942207d80140b91fdcde06cc1ec67 Mon Sep 17 00:00:00 2001 From: Gav Date: Fri, 14 Jul 2023 17:53:25 +0100 Subject: [PATCH 045/131] Fix --- frame/core-fellowship/src/lib.rs | 2 +- frame/glutton/src/lib.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frame/core-fellowship/src/lib.rs b/frame/core-fellowship/src/lib.rs index 938dcff66c13e..2d7e4eff53856 100644 --- a/frame/core-fellowship/src/lib.rs +++ b/frame/core-fellowship/src/lib.rs @@ -328,7 +328,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::set_params())] #[pallet::call_index(1)] pub fn set_params(origin: OriginFor, params: Box>) -> DispatchResult { - T::ParamsOrigin::try_origin_or_root(origin)?; + T::ParamsOrigin::ensure_origin_or_root(origin)?; Params::::put(params.as_ref()); Self::deposit_event(Event::::ParamsChanged { params: *params }); Ok(()) diff --git a/frame/glutton/src/lib.rs b/frame/glutton/src/lib.rs index d0f1be0f19ea1..5b4b4721032e5 100644 --- a/frame/glutton/src/lib.rs +++ b/frame/glutton/src/lib.rs @@ -211,7 +211,7 @@ pub mod pallet { new_count: u32, witness_count: Option, ) -> DispatchResult { - T::AdminOrigin::try_origin_or_root(origin)?; + T::AdminOrigin::ensure_origin_or_root(origin)?; let current_count = TrashDataCount::::get(); ensure!( @@ -236,7 +236,7 @@ pub mod pallet { /// Only callable by Root or `AdminOrigin`. #[pallet::call_index(1)] pub fn set_compute(origin: OriginFor, compute: FixedU64) -> DispatchResult { - T::AdminOrigin::try_origin_or_root(origin)?; + T::AdminOrigin::ensure_origin_or_root(origin)?; ensure!(compute <= RESOURCE_HARD_LIMIT, Error::::InsaneLimit); Compute::::set(compute); @@ -254,7 +254,7 @@ pub mod pallet { /// Only callable by Root or `AdminOrigin`. #[pallet::call_index(2)] pub fn set_storage(origin: OriginFor, storage: FixedU64) -> DispatchResult { - T::AdminOrigin::try_origin_or_root(origin)?; + T::AdminOrigin::ensure_origin_or_root(origin)?; ensure!(storage <= RESOURCE_HARD_LIMIT, Error::::InsaneLimit); Storage::::set(storage); From dc02d157cd7ee0f5de847498bd532e61130647a2 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 15 Jul 2023 12:37:31 +0530 Subject: [PATCH 046/131] Adds benchmark for configure and some basic setup --- frame/broker/src/benchmarking.rs | 31 ++++++++++++++++++++++++++++++- frame/broker/src/mock.rs | 17 ++++++++++++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 8135bd6b9f4c2..159526041c06d 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -20,12 +20,41 @@ use super::*; use frame_benchmarking::v2::*; -use frame_system::RawOrigin; +use frame_support::traits::EnsureOrigin; +use sp_arithmetic::Perbill; + +fn new_config_record() -> ConfigRecordOf { + ConfigRecord { + advance_notice: 2u32.into(), + interlude_length: 1u32.into(), + leadin_length: 1u32.into(), + ideal_bulk_proportion: Default::default(), + limit_cores_offered: None, + region_length: 3, + renewal_bump: Perbill::from_percent(10), + contribution_timeout: 5, + } +} #[benchmarks] mod benches { use super::*; + #[benchmark] + fn configure() -> Result<(), BenchmarkError> { + let config = new_config_record::(); + + let origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, config.clone()); + + assert_eq!(Configuration::::get(), Some(config)); + + Ok(()) + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 546d558ff2204..fd5efa87292f7 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -19,15 +19,16 @@ use crate::{test_fungibles::TestFungibles, *}; use frame_support::{ - assert_ok, ensure, parameter_types, + assert_ok, ensure, ord_parameter_types, parameter_types, traits::{ + EitherOfDiverse, fungible::{Balanced, Credit, Inspect, ItemOf, Mutate}, nonfungible::Inspect as NftInspect, Hooks, OnUnbalanced, }, PalletId, }; -use frame_system::EnsureNever; +use frame_system::{EnsureRoot, EnsureSignedBy}; use sp_arithmetic::Perbill; use sp_core::{ConstU16, ConstU32, ConstU64, H256}; use sp_runtime::{ @@ -192,6 +193,11 @@ impl OnUnbalanced::Currency>> for IntoZero { } } +ord_parameter_types! { + pub const One: u64 = 1; +} +type EnsureOneOrRoot = EitherOfDiverse, EnsureSignedBy>; + impl crate::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = ItemOf, ()>, (), u64>; @@ -203,7 +209,7 @@ impl crate::Config for Test { type ConvertBalance = Identity; type WeightInfo = (); type PalletId = TestBrokerId; - type AdminOrigin = EnsureNever<()>; + type AdminOrigin = EnsureOneOrRoot; type PriceAdapter = Linear; } @@ -300,3 +306,8 @@ impl TestExt { }) } } + +pub fn new_test_ext() -> sp_io::TestExternalities { + let c = frame_system::GenesisConfig::default().build_storage::().unwrap(); + sp_io::TestExternalities::from(c) +} From 57015e7243893b827846dd4a29168a8200f1cb88 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 15 Jul 2023 14:32:08 +0530 Subject: [PATCH 047/131] Adds benchmark for reserve and unreserve --- frame/broker/src/benchmarking.rs | 67 +++++++++++++++++++++++++++++++- frame/broker/src/mock.rs | 3 +- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 159526041c06d..aeeef8c9be9af 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -19,6 +19,7 @@ use super::*; +use crate::CoreAssignment::Task; use frame_benchmarking::v2::*; use frame_support::traits::EnsureOrigin; use sp_arithmetic::Perbill; @@ -39,13 +40,15 @@ fn new_config_record() -> ConfigRecordOf { #[benchmarks] mod benches { use super::*; + use frame_support::storage::bounded_vec::BoundedVec; + use sp_core::Get; #[benchmark] - fn configure() -> Result<(), BenchmarkError> { + fn configure() -> Result<(), BenchmarkError> { let config = new_config_record::(); let origin = - T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] _(origin as T::RuntimeOrigin, config.clone()); @@ -55,6 +58,66 @@ mod benches { Ok(()) } + #[benchmark] + fn reserve() -> Result<(), BenchmarkError> { + // Max items for worst case + let mut items = Vec::new(); + for i in 0..80 { + items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); + } + let schedule = Schedule::truncate_from(items); + + // Assume MaxReservations to be almost filled for worst case + Reservations::::put( + BoundedVec::try_from(vec![ + schedule.clone(); + T::MaxReservedCores::get().saturating_sub(1) as usize + ]) + .unwrap(), + ); + + let origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, schedule.clone()); + + assert_eq!(Reservations::::get().len(), T::MaxReservedCores::get() as usize); + + Ok(()) + } + + #[benchmark] + fn unreserve( + n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, + ) -> Result<(), BenchmarkError> { + // Max items for worst case + let mut items = Vec::new(); + for i in 0..80 { + items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); + } + let schedule = Schedule::truncate_from(items); + + // Assume MaxReservations to be filled for worst case + Reservations::::put( + BoundedVec::try_from(vec![schedule.clone(); T::MaxReservedCores::get() as usize]) + .unwrap(), + ); + + let origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, n); + + assert_eq!( + Reservations::::get().len(), + T::MaxReservedCores::get().saturating_sub(1) as usize + ); + + Ok(()) + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index fd5efa87292f7..c243340d20b69 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -21,10 +21,9 @@ use crate::{test_fungibles::TestFungibles, *}; use frame_support::{ assert_ok, ensure, ord_parameter_types, parameter_types, traits::{ - EitherOfDiverse, fungible::{Balanced, Credit, Inspect, ItemOf, Mutate}, nonfungible::Inspect as NftInspect, - Hooks, OnUnbalanced, + EitherOfDiverse, Hooks, OnUnbalanced, }, PalletId, }; From e403464e7124e082e5eee592b3cfd7f44c483b5e Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 15 Jul 2023 17:00:42 +0530 Subject: [PATCH 048/131] Adds a couple of more benchmarks --- frame/broker/src/benchmarking.rs | 108 ++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 30 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index aeeef8c9be9af..e2cf8564ff4d0 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -23,6 +23,8 @@ use crate::CoreAssignment::Task; use frame_benchmarking::v2::*; use frame_support::traits::EnsureOrigin; use sp_arithmetic::Perbill; +use frame_support::storage::bounded_vec::BoundedVec; +use sp_core::Get; fn new_config_record() -> ConfigRecordOf { ConfigRecord { @@ -37,11 +39,36 @@ fn new_config_record() -> ConfigRecordOf { } } +fn new_schedule() -> Schedule { + // Max items for worst case + let mut items = Vec::new(); + for i in 0..80 { + items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); + } + Schedule::truncate_from(items) +} + +fn setup_reservations(n: u32) { + let schedule = new_schedule(); + + Reservations::::put( + BoundedVec::try_from(vec![schedule.clone(); n as usize]).unwrap(), + ); +} + +fn setup_leases(n: u32, task: u32, until: u32) { + Leases::::put( + BoundedVec::try_from(vec![ + LeaseRecordItem { task , until: until.into() }; + n as usize + ]) + .unwrap(), + ); +} + #[benchmarks] mod benches { use super::*; - use frame_support::storage::bounded_vec::BoundedVec; - use sp_core::Get; #[benchmark] fn configure() -> Result<(), BenchmarkError> { @@ -60,27 +87,16 @@ mod benches { #[benchmark] fn reserve() -> Result<(), BenchmarkError> { - // Max items for worst case - let mut items = Vec::new(); - for i in 0..80 { - items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); - } - let schedule = Schedule::truncate_from(items); - - // Assume MaxReservations to be almost filled for worst case - Reservations::::put( - BoundedVec::try_from(vec![ - schedule.clone(); - T::MaxReservedCores::get().saturating_sub(1) as usize - ]) - .unwrap(), - ); + let schedule = new_schedule(); + + // Assume Reservations to be almost filled for worst case + setup_reservations::(T::MaxReservedCores::get().saturating_sub(1)); let origin = T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(origin as T::RuntimeOrigin, schedule.clone()); + _(origin as T::RuntimeOrigin, schedule); assert_eq!(Reservations::::get().len(), T::MaxReservedCores::get() as usize); @@ -91,18 +107,8 @@ mod benches { fn unreserve( n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, ) -> Result<(), BenchmarkError> { - // Max items for worst case - let mut items = Vec::new(); - for i in 0..80 { - items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); - } - let schedule = Schedule::truncate_from(items); - - // Assume MaxReservations to be filled for worst case - Reservations::::put( - BoundedVec::try_from(vec![schedule.clone(); T::MaxReservedCores::get() as usize]) - .unwrap(), - ); + // Assume Reservations to be filled for worst case + setup_reservations::(T::MaxReservedCores::get()); let origin = T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; @@ -118,6 +124,48 @@ mod benches { Ok(()) } + #[benchmark] + fn set_lease() -> Result<(), BenchmarkError> { + let task = 1u32; + let until = 10u32.into(); + + // Assume Leases to be filled for worst case + setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), task, until); + + let origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, task, until); + + assert_eq!(Leases::::get().len(), T::MaxLeasedCores::get() as usize); + + Ok(()) + } + + #[benchmark] + fn start_sales(n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>,) -> Result<(), BenchmarkError> { + Configuration::::put(new_config_record::()); + + // Assume Reservations to be almost filled for worst case + setup_reservations::(T::MaxReservedCores::get()); + + // Assume Leases to be filled for worst case + setup_leases::(T::MaxLeasedCores::get(), 1, 10); + + let initial_price = 10u32.into(); + + let origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(origin as T::RuntimeOrigin, initial_price, n.try_into().unwrap()); + + assert!(SaleInfo::::get().is_some()); + + Ok(()) + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); From 478462a38cc59596615da1df5a3a81693b93435b Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 15 Jul 2023 17:04:28 +0200 Subject: [PATCH 049/131] Docs --- frame/broker/src/benchmarking.rs | 18 +++++++----------- frame/broker/src/implementation.rs | 5 ++--- frame/broker/src/lib.rs | 12 ++++++++++++ frame/glutton/src/lib.rs | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index e2cf8564ff4d0..f0675e9268e85 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -21,9 +21,8 @@ use super::*; use crate::CoreAssignment::Task; use frame_benchmarking::v2::*; -use frame_support::traits::EnsureOrigin; +use frame_support::{storage::bounded_vec::BoundedVec, traits::EnsureOrigin}; use sp_arithmetic::Perbill; -use frame_support::storage::bounded_vec::BoundedVec; use sp_core::Get; fn new_config_record() -> ConfigRecordOf { @@ -51,18 +50,13 @@ fn new_schedule() -> Schedule { fn setup_reservations(n: u32) { let schedule = new_schedule(); - Reservations::::put( - BoundedVec::try_from(vec![schedule.clone(); n as usize]).unwrap(), - ); + Reservations::::put(BoundedVec::try_from(vec![schedule.clone(); n as usize]).unwrap()); } fn setup_leases(n: u32, task: u32, until: u32) { Leases::::put( - BoundedVec::try_from(vec![ - LeaseRecordItem { task , until: until.into() }; - n as usize - ]) - .unwrap(), + BoundedVec::try_from(vec![LeaseRecordItem { task, until: until.into() }; n as usize]) + .unwrap(), ); } @@ -144,7 +138,9 @@ mod benches { } #[benchmark] - fn start_sales(n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>,) -> Result<(), BenchmarkError> { + fn start_sales( + n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, + ) -> Result<(), BenchmarkError> { Configuration::::put(new_config_record::()); // Assume Reservations to be almost filled for worst case diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index f7759a2f992c7..b3be502563299 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -308,9 +308,8 @@ impl Pallet { } pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { - T::OnRevenue::on_unbalanced(T::Currency::withdraw( - &who, amount, Exact, Expendable, Polite, - )?); + let credit = T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?; + T::OnRevenue::on_unbalanced(credit); Ok(()) } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index c192bbfeeda2e..e711aafb25aa3 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -296,6 +296,7 @@ pub mod pallet { /// The amount which was claimed at this timeslice. amount: BalanceOf, }, + /// A revenue claim has (possibly only in part) been paid. RevenueClaimPaid { /// The account to whom revenue has been paid. who: T::AccountId, @@ -320,16 +321,27 @@ pub mod pallet { /// The duration of the Region. duration: Timeslice, }, + /// Some historical Instantaneous Core Pool contribution record has been dropped. ContributionDropped { /// The Region whose contribution is no longer exists. region_id: RegionId, }, + /// Some historical Instantaneous Core Pool payment record has been dropped. HistoryDropped { /// The timeslice whose history is no longer available. when: Timeslice, /// The amount of revenue the system has taken. revenue: BalanceOf, }, + /// A Core has been assigned to one or more tasks and/or the Pool on the Relay-chain. + CoreAssigned { + /// The index of the Core which has been assigned. + core: CoreIndex, + /// The Relay-chain block at which this assignment should take effect. + when: RelayBlockNumberOf, + /// The workload to be done on the Core. + assignment: Schedule, + }, } #[pallet::error] diff --git a/frame/glutton/src/lib.rs b/frame/glutton/src/lib.rs index 5b4b4721032e5..b12a30d45036b 100644 --- a/frame/glutton/src/lib.rs +++ b/frame/glutton/src/lib.rs @@ -246,7 +246,7 @@ pub mod pallet { } /// Set how much of the remaining `proof_size` weight should be consumed by `on_idle`. - // + /// /// `1.0` means that all remaining `proof_size` will be consumed. The PoV benchmarking /// results that are used here are likely an over-estimation. 100% intended consumption will /// therefore translate to less than 100% actual consumption. From 01b54ab25bd8e42d3ec1b8eb3fe2f7686292857c Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 15 Jul 2023 17:04:42 +0200 Subject: [PATCH 050/131] Event --- frame/broker/src/implementation.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index b3be502563299..9a5423132e3f0 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -304,6 +304,7 @@ impl Pallet { } assignment.push(i); } + Self::deposit_event(Event::::CoreAssigned { core, when, assignment }); T::Coretime::assign_core(core, rc_begin, assignment, None); } From ea9c31e22db2e34b0a29919347dbe4799f88ffb3 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 15 Jul 2023 17:08:09 +0200 Subject: [PATCH 051/131] Fix --- frame/broker/src/implementation.rs | 4 ++-- frame/broker/src/lib.rs | 2 +- frame/broker/src/mock.rs | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 9a5423132e3f0..4b53bd9f8220c 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -304,8 +304,8 @@ impl Pallet { } assignment.push(i); } - Self::deposit_event(Event::::CoreAssigned { core, when, assignment }); - T::Coretime::assign_core(core, rc_begin, assignment, None); + T::Coretime::assign_core(core, rc_begin, assignment.clone(), None); + Self::deposit_event(Event::::CoreAssigned { core, when: rc_begin, assignment }); } pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index e711aafb25aa3..238647003ace2 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -340,7 +340,7 @@ pub mod pallet { /// The Relay-chain block at which this assignment should take effect. when: RelayBlockNumberOf, /// The workload to be done on the Core. - assignment: Schedule, + assignment: Vec<(CoreAssignment, PartsOf57600)>, }, } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index c243340d20b69..50ee6eafd2aaf 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -306,6 +306,7 @@ impl TestExt { } } +#[cfg(feature = "runtime-benchmarks")] pub fn new_test_ext() -> sp_io::TestExternalities { let c = frame_system::GenesisConfig::default().build_storage::().unwrap(); sp_io::TestExternalities::from(c) From ec8b54665bfb5830e0af89b6dd73b0af11433777 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sun, 16 Jul 2023 11:25:45 +0530 Subject: [PATCH 052/131] Adds benchmark for purchase --- frame/broker/src/benchmarking.rs | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index f0675e9268e85..c608e02387d55 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -19,11 +19,16 @@ use super::*; -use crate::CoreAssignment::Task; +use crate::{CoreAssignment::Task, Pallet as Broker}; use frame_benchmarking::v2::*; -use frame_support::{storage::bounded_vec::BoundedVec, traits::EnsureOrigin}; +use frame_support::{ + storage::bounded_vec::BoundedVec, + traits::{fungible::Mutate, EnsureOrigin, Hooks}, +}; +use frame_system::{Pallet as System, RawOrigin}; use sp_arithmetic::Perbill; use sp_core::Get; +use sp_runtime::Saturating; fn new_config_record() -> ConfigRecordOf { ConfigRecord { @@ -60,6 +65,13 @@ fn setup_leases(n: u32, task: u32, until: u32) { ); } +fn advance_to(b: u32) { + while System::::block_number() < b.into() { + System::::set_block_number(System::::block_number().saturating_add(1u32.into())); + Broker::::on_initialize(System::::block_number()); + } +} + #[benchmarks] mod benches { use super::*; @@ -123,7 +135,7 @@ mod benches { let task = 1u32; let until = 10u32.into(); - // Assume Leases to be filled for worst case + // Assume Leases to be almost filled for worst case setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), task, until); let origin = @@ -162,6 +174,37 @@ mod benches { Ok(()) } + // Todo: Check further for worst case + #[benchmark] + fn purchase() -> Result<(), BenchmarkError> { + Configuration::::put(new_config_record::()); + + // Assume Leases to be almost filled for worst case + setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), 1, 10); + + let admin_origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + Broker::::start_sales( + admin_origin, + 1u32.into(), + T::MaxReservedCores::get().try_into().unwrap(), + ) + .map_err(|_| BenchmarkError::Weightless)?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 100u32.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), 1u32.into()); + + assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(1u32.into())); + + Ok(()) + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); From 904fae51c5b8c91690c67499352042855c6b20e2 Mon Sep 17 00:00:00 2001 From: Gav Date: Sun, 16 Jul 2023 15:35:14 +0200 Subject: [PATCH 053/131] Dedup --- frame/broker/src/mock.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 50ee6eafd2aaf..2c96c354a806f 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -298,15 +298,13 @@ impl TestExt { } pub fn execute_with(self, f: impl Fn() -> R) -> R { - let c = frame_system::GenesisConfig::default().build_storage::().unwrap(); - sp_io::TestExternalities::from(c).execute_with(|| { + new_test_ext().execute_with(|| { assert_ok!(Broker::do_configure(self.0)); f() }) } } -#[cfg(feature = "runtime-benchmarks")] pub fn new_test_ext() -> sp_io::TestExternalities { let c = frame_system::GenesisConfig::default().build_storage::().unwrap(); sp_io::TestExternalities::from(c) From 2675695300c30ec7b7e7b593fda34db027fa758a Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 17 Jul 2023 10:55:28 +0200 Subject: [PATCH 054/131] Add some weight breakdowns --- frame/broker/src/dispatchable_impls.rs | 14 +-- frame/broker/src/implementation.rs | 143 ++++++++++++++----------- frame/broker/src/lib.rs | 24 ++++- frame/broker/src/types.rs | 19 ++-- frame/broker/src/weights.rs | 18 ++++ primitives/weights/src/weight_meter.rs | 30 +++++- 6 files changed, 160 insertions(+), 88 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 8c1c7e941352c..252486aebba5d 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -54,9 +54,9 @@ impl Pallet { let commit_timeslice = Self::latest_timeslice_ready_to_commit(&config); let status = StatusRecord { core_count, - pool_size: 0, - last_committed_timeslice: commit_timeslice.saturating_sub(1), + private_pool_size: 0, system_pool_size: 0, + last_committed_timeslice: commit_timeslice.saturating_sub(1), last_timeslice: Self::current_timeslice(), }; let now = frame_system::Pallet::::block_number(); @@ -293,8 +293,8 @@ impl Pallet { { Workplan::::insert(&workplan_key, &workplan); let size = region_id.part.count_ones() as i32; - InstaPoolIo::::mutate(region_id.begin, |a| a.total.saturating_accrue(size)); - InstaPoolIo::::mutate(region.end, |a| a.total.saturating_reduce(size)); + InstaPoolIo::::mutate(region_id.begin, |a| a.private.saturating_accrue(size)); + InstaPoolIo::::mutate(region.end, |a| a.private.saturating_reduce(size)); let record = ContributionRecord { length: duration, payee }; InstaPoolContribution::::insert(®ion_id, record); } @@ -330,13 +330,13 @@ impl Pallet { None => break, }; let p = total_payout.saturating_mul(contributed_parts.into()) / - pool_record.total_contributions.into(); + pool_record.private_contributions.into(); payout.saturating_accrue(p); - pool_record.total_contributions.saturating_reduce(contributed_parts); + pool_record.private_contributions.saturating_reduce(contributed_parts); let remaining_payout = total_payout.saturating_sub(payout); - if !remaining_payout.is_zero() && pool_record.total_contributions > 0 { + if !remaining_payout.is_zero() && pool_record.private_contributions > 0 { pool_record.maybe_payout = Some(remaining_payout); InstaPoolHistory::::insert(r, &pool_record); } else { diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/implementation.rs index 4b53bd9f8220c..b20cfb8330e1b 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/implementation.rs @@ -4,8 +4,9 @@ use frame_support::{ traits::{ fungible::Balanced, tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, - Defensive, OnUnbalanced, + OnUnbalanced, }, + weights::WeightMeter, }; use sp_arithmetic::{ traits::{SaturatedConversion, Saturating, Zero}, @@ -39,14 +40,30 @@ impl Pallet { } } - /// Attempt to tick things along. Will only do anything if the `Status.last_timeslice` is - /// less than `Self::current_timeslice`. - pub(crate) fn do_tick() -> DispatchResult { - let mut status = Status::::get().ok_or(Error::::Uninitialized)?; - let config = Configuration::::get().ok_or(Error::::Uninitialized)?; + /// Attempt to tick things along. + /// + /// This may do several things: + /// - Processes notifications of the core count changing + /// - Processes reports of Instantaneous Core Market Revenue + /// - Commit a timeslice + /// - Rotate the sale period + /// - Request revenue information for a previous timeslice + /// - Initialize an instantaneous core pool historical revenue record + pub(crate) fn do_tick() -> Weight { + let (mut status, config) = match (Status::::get(), Configuration::::get()) { + (Some(s), Some(c)) => (s, c), + _ => return Weight::zero(), + }; + + let mut meter = WeightMeter::max_limit(); - Self::process_core_count(); - let _ = Self::process_revenue().defensive(); + if Self::process_core_count() { + meter.consume(T::WeightInfo::process_core_count()); + } + + if Self::process_revenue() { + meter.consume(T::WeightInfo::process_revenue()); + } if let Some(commit_timeslice) = Self::next_timeslice_to_commit(&config, &status) { status.last_committed_timeslice = commit_timeslice; @@ -54,15 +71,18 @@ impl Pallet { if commit_timeslice >= sale.region_begin { // Sale can be rotated. Self::rotate_sale(sale, &config, &status); + meter.consume(T::WeightInfo::rotate_sale()); } } Self::process_pool(commit_timeslice, &mut status); + meter.consume(T::WeightInfo::process_pool()); let timeslice_period = T::TimeslicePeriod::get(); let rc_begin = RelayBlockNumberOf::::from(commit_timeslice) * timeslice_period; for core in 0..status.core_count { Self::process_core_schedule(commit_timeslice, rc_begin, core); + meter.consume(T::WeightInfo::process_core_schedule()); } } @@ -70,12 +90,13 @@ impl Pallet { if status.last_timeslice < current_timeslice { let rc_block = T::TimeslicePeriod::get() * current_timeslice.into(); T::Coretime::request_revenue_info_at(rc_block); + meter.consume(T::WeightInfo::request_revenue_info_at()); status.last_timeslice.saturating_inc(); } Status::::put(&status); - Ok(()) + meter.consumed } /// Begin selling for the next sale period. @@ -94,19 +115,13 @@ impl Pallet { // Clean up the old sale - we need to use up any unused cores by putting them into the // InstaPool. - let mut total_old_pooled: SignedPartCount = 0; + let mut old_pooled: SignedPartCount = 0; for i in old_sale.cores_sold..old_sale.cores_offered { - total_old_pooled.saturating_accrue(80); + old_pooled.saturating_accrue(80); Workplan::::insert((old_sale.region_begin, old_sale.first_core + i), &just_pool); } - InstaPoolIo::::mutate(old_sale.region_begin, |r| { - r.total.saturating_accrue(total_old_pooled); - r.system.saturating_accrue(total_old_pooled); - }); - InstaPoolIo::::mutate(old_sale.region_end, |r| { - r.total.saturating_reduce(total_old_pooled); - r.system.saturating_reduce(total_old_pooled); - }); + InstaPoolIo::::mutate(old_sale.region_begin, |r| r.system.saturating_accrue(old_pooled)); + InstaPoolIo::::mutate(old_sale.region_end, |r| r.system.saturating_reduce(old_pooled)); // Calculate the start price for the sale after. let reserve_price = { @@ -139,14 +154,8 @@ impl Pallet { Workplan::::insert((region_begin, first_core), &schedule); first_core.saturating_inc(); } - InstaPoolIo::::mutate(region_begin, |r| { - r.total.saturating_accrue(total_pooled); - r.system.saturating_accrue(total_pooled); - }); - InstaPoolIo::::mutate(region_end, |r| { - r.total.saturating_reduce(total_pooled); - r.system.saturating_reduce(total_pooled); - }); + InstaPoolIo::::mutate(region_begin, |r| r.system.saturating_accrue(total_pooled)); + InstaPoolIo::::mutate(region_end, |r| r.system.saturating_reduce(total_pooled)); let mut leases = Leases::::get(); // Can morph to a renewable as long as it's >=begin and Pallet { false } - fn process_revenue() -> Result { - if let Some((until, amount)) = T::Coretime::check_notify_revenue_info() { - let timeslice: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); - let mut amount = T::ConvertBalance::convert_back(amount); - if amount.is_zero() { - InstaPoolHistory::::remove(timeslice); - return Ok(true) - } - let mut pool_record = InstaPoolHistory::::get(timeslice).unwrap_or_default(); - ensure!(pool_record.maybe_payout.is_none(), Error::::RevenueAlreadyKnown); - ensure!( - pool_record.total_contributions >= pool_record.system_contributions, - Error::::InvalidContributions, - ); - ensure!(pool_record.total_contributions > 0, Error::::InvalidContributions); - - // Payout system InstaPool Cores. - let system_payout = amount.saturating_mul(pool_record.system_contributions.into()) / - pool_record.total_contributions.into(); - let _ = Self::charge(&Self::account_id(), system_payout); - pool_record - .total_contributions - .saturating_reduce(pool_record.system_contributions); - pool_record.system_contributions = 0; - amount.saturating_reduce(system_payout); - - if !amount.is_zero() && pool_record.total_contributions > 0 { - pool_record.maybe_payout = Some(amount); - InstaPoolHistory::::insert(timeslice, &pool_record); - } else { - InstaPoolHistory::::remove(timeslice); - } - return Ok(true) + fn process_revenue() -> bool { + let (until, amount) = match T::Coretime::check_notify_revenue_info() { + Some(x) => x, + None => return false, + }; + let when: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); + let mut revenue = T::ConvertBalance::convert_back(amount); + if revenue.is_zero() { + Self::deposit_event(Event::::HistoryDropped { when, revenue }); + InstaPoolHistory::::remove(when); + return true + } + let mut r = InstaPoolHistory::::get(when).unwrap_or_default(); + if r.maybe_payout.is_some() { + Self::deposit_event(Event::::HistoryIgnored { when, revenue }); + return true + } + // Payout system InstaPool Cores. + let total_contrib = r.system_contributions.saturating_add(r.private_contributions); + let system_payout = revenue.saturating_mul(r.system_contributions.into()) / + total_contrib.into(); + let _ = Self::charge(&Self::account_id(), system_payout); + revenue.saturating_reduce(system_payout); + + if !revenue.is_zero() && r.private_contributions > 0 { + r.maybe_payout = Some(revenue); + InstaPoolHistory::::insert(when, &r); + Self::deposit_event(Event::::ClaimsReady { + when, + system_payout, + private_payout: revenue, + private_contributions: r.private_contributions, + }); + } else { + InstaPoolHistory::::remove(when); + Self::deposit_event(Event::::HistoryDropped { when, revenue }); } - Ok(false) + true } pub fn sale_price(sale: &SaleInfoRecordOf, now: T::BlockNumber) -> BalanceOf { @@ -255,11 +267,12 @@ impl Pallet { fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); - status.pool_size = (status.pool_size as i32).saturating_add(pool_io.total) as u32; - status.system_pool_size = - (status.system_pool_size as i32).saturating_add(pool_io.system) as u32; + status.private_pool_size = (status.private_pool_size as SignedPartCount) + .saturating_add(pool_io.private) as PartCount; + status.system_pool_size = (status.system_pool_size as SignedPartCount) + .saturating_add(pool_io.system) as PartCount; let record = InstaPoolHistoryRecord { - total_contributions: status.pool_size, + private_contributions: status.private_pool_size, system_contributions: status.system_pool_size, maybe_payout: None, }; diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 238647003ace2..2776efddefaff 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -333,6 +333,26 @@ pub mod pallet { /// The amount of revenue the system has taken. revenue: BalanceOf, }, + /// Some historical Instantaneous Core Pool payment record has been ignored because the + /// timeslice was already known. Governance may need to intervene. + HistoryIgnored { + /// The timeslice whose history is was ignored. + when: Timeslice, + /// The amount of revenue which was ignored. + revenue: BalanceOf, + }, + /// Some historical Instantaneous Core Pool Revenue is ready for payout claims. + ClaimsReady { + /// The timeslice whose history is available. + when: Timeslice, + /// The amount of revenue the Polkadot System has already taken. + system_payout: BalanceOf, + /// The total amount of revenue remaining to be claimed. + private_payout: BalanceOf, + /// The total amount of Core Mask bits contributed privately (i.e. excluding the + /// Polkadot System). + private_contributions: PartCount, + }, /// A Core has been assigned to one or more tasks and/or the Pool on the Relay-chain. CoreAssigned { /// The index of the Core which has been assigned. @@ -411,9 +431,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_initialize(_now: T::BlockNumber) -> Weight { - // NOTE: This may need some clever benchmarking... - let _ = Self::do_tick(); - Weight::zero() + Self::do_tick() } } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 066a5ec9ed987..085a116f8ce2e 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -95,13 +95,13 @@ pub type ContributionRecordOf = ContributionRecord<::AccountId> #[derive(Encode, Decode, Clone, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct InstaPoolHistoryRecord { /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block - /// of a Polkadot Core) contributed over a timeslice minus any contributions which have - /// already been paid out. - pub total_contributions: PartCount, + /// of a Polkadot Core) contributed from purchased Bulk Coretime over a timeslice minus any + /// contributions which have already been paid out. + pub private_contributions: PartCount, /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block /// of a Polkadot Core) contributed by the Polkadot System in this timeslice. pub system_contributions: PartCount, - /// The payout remaining for the `total_contributions`, or `None` if the revenue is not yet + /// The payout remaining for the `private_contributions`, or `None` if the revenue is not yet /// known. pub maybe_payout: Option, } @@ -153,7 +153,7 @@ pub struct StatusRecord { pub core_count: CoreIndex, /// The current size of the Instantaneous Coretime Pool, measured in /// Regularity Parts or 1/80th of a single block of a Polkadot Core. - pub pool_size: PartCount, + pub private_pool_size: PartCount, /// The current amount of the Instantaneous Coretime Pool which is provided by the Polkadot /// System, rather than provided as a result of privately operated Coretime. pub system_pool_size: PartCount, @@ -168,10 +168,11 @@ pub struct StatusRecord { Encode, Decode, Clone, Copy, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen, )] pub struct PoolIoRecord { - /// The total change of the pool, measured in Regularity Parts. - pub total: SignedPartCount, - /// The total change of the portion of the pool supplied by the Polkaot System, - /// measured in Regularity Parts. + /// The total change of the portion of the pool supplied by purchased Bulk Coretime, measured + /// in Regularity Parts. + pub private: SignedPartCount, + /// The total change of the portion of the pool supplied by the Polkaot System, measured in + /// Regularity Parts. pub system: SignedPartCount, } diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index 6c1d6b54a9cec..a5cbd01c12fde 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -44,6 +44,12 @@ pub trait WeightInfo { fn drop_contribution() -> Weight; fn drop_history() -> Weight; fn request_core_count() -> Weight; + fn process_core_count() -> Weight; + fn process_revenue() -> Weight; + fn rotate_sale() -> Weight; + fn process_pool() -> Weight; + fn process_core_schedule() -> Weight; + fn request_revenue_info_at() -> Weight; } /// Weights for `pallet-broker` using the Substrate node and recommended hardware. @@ -67,6 +73,12 @@ impl WeightInfo for SubstrateWeight { fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } fn drop_history() -> Weight { Weight::from_parts(123, 456) } fn request_core_count() -> Weight { Weight::from_parts(123, 456) } + fn process_core_count() -> Weight { Weight::from_parts(123, 456) } + fn process_revenue() -> Weight { Weight::from_parts(123, 456) } + fn rotate_sale() -> Weight { Weight::from_parts(123, 456) } + fn process_pool() -> Weight { Weight::from_parts(123, 456) } + fn process_core_schedule() -> Weight { Weight::from_parts(123, 456) } + fn request_revenue_info_at() -> Weight { Weight::from_parts(123, 456) } } // For backwards compatibility and tests @@ -89,4 +101,10 @@ impl WeightInfo for () { fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } fn drop_history() -> Weight { Weight::from_parts(123, 456) } fn request_core_count() -> Weight { Weight::from_parts(123, 456) } + fn process_core_count() -> Weight { Weight::from_parts(123, 456) } + fn process_revenue() -> Weight { Weight::from_parts(123, 456) } + fn rotate_sale() -> Weight { Weight::from_parts(123, 456) } + fn process_pool() -> Weight { Weight::from_parts(123, 456) } + fn process_core_schedule() -> Weight { Weight::from_parts(123, 456) } + fn request_revenue_info_at() -> Weight { Weight::from_parts(123, 456) } } diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index ab7b6c63ed383..6accf42ae8fe4 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -72,27 +72,49 @@ impl WeightMeter { } /// Consume some weight and defensively fail if it is over the limit. Saturate in any case. + #[deprecated = "Use `consume` instead"] pub fn defensive_saturating_accrue(&mut self, w: Weight) { + self.consume(w); + } + + /// Consume some weight and defensively fail if it is over the limit. Saturate in any case. + /// + /// This is provided as a less noisy version of `defensive_saturating_accrue`. + pub fn consume(&mut self, w: Weight) { self.consumed.saturating_accrue(w); debug_assert!(self.consumed.all_lte(self.limit), "Weight counter overflow"); } - /// Consume the given weight after checking that it can be consumed. Otherwise do nothing. + /// Consume the given weight after checking that it can be consumed and return `true`. Otherwise + /// do nothing and return `false`. + #[deprecated = "Use `try_consume` instead"] pub fn check_accrue(&mut self, w: Weight) -> bool { - self.consumed.checked_add(&w).map_or(false, |test| { + self.try_consume(w).is_ok() + } + + /// Consume the given weight after checking that it can be consumed and return `Ok`. Otherwise + /// do nothing and return `Err`. + pub fn try_consume(&mut self, w: Weight) -> Result<(), ()> { + self.consumed.checked_add(&w).map_or(Err(()), |test| { if test.any_gt(self.limit) { - false + Err(()) } else { self.consumed = test; - true + Ok(()) } }) } /// Check if the given weight can be consumed. + #[deprecated = "Use `can_consume` instead"] pub fn can_accrue(&self, w: Weight) -> bool { self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) } + + /// Check if the given weight can be consumed. + pub fn can_consume(&self, w: Weight) -> bool { + self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) + } } #[cfg(test)] From c112d095cd4d5232727c6953e2f1258aa2c8eb20 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 17 Jul 2023 11:01:47 +0200 Subject: [PATCH 055/131] Repotting --- frame/broker/src/dispatchable_impls.rs | 1 - frame/broker/src/lib.rs | 6 +- .../src/{implementation.rs => tick_impls.rs} | 95 +------------- frame/broker/src/utility_impls.rs | 121 ++++++++++++++++++ frame/broker/src/utils.rs | 21 --- 5 files changed, 126 insertions(+), 118 deletions(-) rename frame/broker/src/{implementation.rs => tick_impls.rs} (76%) create mode 100644 frame/broker/src/utility_impls.rs delete mode 100644 frame/broker/src/utils.rs diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 252486aebba5d..0d81aa544fd0b 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -304,7 +304,6 @@ impl Pallet { Ok(()) } - // TODO: Consolidation of InstaPoolHistory records as long as contributors don't change. pub(crate) fn do_claim_revenue( mut region: RegionId, max_timeslices: Timeslice, diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 2776efddefaff..6f8651efefd0f 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -25,13 +25,13 @@ mod benchmarking; mod core_part; mod coretime_interface; mod dispatchable_impls; -mod implementation; mod mock; mod nonfungible_impl; mod test_fungibles; mod tests; +mod tick_impls; mod types; -mod utils; +mod utility_impls; pub mod weights; pub use weights::WeightInfo; @@ -41,7 +41,7 @@ pub use core_part::*; pub use coretime_interface::*; pub use nonfungible_impl::*; pub use types::*; -pub use utils::*; +pub use utility_impls::*; #[frame_support::pallet] pub mod pallet { diff --git a/frame/broker/src/implementation.rs b/frame/broker/src/tick_impls.rs similarity index 76% rename from frame/broker/src/implementation.rs rename to frame/broker/src/tick_impls.rs index b20cfb8330e1b..e75e772767f80 100644 --- a/frame/broker/src/implementation.rs +++ b/frame/broker/src/tick_impls.rs @@ -1,45 +1,16 @@ use super::*; use frame_support::{ - pallet_prelude::{DispatchResult, *}, - traits::{ - fungible::Balanced, - tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, - OnUnbalanced, - }, + pallet_prelude::*, weights::WeightMeter, }; use sp_arithmetic::{ traits::{SaturatedConversion, Saturating, Zero}, FixedPointNumber, }; -use sp_runtime::traits::{AccountIdConversion, ConvertBack}; +use sp_runtime::traits::ConvertBack; use CompletionStatus::Complete; impl Pallet { - pub fn current_timeslice() -> Timeslice { - let latest = T::Coretime::latest(); - let timeslice_period = T::TimeslicePeriod::get(); - (latest / timeslice_period).saturated_into() - } - - pub fn latest_timeslice_ready_to_commit(config: &ConfigRecordOf) -> Timeslice { - let latest = T::Coretime::latest(); - let advanced = latest.saturating_add(config.advance_notice); - let timeslice_period = T::TimeslicePeriod::get(); - (advanced / timeslice_period).saturated_into() - } - - pub fn next_timeslice_to_commit( - config: &ConfigRecordOf, - status: &StatusRecord, - ) -> Option { - if status.last_committed_timeslice < Self::latest_timeslice_ready_to_commit(config) { - Some(status.last_committed_timeslice + 1) - } else { - None - } - } - /// Attempt to tick things along. /// /// This may do several things: @@ -207,10 +178,6 @@ impl Pallet { Some(()) } - pub fn account_id() -> T::AccountId { - T::PalletId::get().into_account_truncating() - } - fn process_core_count() -> bool { if let Some(core_count) = T::Coretime::check_notify_core_count() { Status::::mutate_extant(|c| c.core_count = core_count); @@ -260,11 +227,6 @@ impl Pallet { true } - pub fn sale_price(sale: &SaleInfoRecordOf, now: T::BlockNumber) -> BalanceOf { - lerp(now, sale.sale_start, sale.leadin_length, sale.start_price, sale.reserve_price) - .unwrap_or(sale.start_price) - } - fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(timeslice); status.private_pool_size = (status.private_pool_size as SignedPartCount) @@ -320,57 +282,4 @@ impl Pallet { T::Coretime::assign_core(core, rc_begin, assignment.clone(), None); Self::deposit_event(Event::::CoreAssigned { core, when: rc_begin, assignment }); } - - pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { - let credit = T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?; - T::OnRevenue::on_unbalanced(credit); - Ok(()) - } - - pub(crate) fn issue( - core: CoreIndex, - begin: Timeslice, - end: Timeslice, - owner: T::AccountId, - paid: Option>, - ) -> RegionId { - let id = RegionId { begin, core, part: CoreMask::complete() }; - let record = RegionRecord { end, owner, paid }; - Regions::::insert(&id, &record); - id - } - - pub(crate) fn utilize( - mut region_id: RegionId, - maybe_check_owner: Option, - finality: Finality, - ) -> Result)>, Error> { - let status = Status::::get().ok_or(Error::::Uninitialized)?; - let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; - - if let Some(check_owner) = maybe_check_owner { - ensure!(check_owner == region.owner, Error::::NotOwner); - } - - Regions::::remove(®ion_id); - - let last_committed_timeslice = status.last_committed_timeslice; - if region_id.begin <= last_committed_timeslice { - region_id.begin = last_committed_timeslice + 1; - if region_id.begin >= region.end { - let duration = region.end.saturating_sub(region_id.begin); - Self::deposit_event(Event::RegionDropped { region_id, duration }); - return Ok(None) - } - } else { - Workplan::::mutate_extant((region_id.begin, region_id.core), |p| { - p.retain(|i| (i.part & region_id.part).is_void()) - }); - } - if finality == Finality::Provisional { - Regions::::insert(®ion_id, ®ion); - } - - Ok(Some((region_id, region))) - } } diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs new file mode 100644 index 0000000000000..775a1e45eae56 --- /dev/null +++ b/frame/broker/src/utility_impls.rs @@ -0,0 +1,121 @@ +use super::*; +use frame_support::{ + pallet_prelude::{DispatchResult, *}, + traits::{ + fungible::Balanced, + tokens::{Fortitude::Polite, Precision::Exact, Preservation::Expendable}, + OnUnbalanced, + }, +}; +use sp_arithmetic::{ + traits::{SaturatedConversion, Saturating, Bounded}, +}; +use sp_runtime::traits::AccountIdConversion; + +impl Pallet { + pub fn current_timeslice() -> Timeslice { + let latest = T::Coretime::latest(); + let timeslice_period = T::TimeslicePeriod::get(); + (latest / timeslice_period).saturated_into() + } + + pub fn latest_timeslice_ready_to_commit(config: &ConfigRecordOf) -> Timeslice { + let latest = T::Coretime::latest(); + let advanced = latest.saturating_add(config.advance_notice); + let timeslice_period = T::TimeslicePeriod::get(); + (advanced / timeslice_period).saturated_into() + } + + pub fn next_timeslice_to_commit( + config: &ConfigRecordOf, + status: &StatusRecord, + ) -> Option { + if status.last_committed_timeslice < Self::latest_timeslice_ready_to_commit(config) { + Some(status.last_committed_timeslice + 1) + } else { + None + } + } + + pub fn account_id() -> T::AccountId { + T::PalletId::get().into_account_truncating() + } + + pub fn sale_price(sale: &SaleInfoRecordOf, now: T::BlockNumber) -> BalanceOf { + lerp(now, sale.sale_start, sale.leadin_length, sale.start_price, sale.reserve_price) + .unwrap_or(sale.start_price) + } + + pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + let credit = T::Currency::withdraw(&who, amount, Exact, Expendable, Polite)?; + T::OnRevenue::on_unbalanced(credit); + Ok(()) + } + + pub(crate) fn issue( + core: CoreIndex, + begin: Timeslice, + end: Timeslice, + owner: T::AccountId, + paid: Option>, + ) -> RegionId { + let id = RegionId { begin, core, part: CoreMask::complete() }; + let record = RegionRecord { end, owner, paid }; + Regions::::insert(&id, &record); + id + } + + pub(crate) fn utilize( + mut region_id: RegionId, + maybe_check_owner: Option, + finality: Finality, + ) -> Result)>, Error> { + let status = Status::::get().ok_or(Error::::Uninitialized)?; + let region = Regions::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + + if let Some(check_owner) = maybe_check_owner { + ensure!(check_owner == region.owner, Error::::NotOwner); + } + + Regions::::remove(®ion_id); + + let last_committed_timeslice = status.last_committed_timeslice; + if region_id.begin <= last_committed_timeslice { + region_id.begin = last_committed_timeslice + 1; + if region_id.begin >= region.end { + let duration = region.end.saturating_sub(region_id.begin); + Self::deposit_event(Event::RegionDropped { region_id, duration }); + return Ok(None) + } + } else { + Workplan::::mutate_extant((region_id.begin, region_id.core), |p| { + p.retain(|i| (i.part & region_id.part).is_void()) + }); + } + if finality == Finality::Provisional { + Regions::::insert(®ion_id, ®ion); + } + + Ok(Some((region_id, region))) + } +} + +pub fn lerp, S: TryInto + TryFrom + Bounded>( + v: T, + a: T, + d: T, + x: S, + y: S, +) -> Option { + use sp_arithmetic::{ + helpers_128bit::multiply_by_rational_with_rounding, Rounding::NearestPrefUp, + }; + let v: u128 = v.try_into().ok()?; + let a: u128 = a.try_into().ok()?; + let d: u128 = d.try_into().ok()?; + let r: u128 = x.try_into().ok()?; + let s: u128 = y.try_into().ok()?; + let rsd = r.max(s) - r.min(s); + let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; + if r < s { r + td } else { r - td }.try_into().ok() +} diff --git a/frame/broker/src/utils.rs b/frame/broker/src/utils.rs deleted file mode 100644 index 17eba5bef7d63..0000000000000 --- a/frame/broker/src/utils.rs +++ /dev/null @@ -1,21 +0,0 @@ -use sp_arithmetic::traits::Bounded; - -pub fn lerp, S: TryInto + TryFrom + Bounded>( - v: T, - a: T, - d: T, - x: S, - y: S, -) -> Option { - use sp_arithmetic::{ - helpers_128bit::multiply_by_rational_with_rounding, Rounding::NearestPrefUp, - }; - let v: u128 = v.try_into().ok()?; - let a: u128 = a.try_into().ok()?; - let d: u128 = d.try_into().ok()?; - let r: u128 = x.try_into().ok()?; - let s: u128 = y.try_into().ok()?; - let rsd = r.max(s) - r.min(s); - let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; - if r < s { r + td } else { r - td }.try_into().ok() -} From 81ba2fac331bff972cd40e9e5281e8584076a7ac Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:02:26 +0530 Subject: [PATCH 056/131] Adds more benchmarks --- frame/broker/src/benchmarking.rs | 256 ++++++++++++++++++++++++++++--- 1 file changed, 237 insertions(+), 19 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index c608e02387d55..794b737d210cf 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -30,6 +30,8 @@ use sp_arithmetic::Perbill; use sp_core::Get; use sp_runtime::Saturating; +const SEED: u32 = 0; + fn new_config_record() -> ConfigRecordOf { ConfigRecord { advance_notice: 2u32.into(), @@ -72,9 +74,27 @@ fn advance_to(b: u32) { } } +fn setup_and_start_sale() -> Result<(), BenchmarkError> { + Configuration::::put(new_config_record::()); + + // Assume Leases to be almost filled for worst case + setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), 1, 10); + + let core_index: u16 = T::MaxReservedCores::get().try_into().unwrap(); + + Broker::::do_start_sales( + 10u32.into(), + core_index + ) + .map_err(|_| BenchmarkError::Weightless)?; + + Ok(()) +} + #[benchmarks] mod benches { use super::*; + use crate::Finality::Final; #[benchmark] fn configure() -> Result<(), BenchmarkError> { @@ -150,9 +170,7 @@ mod benches { } #[benchmark] - fn start_sales( - n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, - ) -> Result<(), BenchmarkError> { + fn start_sales() -> Result<(), BenchmarkError> { Configuration::::put(new_config_record::()); // Assume Reservations to be almost filled for worst case @@ -167,40 +185,240 @@ mod benches { T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(origin as T::RuntimeOrigin, initial_price, n.try_into().unwrap()); + _(origin as T::RuntimeOrigin, initial_price, 12); //Todo: Check with Gav assert!(SaleInfo::::get().is_some()); Ok(()) } + + #[benchmark] + fn purchase() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), 10u32.into()); + + assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(10u32.into())); + + Ok(()) + } + + #[benchmark] + fn renew() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let core_index: u16 = T::MaxReservedCores::get().try_into().unwrap(); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 20u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + Broker::::do_assign(region, None, 1001, Final).map_err(|_| BenchmarkError::Weightless)?; + + advance_to::(6); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), core_index.saturating_sub(1)); + + assert!(AllowedRenewals::::get(core_index.saturating_sub(1)).is_some()); + + Ok(()) + } + + #[benchmark] + fn transfer() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + let recipient: T::AccountId = account("recipient", 0, SEED); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, recipient); + + Ok(()) + } + + #[benchmark] + fn partition() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, 2); + + Ok(()) + } + + #[benchmark] + fn interlace() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, 0x00000_fffff_fffff_00000.into()); + + Ok(()) + } + + #[benchmark] + fn assign() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, 1000, Final); + + Ok(()) + } + + #[benchmark] + fn pool() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + let recipient: T::AccountId = account("recipient", 0, SEED); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, recipient, Final); + + Ok(()) + } + + #[benchmark] + fn claim_revenue() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + let recipient: T::AccountId = account("recipient", 0, SEED); + + Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region, 100); + + Ok(()) + } // Todo: Check further for worst case #[benchmark] - fn purchase() -> Result<(), BenchmarkError> { - Configuration::::put(new_config_record::()); + fn purchase_credit() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; - // Assume Leases to be almost filled for worst case - setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), 1, 10); + advance_to::(2); - let admin_origin = - T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 30u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + let recipient: T::AccountId = account("recipient", 0, SEED); + + Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + + let beneficiary: RelayAccountIdOf = account("beneficiary", 0, SEED); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), 20u32.into(), beneficiary); + + Ok(()) + } - Broker::::start_sales( - admin_origin, - 1u32.into(), - T::MaxReservedCores::get().try_into().unwrap(), - ) - .map_err(|_| BenchmarkError::Weightless)?; + #[benchmark] + fn drop_region() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 100u32.into()); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + advance_to::(12); #[extrinsic_call] - _(RawOrigin::Signed(caller), 1u32.into()); + _(RawOrigin::Signed(caller), region); + + Ok(()) + } - assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(1u32.into())); + #[benchmark] + fn drop_contribution() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance(&caller.clone(), 10u32.into()); + + let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + + let recipient: T::AccountId = account("recipient", 0, SEED); + + Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + + advance_to::(26); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), region); + + Ok(()) + } + + #[benchmark] + fn request_core_count( + n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, + ) -> Result<(), BenchmarkError> { + let admin_origin = + T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; + + #[extrinsic_call] + _(admin_origin as T::RuntimeOrigin, n.try_into().unwrap()); Ok(()) } From 60c11f1bbe3a45da8d9ff38af4d5a18bdda1228b Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 17 Jul 2023 11:39:52 +0200 Subject: [PATCH 057/131] Renaming and one more event --- frame/broker/README.md | 5 ++ frame/broker/src/lib.rs | 13 +++- frame/broker/src/mock.rs | 6 +- frame/broker/src/tick_impls.rs | 120 +++++++++++++++++---------------- frame/broker/src/types.rs | 36 +++++----- 5 files changed, 98 insertions(+), 82 deletions(-) diff --git a/frame/broker/README.md b/frame/broker/README.md index 4f0b688bcb393..b62eebbed177e 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -6,6 +6,11 @@ Properly described in RFC-0001 Agile Coretime. ## Implemnentation Specifics +### Core Mask Bits + +This is 1/80th of a Polkadot Core per timeslice. Assuming timeslices are 80 blocks, then this +indicates usage of a single core one time over a timeslice. + ### The Sale ```nocompile diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 6f8651efefd0f..6b65d25db2898 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -326,6 +326,16 @@ pub mod pallet { /// The Region whose contribution is no longer exists. region_id: RegionId, }, + /// Some historical Instantaneous Core Pool payment record has been initialized. + HistoryInitialized { + /// The timeslice whose history has been initialized. + when: Timeslice, + /// The amount of privately contributed Coretime to the Instantaneous Coretime Pool. + private_pool_size: CoreMaskBitCount, + /// The amount of Coretime contributed to the Instantaneous Coretime Pool by the + /// Polkadot System. + system_pool_size: CoreMaskBitCount, + }, /// Some historical Instantaneous Core Pool payment record has been dropped. HistoryDropped { /// The timeslice whose history is no longer available. @@ -349,9 +359,6 @@ pub mod pallet { system_payout: BalanceOf, /// The total amount of revenue remaining to be claimed. private_payout: BalanceOf, - /// The total amount of Core Mask bits contributed privately (i.e. excluding the - /// Polkadot System). - private_contributions: PartCount, }, /// A Core has been assigned to one or more tasks and/or the Pool on the Relay-chain. CoreAssigned { diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 2c96c354a806f..6b80920a4eec2 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -95,7 +95,7 @@ parameter_types! { pub static CoretimeSpending: Vec<(u32, u64)> = Default::default(); pub static CoretimeWorkplan: BTreeMap<(u32, CoreIndex), Vec<(CoreAssignment, PartsOf57600)>> = Default::default(); pub static CoretimeUsage: BTreeMap> = Default::default(); - pub static CoretimeInPool: PartCount = 0; + pub static CoretimeInPool: CoreMaskBitCount = 0; pub static NotifyCoreCount: Vec = Default::default(); pub static NotifyRevenueInfo: Vec<(u32, u64)> = Default::default(); } @@ -163,11 +163,11 @@ impl TestCoretimeProvider { if *when <= now { if let Some(old_assignment) = usage.get(core) { if let Some(a) = old_assignment.iter().find(|i| i.0 == CoreAssignment::Pool) { - pool_size -= (a.1 / 720) as PartCount; + pool_size -= (a.1 / 720) as CoreMaskBitCount; } } if let Some(a) = assignment.iter().find(|i| i.0 == CoreAssignment::Pool) { - pool_size += (a.1 / 720) as PartCount; + pool_size += (a.1 / 720) as CoreMaskBitCount; } usage.insert(*core, assignment.clone()); false diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index e75e772767f80..da7d1b7755a51 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -70,6 +70,54 @@ impl Pallet { meter.consumed } + fn process_core_count() -> bool { + if let Some(core_count) = T::Coretime::check_notify_core_count() { + Status::::mutate_extant(|c| c.core_count = core_count); + Self::deposit_event(Event::::CoreCountChanged { core_count }); + return true + } + false + } + + fn process_revenue() -> bool { + let (until, amount) = match T::Coretime::check_notify_revenue_info() { + Some(x) => x, + None => return false, + }; + let when: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); + let mut revenue = T::ConvertBalance::convert_back(amount); + if revenue.is_zero() { + Self::deposit_event(Event::::HistoryDropped { when, revenue }); + InstaPoolHistory::::remove(when); + return true + } + let mut r = InstaPoolHistory::::get(when).unwrap_or_default(); + if r.maybe_payout.is_some() { + Self::deposit_event(Event::::HistoryIgnored { when, revenue }); + return true + } + // Payout system InstaPool Cores. + let total_contrib = r.system_contributions.saturating_add(r.private_contributions); + let system_payout = revenue.saturating_mul(r.system_contributions.into()) / + total_contrib.into(); + let _ = Self::charge(&Self::account_id(), system_payout); + revenue.saturating_reduce(system_payout); + + if !revenue.is_zero() && r.private_contributions > 0 { + r.maybe_payout = Some(revenue); + InstaPoolHistory::::insert(when, &r); + Self::deposit_event(Event::::ClaimsReady { + when, + system_payout, + private_payout: revenue, + }); + } else { + InstaPoolHistory::::remove(when); + Self::deposit_event(Event::::HistoryDropped { when, revenue }); + } + true + } + /// Begin selling for the next sale period. /// /// Triggered by Relay-chain block number/timeslice. @@ -86,7 +134,7 @@ impl Pallet { // Clean up the old sale - we need to use up any unused cores by putting them into the // InstaPool. - let mut old_pooled: SignedPartCount = 0; + let mut old_pooled: SignedCoreMaskBitCount = 0; for i in old_sale.cores_sold..old_sale.cores_offered { old_pooled.saturating_accrue(80); Workplan::::insert((old_sale.region_begin, old_sale.first_core + i), &just_pool); @@ -113,7 +161,7 @@ impl Pallet { let region_end = region_begin + config.region_length; let mut first_core = 0; - let mut total_pooled: SignedPartCount = 0; + let mut total_pooled: SignedCoreMaskBitCount = 0; for schedule in Reservations::::get().into_iter() { let parts: u32 = schedule .iter() @@ -178,67 +226,23 @@ impl Pallet { Some(()) } - fn process_core_count() -> bool { - if let Some(core_count) = T::Coretime::check_notify_core_count() { - Status::::mutate_extant(|c| c.core_count = core_count); - Self::deposit_event(Event::::CoreCountChanged { core_count }); - return true - } - false - } - - fn process_revenue() -> bool { - let (until, amount) = match T::Coretime::check_notify_revenue_info() { - Some(x) => x, - None => return false, - }; - let when: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); - let mut revenue = T::ConvertBalance::convert_back(amount); - if revenue.is_zero() { - Self::deposit_event(Event::::HistoryDropped { when, revenue }); - InstaPoolHistory::::remove(when); - return true - } - let mut r = InstaPoolHistory::::get(when).unwrap_or_default(); - if r.maybe_payout.is_some() { - Self::deposit_event(Event::::HistoryIgnored { when, revenue }); - return true - } - // Payout system InstaPool Cores. - let total_contrib = r.system_contributions.saturating_add(r.private_contributions); - let system_payout = revenue.saturating_mul(r.system_contributions.into()) / - total_contrib.into(); - let _ = Self::charge(&Self::account_id(), system_payout); - revenue.saturating_reduce(system_payout); - - if !revenue.is_zero() && r.private_contributions > 0 { - r.maybe_payout = Some(revenue); - InstaPoolHistory::::insert(when, &r); - Self::deposit_event(Event::::ClaimsReady { - when, - system_payout, - private_payout: revenue, - private_contributions: r.private_contributions, - }); - } else { - InstaPoolHistory::::remove(when); - Self::deposit_event(Event::::HistoryDropped { when, revenue }); - } - true - } - - fn process_pool(timeslice: Timeslice, status: &mut StatusRecord) { - let pool_io = InstaPoolIo::::take(timeslice); - status.private_pool_size = (status.private_pool_size as SignedPartCount) - .saturating_add(pool_io.private) as PartCount; - status.system_pool_size = (status.system_pool_size as SignedPartCount) - .saturating_add(pool_io.system) as PartCount; + fn process_pool(when: Timeslice, status: &mut StatusRecord) { + let pool_io = InstaPoolIo::::take(when); + status.private_pool_size = (status.private_pool_size as SignedCoreMaskBitCount) + .saturating_add(pool_io.private) as CoreMaskBitCount; + status.system_pool_size = (status.system_pool_size as SignedCoreMaskBitCount) + .saturating_add(pool_io.system) as CoreMaskBitCount; let record = InstaPoolHistoryRecord { private_contributions: status.private_pool_size, system_contributions: status.system_pool_size, maybe_payout: None, }; - InstaPoolHistory::::insert(timeslice, record); + InstaPoolHistory::::insert(when, record); + Self::deposit_event(Event::::HistoryInitialized { + when, + private_pool_size: status.private_pool_size, + system_pool_size: status.system_pool_size, + }); } /// Schedule cores for the given `timeslice`. diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 085a116f8ce2e..a5095a69c9ac0 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -15,10 +15,11 @@ pub type RelayAccountIdOf = <::Coretime as CoretimeInterface>::A /// Relay-chain block number with a fixed divisor of Config::TimeslicePeriod. pub type Timeslice = u32; /// Counter for the total number of set bits over every core's `CoreMask`. `u32` so we don't -/// ever get an overflow. -pub type PartCount = u32; -/// The same as `PartCount` but signed. -pub type SignedPartCount = i32; +/// ever get an overflow. This is 1/80th of a Polkadot Core per timeslice. Assuming timeslices are +/// 80 blocks, then this indicates usage of a single core one time over a timeslice. +pub type CoreMaskBitCount = u32; +/// The same as `CoreMaskBitCount` but signed. +pub type SignedCoreMaskBitCount = i32; /// Whether a core assignment is revokable or not. #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] @@ -94,13 +95,12 @@ pub type ContributionRecordOf = ContributionRecord<::AccountId> /// making proper payments to contributors. #[derive(Encode, Decode, Clone, Default, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct InstaPoolHistoryRecord { - /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block - /// of a Polkadot Core) contributed from purchased Bulk Coretime over a timeslice minus any - /// contributions which have already been paid out. - pub private_contributions: PartCount, - /// The total amount of Coretime (measured in Regularity Parts or 1/80th of a single block - /// of a Polkadot Core) contributed by the Polkadot System in this timeslice. - pub system_contributions: PartCount, + /// The total amount of Coretime (measured in Core Mask Bits minus any contributions which have + /// already been paid out. + pub private_contributions: CoreMaskBitCount, + /// The total amount of Coretime (measured in Core Mask Bits contributed by the Polkadot System + /// in this timeslice. + pub system_contributions: CoreMaskBitCount, /// The payout remaining for the `private_contributions`, or `None` if the revenue is not yet /// known. pub maybe_payout: Option, @@ -152,11 +152,11 @@ pub struct StatusRecord { /// be used in `Coretime::assign`). pub core_count: CoreIndex, /// The current size of the Instantaneous Coretime Pool, measured in - /// Regularity Parts or 1/80th of a single block of a Polkadot Core. - pub private_pool_size: PartCount, + /// Core Mask Bits. + pub private_pool_size: CoreMaskBitCount, /// The current amount of the Instantaneous Coretime Pool which is provided by the Polkadot /// System, rather than provided as a result of privately operated Coretime. - pub system_pool_size: PartCount, + pub system_pool_size: CoreMaskBitCount, /// The last (Relay-chain) timeslice which we committed to the Relay-chain. pub last_committed_timeslice: Timeslice, /// The timeslice of the last time we ticked. @@ -169,11 +169,11 @@ pub struct StatusRecord { )] pub struct PoolIoRecord { /// The total change of the portion of the pool supplied by purchased Bulk Coretime, measured - /// in Regularity Parts. - pub private: SignedPartCount, + /// in Core Mask Bits. + pub private: SignedCoreMaskBitCount, /// The total change of the portion of the pool supplied by the Polkaot System, measured in - /// Regularity Parts. - pub system: SignedPartCount, + /// Core Mask Bits. + pub system: SignedCoreMaskBitCount, } /// The status of a Bulk Coretime Sale. From 6f8f2d3084b2e28beabcd7ec47f6c44fb6f5c083 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 17 Jul 2023 11:56:48 +0200 Subject: [PATCH 058/131] Sale event --- frame/broker/src/lib.rs | 30 +++++++++++++++++++++++++++++- frame/broker/src/tick_impls.rs | 20 +++++++++++++++++--- frame/broker/src/types.rs | 10 +++++----- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 6b65d25db2898..05aab5777e848 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -266,15 +266,43 @@ pub mod pallet { /// The workload of the now cancelled reservation. workload: Schedule, }, + /// A new sale has been initialized. + SaleInitialized { + /// The local block number at which the sale will/did start. + sale_start: T::BlockNumber, + /// The length in blocks of the Leadin Period (where the price is decreasing). + leadin_length: T::BlockNumber, + /// The price of Bulk Coretime at the beginning of the Leadin Period. + start_price: BalanceOf, + /// The price of Bulk Coretime by the end of the Leadin Period. + reserve_price: BalanceOf, + /// The first timeslice of the Regions which are being sold in this sale. + region_begin: Timeslice, + /// The timeslice on which the Regions which are being sold in the sale terminate. + /// (i.e. One after the last timeslice which the Regions control.) + region_end: Timeslice, + /// The number of cores we want to sell, ideally. Selling this amount would result in no + /// change to the reserve_price for the next sale. + ideal_cores_sold: CoreIndex, + /// Number of cores which are/have been offered for sale. + cores_offered: CoreIndex, + }, /// A new lease has been created. Leased { - /// The task to which a core will be assigned + /// The task to which a core will be assigned. task: TaskId, /// The timeslice contained in the sale period after which this lease will /// self-terminate (and therefore the earliest timeslice at which the lease may no /// longer apply). until: Timeslice, }, + /// A lease is about to end. + LeaseEnding { + /// The task to which a core was assigned. + task: TaskId, + /// The timeslice at which the task will no longer be scheduled. + when: Timeslice, + }, /// The sale rotation has been started and a new sale is imminent. SalesStarted { /// The nominal price of an Region of Bulk Coretime. diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index da7d1b7755a51..b910faf5e8c26 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -198,6 +198,7 @@ impl Pallet { begin: region_end, workload: record.completion.drain_complete().unwrap_or_default(), }); + Self::deposit_event(Event::LeaseEnding { when: region_end, task }); } first_core.saturating_inc(); !expiring @@ -207,21 +208,34 @@ impl Pallet { let max_possible_sales = status.core_count.saturating_sub(first_core); let limit_cores_offered = config.limit_cores_offered.unwrap_or(CoreIndex::max_value()); let cores_offered = limit_cores_offered.min(max_possible_sales); + let sale_start = now.saturating_add(config.interlude_length); + let leadin_length = config.leadin_length; + let ideal_cores_sold = (config.ideal_bulk_proportion * cores_offered as u32) as u16; // Update SaleInfo let new_sale = SaleInfoRecord { - sale_start: now.saturating_add(config.interlude_length), - leadin_length: config.leadin_length, + sale_start, + leadin_length, start_price, reserve_price, sellout_price: None, region_begin, region_end, first_core, - ideal_cores_sold: (config.ideal_bulk_proportion * cores_offered as u32) as u16, + ideal_cores_sold, cores_offered, cores_sold: 0, }; SaleInfo::::put(&new_sale); + Self::deposit_event(Event::SaleInitialized { + sale_start, + leadin_length, + start_price, + reserve_price, + region_begin, + region_end, + ideal_cores_sold, + cores_offered, + }); Some(()) } diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index a5095a69c9ac0..fecedd0fd2c45 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -187,21 +187,21 @@ pub struct SaleInfoRecord { pub start_price: Balance, /// The price of Bulk Coretime by the end of the Leadin Period. pub reserve_price: Balance, - /// The price at which the Bulk Coretime offered sold out, if it did sell out. - pub sellout_price: Option, /// The first timeslice of the Regions which are being sold in this sale. pub region_begin: Timeslice, /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One /// after the last timeslice which the Regions control.) pub region_end: Timeslice, - /// The index of the first core which is for sale. Core of Regions which are sold have - /// incrementing indices from this. - pub first_core: CoreIndex, /// The number of cores we want to sell, ideally. Selling this amount would result in no /// change to the reserve_price for the next sale. pub ideal_cores_sold: CoreIndex, /// Number of cores which are/have been offered for sale. pub cores_offered: CoreIndex, + /// The index of the first core which is for sale. Core of Regions which are sold have + /// incrementing indices from this. + pub first_core: CoreIndex, + /// The price at which the Bulk Coretime offered sold out, if it did sell out. + pub sellout_price: Option, /// Number of cores which have been sold; never more than cores_offered. pub cores_sold: CoreIndex, } From 2e9cd554cfad4293d7d4d6cc7a3a3c0ddb4ae21b Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 17 Jul 2023 12:47:46 +0200 Subject: [PATCH 059/131] Better price API and docs --- frame/broker/src/adapt_price.rs | 23 ++++++++++++++-- frame/broker/src/benchmarking.rs | 2 +- frame/broker/src/dispatchable_impls.rs | 13 +++------ frame/broker/src/lib.rs | 8 +++--- frame/broker/src/tick_impls.rs | 38 +++++++++++++++++--------- frame/broker/src/types.rs | 11 ++++---- frame/broker/src/utility_impls.rs | 7 +++-- 7 files changed, 63 insertions(+), 39 deletions(-) diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs index 90f5f3b25cf34..c8917a745acf5 100644 --- a/frame/broker/src/adapt_price.rs +++ b/frame/broker/src/adapt_price.rs @@ -1,23 +1,40 @@ use crate::CoreIndex; use sp_arithmetic::{traits::One, FixedU64}; +/// Type for determining how to set price. pub trait AdaptPrice { - fn adapt_price(sold: CoreIndex, target: CoreIndex, max: CoreIndex) -> FixedU64; + /// Return the factor by which the regular price must be multiplied during the leadin period. + /// + /// - `when`: The amount through the leadin period; between zero and one. + fn leadin_factor_at(when: FixedU64) -> FixedU64; + /// Return the correction factor by which the regular price must be multiplied based on market + /// performance. + /// + /// - `sold`: The number of cores sold. + /// - `target`: The target number of cores to be sold. + /// - `limit`: The maximum number of cores to be sold. + fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64; } impl AdaptPrice for () { + fn leadin_factor_at(_: FixedU64) -> FixedU64 { FixedU64::one() } fn adapt_price(_: CoreIndex, _: CoreIndex, _: CoreIndex) -> FixedU64 { FixedU64::one() } } +/// Simple implementation of `AdaptPrice` giving a monotonic leadin and a linear price change based +/// on cores sold. pub struct Linear; impl AdaptPrice for Linear { - fn adapt_price(sold: CoreIndex, target: CoreIndex, max: CoreIndex) -> FixedU64 { + fn leadin_factor_at(when: FixedU64) -> FixedU64 { + FixedU64::from(2) - when + } + fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64 { if sold < target { FixedU64::from_rational(sold.into(), target.into()) } else { - FixedU64::one() + FixedU64::from_rational((sold - target).into(), (max - target).into()) + FixedU64::one() + FixedU64::from_rational((sold - target).into(), (limit - target).into()) } } } diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 794b737d210cf..c5dfa7e724987 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -204,7 +204,7 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), 10u32.into()); - assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(10u32.into())); + assert_eq!(SaleInfo::::get().unwrap().last_purchase_price, Some(10u32.into())); Ok(()) } diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 0d81aa544fd0b..8cc0af148fa69 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -47,7 +47,7 @@ impl Pallet { } pub(crate) fn do_start_sales( - reserve_price: BalanceOf, + price: BalanceOf, core_count: CoreIndex, ) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; @@ -63,8 +63,7 @@ impl Pallet { let dummy_sale = SaleInfoRecord { sale_start: now, leadin_length: Zero::zero(), - start_price: Zero::zero(), - reserve_price, + price, sellout_price: None, region_begin: commit_timeslice, region_end: commit_timeslice + config.region_length, @@ -73,7 +72,7 @@ impl Pallet { cores_offered: 0, cores_sold: 0, }; - Self::deposit_event(Event::::SalesStarted { reserve_price, core_count }); + Self::deposit_event(Event::::SalesStarted { price, core_count }); Self::rotate_sale(dummy_sale, &config, &status); Status::::put(&status); Ok(()) @@ -95,7 +94,7 @@ impl Pallet { Self::charge(&who, price)?; let core = sale.first_core + sale.cores_sold; sale.cores_sold.saturating_inc(); - if sale.cores_sold >= sale.ideal_cores_sold && sale.sellout_price.is_none() { + if sale.cores_sold <= sale.ideal_cores_sold || sale.sellout_price.is_none() { sale.sellout_price = Some(price); } SaleInfo::::put(&sale); @@ -140,10 +139,6 @@ impl Pallet { let price = record.price + config.renewal_bump * record.price; let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; AllowedRenewals::::insert(core, &new_record); - if sale.cores_sold >= sale.ideal_cores_sold && sale.sellout_price.is_none() { - let price = Self::sale_price(&sale, frame_system::Pallet::::block_number()); - sale.sellout_price = Some(price); - } SaleInfo::::put(&sale); if let Some(workload) = new_record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core, price, begin, workload }); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 05aab5777e848..d25885c8a7960 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -274,15 +274,15 @@ pub mod pallet { leadin_length: T::BlockNumber, /// The price of Bulk Coretime at the beginning of the Leadin Period. start_price: BalanceOf, - /// The price of Bulk Coretime by the end of the Leadin Period. - reserve_price: BalanceOf, + /// The price of Bulk Coretime after the Leadin Period. + regular_price: BalanceOf, /// The first timeslice of the Regions which are being sold in this sale. region_begin: Timeslice, /// The timeslice on which the Regions which are being sold in the sale terminate. /// (i.e. One after the last timeslice which the Regions control.) region_end: Timeslice, /// The number of cores we want to sell, ideally. Selling this amount would result in no - /// change to the reserve_price for the next sale. + /// change to the price for the next sale. ideal_cores_sold: CoreIndex, /// Number of cores which are/have been offered for sale. cores_offered: CoreIndex, @@ -306,7 +306,7 @@ pub mod pallet { /// The sale rotation has been started and a new sale is imminent. SalesStarted { /// The nominal price of an Region of Bulk Coretime. - reserve_price: BalanceOf, + price: BalanceOf, /// The maximum number of cores which this pallet will attempt to assign. core_count: CoreIndex, }, diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index b910faf5e8c26..a90aa8a8ed664 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -142,19 +142,32 @@ impl Pallet { InstaPoolIo::::mutate(old_sale.region_begin, |r| r.system.saturating_accrue(old_pooled)); InstaPoolIo::::mutate(old_sale.region_end, |r| r.system.saturating_reduce(old_pooled)); - // Calculate the start price for the sale after. - let reserve_price = { + // Calculate the start price for the upcoming sale. + let price = { let offered = old_sale.cores_offered; let ideal = old_sale.ideal_cores_sold; let sold = old_sale.cores_sold; - let old_price = old_sale.sellout_price.unwrap_or(old_sale.reserve_price); - if sold <= offered && offered > 0 { - T::PriceAdapter::adapt_price(sold, ideal, offered).saturating_mul_int(old_price) + + let maybe_purchase_price = if offered == 0 { + // No cores offered for sale - no purchase price. + None + } else if sold >= ideal { + // Sold more than the ideal amount. We should look for the last purchase price + // before the sell-out. If there was no purchase at all, then we avoid having a + // price here so that we make no alterations to it (since otherwise we would + // increase it). + old_sale.sellout_price + } else { + // Sold less than the ideal - we fall back to the regular price. + Some(old_sale.price) + }; + if let Some(purchase_price) = maybe_purchase_price { + T::PriceAdapter::adapt_price(sold.min(offered), ideal, offered) + .saturating_mul_int(purchase_price) } else { - old_price + old_sale.price } }; - let start_price = reserve_price * 2u32.into(); // Set workload for the reserved (system, probably) workloads. let region_begin = old_sale.region_end; @@ -188,13 +201,13 @@ impl Pallet { // last time for this one - make it renewable. let record = AllowedRenewalRecord { begin: region_end, - price: reserve_price, + price, completion: Complete(schedule), }; AllowedRenewals::::insert(first_core, &record); Self::deposit_event(Event::Renewable { core: first_core, - price: reserve_price, + price, begin: region_end, workload: record.completion.drain_complete().unwrap_or_default(), }); @@ -215,8 +228,7 @@ impl Pallet { let new_sale = SaleInfoRecord { sale_start, leadin_length, - start_price, - reserve_price, + price, sellout_price: None, region_begin, region_end, @@ -229,8 +241,8 @@ impl Pallet { Self::deposit_event(Event::SaleInitialized { sale_start, leadin_length, - start_price, - reserve_price, + start_price: Self::sale_price(&new_sale, now), + regular_price: price, region_begin, region_end, ideal_cores_sold, diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index fecedd0fd2c45..9766f1eef6fb0 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -183,24 +183,23 @@ pub struct SaleInfoRecord { pub sale_start: BlockNumber, /// The length in blocks of the Leadin Period (where the price is decreasing). pub leadin_length: BlockNumber, - /// The price of Bulk Coretime at the beginning of the Leadin Period. - pub start_price: Balance, - /// The price of Bulk Coretime by the end of the Leadin Period. - pub reserve_price: Balance, + /// The price of Bulk Coretime after the Leadin Period. + pub price: Balance, /// The first timeslice of the Regions which are being sold in this sale. pub region_begin: Timeslice, /// The timeslice on which the Regions which are being sold in the sale terminate. (i.e. One /// after the last timeslice which the Regions control.) pub region_end: Timeslice, /// The number of cores we want to sell, ideally. Selling this amount would result in no - /// change to the reserve_price for the next sale. + /// change to the price for the next sale. pub ideal_cores_sold: CoreIndex, /// Number of cores which are/have been offered for sale. pub cores_offered: CoreIndex, /// The index of the first core which is for sale. Core of Regions which are sold have /// incrementing indices from this. pub first_core: CoreIndex, - /// The price at which the Bulk Coretime offered sold out, if it did sell out. + /// The latest price at which Bulk Coretime was purchased until surpassing the ideal number of + /// cores were sold. pub sellout_price: Option, /// Number of cores which have been sold; never more than cores_offered. pub cores_sold: CoreIndex, diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs index 775a1e45eae56..71b40a10fc093 100644 --- a/frame/broker/src/utility_impls.rs +++ b/frame/broker/src/utility_impls.rs @@ -8,7 +8,7 @@ use frame_support::{ }, }; use sp_arithmetic::{ - traits::{SaturatedConversion, Saturating, Bounded}, + traits::{SaturatedConversion, Saturating, Bounded}, FixedU64, FixedPointNumber, }; use sp_runtime::traits::AccountIdConversion; @@ -42,8 +42,9 @@ impl Pallet { } pub fn sale_price(sale: &SaleInfoRecordOf, now: T::BlockNumber) -> BalanceOf { - lerp(now, sale.sale_start, sale.leadin_length, sale.start_price, sale.reserve_price) - .unwrap_or(sale.start_price) + let num = now.saturating_sub(sale.sale_start).min(sale.leadin_length).saturated_into(); + let through = FixedU64::from_rational(num, sale.leadin_length.saturated_into()); + T::PriceAdapter::leadin_factor_at(through).saturating_mul_int(sale.price) } pub(crate) fn charge(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { From 40d8c19913b9758f6167b6a69d94f2bd4a5ab852 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 11:02:54 +0200 Subject: [PATCH 060/131] Avoid possibility of clobbering renewal record --- frame/broker/src/adapt_price.rs | 7 +++- frame/broker/src/benchmarking.rs | 57 +++++++++++++++----------- frame/broker/src/dispatchable_impls.rs | 36 ++++++++-------- frame/broker/src/lib.rs | 6 +-- frame/broker/src/tests.rs | 37 ++++------------- frame/broker/src/tick_impls.rs | 17 +++----- frame/broker/src/types.rs | 2 - frame/broker/src/utility_impls.rs | 3 +- 8 files changed, 74 insertions(+), 91 deletions(-) diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs index c8917a745acf5..0e7d4a534f3de 100644 --- a/frame/broker/src/adapt_price.rs +++ b/frame/broker/src/adapt_price.rs @@ -17,7 +17,9 @@ pub trait AdaptPrice { } impl AdaptPrice for () { - fn leadin_factor_at(_: FixedU64) -> FixedU64 { FixedU64::one() } + fn leadin_factor_at(_: FixedU64) -> FixedU64 { + FixedU64::one() + } fn adapt_price(_: CoreIndex, _: CoreIndex, _: CoreIndex) -> FixedU64 { FixedU64::one() } @@ -34,7 +36,8 @@ impl AdaptPrice for Linear { if sold < target { FixedU64::from_rational(sold.into(), target.into()) } else { - FixedU64::one() + FixedU64::from_rational((sold - target).into(), (limit - target).into()) + FixedU64::one() + + FixedU64::from_rational((sold - target).into(), (limit - target).into()) } } } diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index c5dfa7e724987..3538471bbb74e 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -74,7 +74,7 @@ fn advance_to(b: u32) { } } -fn setup_and_start_sale() -> Result<(), BenchmarkError> { +fn setup_and_start_sale() -> Result<(), BenchmarkError> { Configuration::::put(new_config_record::()); // Assume Leases to be almost filled for worst case @@ -82,11 +82,8 @@ fn setup_and_start_sale() -> Result<(), BenchmarkError> { let core_index: u16 = T::MaxReservedCores::get().try_into().unwrap(); - Broker::::do_start_sales( - 10u32.into(), - core_index - ) - .map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_start_sales(10u32.into(), core_index) + .map_err(|_| BenchmarkError::Weightless)?; Ok(()) } @@ -191,7 +188,7 @@ mod benches { Ok(()) } - + #[benchmark] fn purchase() -> Result<(), BenchmarkError> { setup_and_start_sale::()?; @@ -204,7 +201,7 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), 10u32.into()); - assert_eq!(SaleInfo::::get().unwrap().last_purchase_price, Some(10u32.into())); + assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(10u32.into())); Ok(()) } @@ -220,16 +217,18 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 20u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; - Broker::::do_assign(region, None, 1001, Final).map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_assign(region, None, 1001, Final) + .map_err(|_| BenchmarkError::Weightless)?; advance_to::(6); #[extrinsic_call] _(RawOrigin::Signed(caller), core_index.saturating_sub(1)); - assert!(AllowedRenewals::::get(core_index.saturating_sub(1)).is_some()); + assert!(AllowedRenewals::::get((core_index.saturating_sub(1), 10)).is_some()); Ok(()) } @@ -243,7 +242,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); @@ -262,7 +262,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] _(RawOrigin::Signed(caller), region, 2); @@ -279,7 +280,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] _(RawOrigin::Signed(caller), region, 0x00000_fffff_fffff_00000.into()); @@ -296,7 +298,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] _(RawOrigin::Signed(caller), region, 1000, Final); @@ -313,7 +316,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); @@ -332,11 +336,13 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); - Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_pool(region, None, recipient, Final) + .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] _(RawOrigin::Signed(caller), region, 100); @@ -354,11 +360,13 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 30u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); - Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_pool(region, None, recipient, Final) + .map_err(|_| BenchmarkError::Weightless)?; let beneficiary: RelayAccountIdOf = account("beneficiary", 0, SEED); @@ -377,7 +385,8 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; advance_to::(12); @@ -396,11 +405,13 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 10u32.into()); - let region = Broker::::do_purchase(caller.clone(), 10u32.into()).map_err(|_| BenchmarkError::Weightless)?; + let region = Broker::::do_purchase(caller.clone(), 10u32.into()) + .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); - Broker::::do_pool(region, None, recipient, Final).map_err(|_| BenchmarkError::Weightless)?; + Broker::::do_pool(region, None, recipient, Final) + .map_err(|_| BenchmarkError::Weightless)?; advance_to::(26); diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 8cc0af148fa69..3ea62759171fa 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -46,10 +46,7 @@ impl Pallet { Ok(()) } - pub(crate) fn do_start_sales( - price: BalanceOf, - core_count: CoreIndex, - ) -> DispatchResult { + pub(crate) fn do_start_sales(price: BalanceOf, core_count: CoreIndex) -> DispatchResult { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let commit_timeslice = Self::latest_timeslice_ready_to_commit(&config); let status = StatusRecord { @@ -109,15 +106,15 @@ impl Pallet { pub(crate) fn do_renew(who: T::AccountId, core: CoreIndex) -> Result { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; - let record = AllowedRenewals::::get(core).ok_or(Error::::NotAllowed)?; let mut sale = SaleInfo::::get().ok_or(Error::::NoSales)?; - let workload = - record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; - - ensure!(record.begin == sale.region_begin, Error::::WrongTime); ensure!(sale.first_core < status.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); + let record = + AllowedRenewals::::get((core, sale.region_begin)).ok_or(Error::::NotAllowed)?; + let workload = + record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; + let old_core = core; let core = sale.first_core + sale.cores_sold; Self::charge(&who, record.price)?; @@ -133,12 +130,13 @@ impl Pallet { sale.cores_sold.saturating_inc(); - Workplan::::insert((record.begin, core), &workload); + Workplan::::insert((sale.region_begin, core), &workload); let begin = sale.region_end; let price = record.price + config.renewal_bump * record.price; - let new_record = AllowedRenewalRecord { begin, price, completion: Complete(workload) }; - AllowedRenewals::::insert(core, &new_record); + let new_record = AllowedRenewalRecord { price, completion: Complete(workload) }; + AllowedRenewals::::remove((core, sale.region_begin)); + AllowedRenewals::::insert((core, begin), &new_record); SaleInfo::::put(&sale); if let Some(workload) = new_record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core, price, begin, workload }); @@ -245,18 +243,16 @@ impl Pallet { if duration == config.region_length && finality == Finality::Final { if let Some(price) = region.paid { let begin = region.end; - let assigned = match AllowedRenewals::::get(region_id.core) { - Some(AllowedRenewalRecord { - completion: Partial(w), - begin: b, - price: p, - }) if begin == b && price == p => w, + let assigned = match AllowedRenewals::::get((region_id.core, begin)) { + Some(AllowedRenewalRecord { completion: Partial(w), price: p }) + if price == p => + w, _ => CoreMask::void(), } | region_id.part; let workload = if assigned.is_complete() { Complete(workplan) } else { Partial(assigned) }; - let record = AllowedRenewalRecord { begin, price, completion: workload }; - AllowedRenewals::::insert(region_id.core, &record); + let record = AllowedRenewalRecord { price, completion: workload }; + AllowedRenewals::::insert((region_id.core, begin), &record); if let Some(workload) = record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core: region_id.core, diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index d25885c8a7960..6f13dc4564772 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -128,7 +128,7 @@ pub mod pallet { /// Records of allowed renewals. #[pallet::storage] pub type AllowedRenewals = - StorageMap<_, Twox64Concat, CoreIndex, AllowedRenewalRecordOf, OptionQuery>; + StorageMap<_, Twox64Concat, (CoreIndex, Timeslice), AllowedRenewalRecordOf, OptionQuery>; /// The current (unassigned) Regions. #[pallet::storage] @@ -281,8 +281,8 @@ pub mod pallet { /// The timeslice on which the Regions which are being sold in the sale terminate. /// (i.e. One after the last timeslice which the Regions control.) region_end: Timeslice, - /// The number of cores we want to sell, ideally. Selling this amount would result in no - /// change to the price for the next sale. + /// The number of cores we want to sell, ideally. Selling this amount would result in + /// no change to the price for the next sale. ideal_cores_sold: CoreIndex, /// Number of cores which are/have been offered for sale. cores_offered: CoreIndex, diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 66e74f18d202a..ab1d579a8372a 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -137,7 +137,7 @@ fn nft_metadata_works() { fn migration_works() { TestExt::new().endow(1, 1000).execute_with(|| { assert_ok!(Broker::do_set_lease(1000, 8)); - assert_ok!(Broker::do_start_sales(100, 1)); + assert_ok!(Broker::do_start_sales(100, 2)); // Sale is for regions from TS4..7 // Not ending in this sale period. @@ -151,36 +151,17 @@ fn migration_works() { assert_eq!(balance(1), 900); advance_to(18); + let just_pool = || vec![(Pool, 57600)]; + let just_1000 = || vec![(Task(1000), 57600)]; assert_eq!( CoretimeTrace::get(), vec![ - ( - 6, - AssignCore { - core: 0, - begin: 8, - assignment: vec![(Task(1000), 57600),], - end_hint: None - } - ), - ( - 12, - AssignCore { - core: 0, - begin: 14, - assignment: vec![(Task(1000), 57600),], - end_hint: None - } - ), - ( - 18, - AssignCore { - core: 0, - begin: 20, - assignment: vec![(Task(1000), 57600),], - end_hint: None - } - ), + (6, AssignCore { core: 0, begin: 8, assignment: just_1000(), end_hint: None }), + (6, AssignCore { core: 1, begin: 8, assignment: just_pool(), end_hint: None }), + (12, AssignCore { core: 0, begin: 14, assignment: just_1000(), end_hint: None }), + (12, AssignCore { core: 1, begin: 14, assignment: just_pool(), end_hint: None }), + (18, AssignCore { core: 0, begin: 20, assignment: just_1000(), end_hint: None }), + (18, AssignCore { core: 1, begin: 20, assignment: just_pool(), end_hint: None }), ] ); }); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index a90aa8a8ed664..f1cb147029fb8 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -1,8 +1,5 @@ use super::*; -use frame_support::{ - pallet_prelude::*, - weights::WeightMeter, -}; +use frame_support::{pallet_prelude::*, weights::WeightMeter}; use sp_arithmetic::{ traits::{SaturatedConversion, Saturating, Zero}, FixedPointNumber, @@ -98,8 +95,8 @@ impl Pallet { } // Payout system InstaPool Cores. let total_contrib = r.system_contributions.saturating_add(r.private_contributions); - let system_payout = revenue.saturating_mul(r.system_contributions.into()) / - total_contrib.into(); + let system_payout = + revenue.saturating_mul(r.system_contributions.into()) / total_contrib.into(); let _ = Self::charge(&Self::account_id(), system_payout); revenue.saturating_reduce(system_payout); @@ -199,12 +196,8 @@ impl Pallet { let expiring = until >= region_begin && until < region_end; if expiring { // last time for this one - make it renewable. - let record = AllowedRenewalRecord { - begin: region_end, - price, - completion: Complete(schedule), - }; - AllowedRenewals::::insert(first_core, &record); + let record = AllowedRenewalRecord { price, completion: Complete(schedule) }; + AllowedRenewals::::insert((first_core, region_end), &record); Self::deposit_event(Event::Renewable { core: first_core, price, diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 9766f1eef6fb0..b0ca2828cf5d6 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -135,8 +135,6 @@ impl CompletionStatus { /// A record of an allowed renewal. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct AllowedRenewalRecord { - /// The timeslice denoting the beginning of the Region for which a renewal can secure. - pub begin: Timeslice, /// The price for which the next renewal can be made. pub price: Balance, /// The workload which will be scheduled on the Core in the case a renewal is made, or if diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs index 71b40a10fc093..55f56db9770de 100644 --- a/frame/broker/src/utility_impls.rs +++ b/frame/broker/src/utility_impls.rs @@ -8,7 +8,8 @@ use frame_support::{ }, }; use sp_arithmetic::{ - traits::{SaturatedConversion, Saturating, Bounded}, FixedU64, FixedPointNumber, + traits::{Bounded, SaturatedConversion, Saturating}, + FixedPointNumber, FixedU64, }; use sp_runtime::traits::AccountIdConversion; From 3e70d96370400efaa5f251cef74e3fdf58652cb6 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 11:18:25 +0200 Subject: [PATCH 061/131] Avoid possibility of clobbering renewal record --- frame/broker/src/benchmarking.rs | 3 ++- frame/broker/src/dispatchable_impls.rs | 26 +++++++++++++------ frame/broker/src/lib.rs | 35 ++++++++++++++++++++++---- frame/broker/src/tick_impls.rs | 3 ++- frame/broker/src/types.rs | 9 +++++++ frame/broker/src/weights.rs | 3 +++ 6 files changed, 64 insertions(+), 15 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 3538471bbb74e..341d60b5663ec 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -228,7 +228,8 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), core_index.saturating_sub(1)); - assert!(AllowedRenewals::::get((core_index.saturating_sub(1), 10)).is_some()); + let id = AllowedRenewalId { core: core_index.saturating_sub(1), when: 10 }; + assert!(AllowedRenewals::::get(id).is_some()); Ok(()) } diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 3ea62759171fa..00ea4c3794589 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -110,8 +110,8 @@ impl Pallet { ensure!(sale.first_core < status.core_count, Error::::Unavailable); ensure!(sale.cores_sold < sale.cores_offered, Error::::SoldOut); - let record = - AllowedRenewals::::get((core, sale.region_begin)).ok_or(Error::::NotAllowed)?; + let renewal_id = AllowedRenewalId { core, when: sale.region_begin }; + let record = AllowedRenewals::::get(renewal_id).ok_or(Error::::NotAllowed)?; let workload = record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; @@ -135,8 +135,8 @@ impl Pallet { let begin = sale.region_end; let price = record.price + config.renewal_bump * record.price; let new_record = AllowedRenewalRecord { price, completion: Complete(workload) }; - AllowedRenewals::::remove((core, sale.region_begin)); - AllowedRenewals::::insert((core, begin), &new_record); + AllowedRenewals::::remove(renewal_id); + AllowedRenewals::::insert(AllowedRenewalId { core, when: begin }, &new_record); SaleInfo::::put(&sale); if let Some(workload) = new_record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core, price, begin, workload }); @@ -242,8 +242,8 @@ impl Pallet { let duration = region.end.saturating_sub(region_id.begin); if duration == config.region_length && finality == Finality::Final { if let Some(price) = region.paid { - let begin = region.end; - let assigned = match AllowedRenewals::::get((region_id.core, begin)) { + let renewal_id = AllowedRenewalId { core: region_id.core, when: region.end }; + let assigned = match AllowedRenewals::::get(renewal_id) { Some(AllowedRenewalRecord { completion: Partial(w), price: p }) if price == p => w, @@ -252,12 +252,12 @@ impl Pallet { let workload = if assigned.is_complete() { Complete(workplan) } else { Partial(assigned) }; let record = AllowedRenewalRecord { price, completion: workload }; - AllowedRenewals::::insert((region_id.core, begin), &record); + AllowedRenewals::::insert(&renewal_id, &record); if let Some(workload) = record.completion.drain_complete() { Self::deposit_event(Event::Renewable { core: region_id.core, price, - begin, + begin: region.end, workload, }); } @@ -398,4 +398,14 @@ impl Pallet { Self::deposit_event(Event::HistoryDropped { when, revenue }); Ok(()) } + + pub(crate) fn do_drop_renewal(core: CoreIndex, when: Timeslice) -> DispatchResult { + let status = Status::::get().ok_or(Error::::Uninitialized)?; + ensure!(status.last_committed_timeslice >= when, Error::::StillValid); + let id = AllowedRenewalId { core, when }; + ensure!(AllowedRenewals::::contains_key(id), Error::::UnknownRenewal); + AllowedRenewals::::remove(id); + Self::deposit_event(Event::AllowedRenewalDropped { core, when }); + Ok(()) + } } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 6f13dc4564772..f5c724f0b612c 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -128,7 +128,7 @@ pub mod pallet { /// Records of allowed renewals. #[pallet::storage] pub type AllowedRenewals = - StorageMap<_, Twox64Concat, (CoreIndex, Timeslice), AllowedRenewalRecordOf, OptionQuery>; + StorageMap<_, Twox64Concat, AllowedRenewalId, AllowedRenewalRecordOf, OptionQuery>; /// The current (unassigned) Regions. #[pallet::storage] @@ -397,6 +397,13 @@ pub mod pallet { /// The workload to be done on the Core. assignment: Vec<(CoreAssignment, PartsOf57600)>, }, + /// Some historical Instantaneous Core Pool payment record has been dropped. + AllowedRenewalDropped { + /// The timeslice whose renewal is no longer available. + when: Timeslice, + /// The core whose workload is no longer available to be renewed for `when`. + core: CoreIndex, + }, } #[pallet::error] @@ -461,6 +468,8 @@ pub mod pallet { NoHistory, /// No reservation of the given index exists. UnknownReservation, + /// The renewal record cannot be found. + UnknownRenewal, } #[pallet::hooks] @@ -704,7 +713,7 @@ pub mod pallet { /// Drop an expired Region from the chain. /// - /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `origin`: Must be a Signed origin. /// - `region_id`: The Region which has expired. #[pallet::call_index(14)] pub fn drop_region( @@ -718,7 +727,7 @@ pub mod pallet { /// Drop an expired Instantaneous Pool Contribution record from the chain. /// - /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `origin`: Must be a Signed origin. /// - `region_id`: The Region identifying the Pool Contribution which has expired. #[pallet::call_index(15)] pub fn drop_contribution( @@ -732,7 +741,7 @@ pub mod pallet { /// Drop an expired Instantaneous Pool History record from the chain. /// - /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `origin`: Must be a Signed origin. /// - `region_id`: The time of the Pool History record which has expired. #[pallet::call_index(16)] pub fn drop_history(origin: OriginFor, when: Timeslice) -> DispatchResultWithPostInfo { @@ -741,11 +750,27 @@ pub mod pallet { Ok(Pays::No.into()) } + /// Drop an expired Allowed Renewal record from the chain. + /// + /// - `origin`: Must be a Signed origin of the account which owns the Region `region_id`. + /// - `core`: The core to which the expired renewal refers. + /// - `when`: The timeslice to which the expired renewal refers. This must have passed. + #[pallet::call_index(17)] + pub fn drop_renewal( + origin: OriginFor, + core: CoreIndex, + when: Timeslice, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin)?; + Self::do_drop_renewal(core, when)?; + Ok(Pays::No.into()) + } + /// Request a change to the number of cores available for scheduling work. /// /// - `origin`: Must be Root or pass `AdminOrigin`. /// - `core_count`: The desired number of cores to be made available. - #[pallet::call_index(17)] + #[pallet::call_index(18)] pub fn request_core_count(origin: OriginFor, core_count: CoreIndex) -> DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_request_core_count(core_count)?; diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index f1cb147029fb8..d8f09e707c8ad 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -196,8 +196,9 @@ impl Pallet { let expiring = until >= region_begin && until < region_end; if expiring { // last time for this one - make it renewable. + let renewal_id = AllowedRenewalId { core: first_core, when: region_end }; let record = AllowedRenewalRecord { price, completion: Complete(schedule) }; - AllowedRenewals::::insert((first_core, region_end), &record); + AllowedRenewals::::insert(renewal_id, &record); Self::deposit_event(Event::Renewable { core: first_core, price, diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index b0ca2828cf5d6..15f08937e3c47 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -132,6 +132,15 @@ impl CompletionStatus { } } +/// The identity of a possible Core workload renewal. +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct AllowedRenewalId { + /// The core whose workload at the sale ending with `when` may be renewed to begin at `when`. + pub core: CoreIndex, + /// The point in time that the renewable workload on `core` ends and a fresh renewal may begin. + pub when: Timeslice, +} + /// A record of an allowed renewal. #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct AllowedRenewalRecord { diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index a5cbd01c12fde..5ef20d65000e0 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -43,6 +43,7 @@ pub trait WeightInfo { fn drop_region() -> Weight; fn drop_contribution() -> Weight; fn drop_history() -> Weight; + fn drop_renewal() -> Weight; fn request_core_count() -> Weight; fn process_core_count() -> Weight; fn process_revenue() -> Weight; @@ -72,6 +73,7 @@ impl WeightInfo for SubstrateWeight { fn drop_region() -> Weight { Weight::from_parts(123, 456) } fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } fn drop_history() -> Weight { Weight::from_parts(123, 456) } + fn drop_renewal() -> Weight { Weight::from_parts(123, 456) } fn request_core_count() -> Weight { Weight::from_parts(123, 456) } fn process_core_count() -> Weight { Weight::from_parts(123, 456) } fn process_revenue() -> Weight { Weight::from_parts(123, 456) } @@ -100,6 +102,7 @@ impl WeightInfo for () { fn drop_region() -> Weight { Weight::from_parts(123, 456) } fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } fn drop_history() -> Weight { Weight::from_parts(123, 456) } + fn drop_renewal() -> Weight { Weight::from_parts(123, 456) } fn request_core_count() -> Weight { Weight::from_parts(123, 456) } fn process_core_count() -> Weight { Weight::from_parts(123, 456) } fn process_revenue() -> Weight { Weight::from_parts(123, 456) } From b37992256242388ee622dd9a97436c02b79afcc5 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 18 Jul 2023 16:58:54 +0530 Subject: [PATCH 062/131] Fixes a few benchmarks --- frame/broker/src/benchmarking.rs | 24 ++++++++++++------------ frame/broker/src/tick_impls.rs | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 341d60b5663ec..2521b248b3ba5 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -31,6 +31,7 @@ use sp_core::Get; use sp_runtime::Saturating; const SEED: u32 = 0; +const MAX_CORE_COUNT: u16 = 1_000; fn new_config_record() -> ConfigRecordOf { ConfigRecord { @@ -77,12 +78,13 @@ fn advance_to(b: u32) { fn setup_and_start_sale() -> Result<(), BenchmarkError> { Configuration::::put(new_config_record::()); - // Assume Leases to be almost filled for worst case - setup_leases::(T::MaxLeasedCores::get().saturating_sub(1), 1, 10); + // Assume Reservations to be filled for worst case + setup_reservations::(T::MaxReservedCores::get()); - let core_index: u16 = T::MaxReservedCores::get().try_into().unwrap(); + // Assume Leases to be filled for worst case + setup_leases::(T::MaxLeasedCores::get(), 1, 10); - Broker::::do_start_sales(10u32.into(), core_index) + Broker::::do_start_sales(10u32.into(), MAX_CORE_COUNT.into()) .map_err(|_| BenchmarkError::Weightless)?; Ok(()) @@ -167,10 +169,10 @@ mod benches { } #[benchmark] - fn start_sales() -> Result<(), BenchmarkError> { + fn start_sales(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { Configuration::::put(new_config_record::()); - // Assume Reservations to be almost filled for worst case + // Assume Reservations to be filled for worst case setup_reservations::(T::MaxReservedCores::get()); // Assume Leases to be filled for worst case @@ -182,7 +184,7 @@ mod benches { T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(origin as T::RuntimeOrigin, initial_price, 12); //Todo: Check with Gav + _(origin as T::RuntimeOrigin, initial_price, n.try_into().unwrap()); assert!(SaleInfo::::get().is_some()); @@ -212,8 +214,6 @@ mod benches { advance_to::(2); - let core_index: u16 = T::MaxReservedCores::get().try_into().unwrap(); - let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance(&caller.clone(), 20u32.into()); @@ -226,9 +226,9 @@ mod benches { advance_to::(6); #[extrinsic_call] - _(RawOrigin::Signed(caller), core_index.saturating_sub(1)); + _(RawOrigin::Signed(caller), region.core); - let id = AllowedRenewalId { core: core_index.saturating_sub(1), when: 10 }; + let id = AllowedRenewalId { core: region.core, when: 10 }; assert!(AllowedRenewals::::get(id).is_some()); Ok(()) @@ -424,7 +424,7 @@ mod benches { #[benchmark] fn request_core_count( - n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, + n: Linear<0, { MAX_CORE_COUNT.into() }>, ) -> Result<(), BenchmarkError> { let admin_origin = T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index d8f09e707c8ad..486a3a1c1341c 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -286,7 +286,7 @@ impl Pallet { let mut intermediate = workplan .into_iter() .map(|i| (i.assignment, i.part.count_ones() as u16 * (57_600 / 80))) - .inspect(|i| total_used += i.1) + .inspect(|i| total_used.saturating_accrue(i.1)) .collect::>(); if total_used < 80 { intermediate.push((CoreAssignment::Idle, 80 - total_used)); From b565bdb0bc9e38071125fc9ef7c7740baf5a9178 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 16:21:55 +0200 Subject: [PATCH 063/131] Another test --- frame/broker/src/tests.rs | 14 ++++++++++++++ frame/broker/src/tick_impls.rs | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index ab1d579a8372a..ae8139ffa0958 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -35,6 +35,20 @@ fn basic_initialize_works() { }); } +#[test] +fn request_core_count_works() { + TestExt::new().execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 0)); + assert_ok!(Broker::request_core_count(RuntimeOrigin::root(), 1)); + advance_to(12); + let assignment = vec![(Pool, 57600)]; + assert_eq!( + CoretimeTrace::get(), + vec![(12, AssignCore { core: 0, begin: 14, assignment, end_hint: None })], + ); + }); +} + #[test] fn transfer_works() { TestExt::new().endow(1, 1000).execute_with(|| { diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index d8f09e707c8ad..7f453cf14b02d 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -25,7 +25,7 @@ impl Pallet { let mut meter = WeightMeter::max_limit(); - if Self::process_core_count() { + if Self::process_core_count(&mut status) { meter.consume(T::WeightInfo::process_core_count()); } @@ -67,9 +67,9 @@ impl Pallet { meter.consumed } - fn process_core_count() -> bool { + fn process_core_count(status: &mut StatusRecord) -> bool { if let Some(core_count) = T::Coretime::check_notify_core_count() { - Status::::mutate_extant(|c| c.core_count = core_count); + status.core_count = core_count; Self::deposit_event(Event::::CoreCountChanged { core_count }); return true } From 3ad2499fd39d4e7b19c4d38709b5dcf489ea700c Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 17:02:07 +0200 Subject: [PATCH 064/131] More tests --- frame/broker/src/benchmarking.rs | 4 +- frame/broker/src/dispatchable_impls.rs | 4 +- frame/broker/src/lib.rs | 8 ---- frame/broker/src/tests.rs | 62 ++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 13 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 2521b248b3ba5..62372d66d8222 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -423,9 +423,7 @@ mod benches { } #[benchmark] - fn request_core_count( - n: Linear<0, { MAX_CORE_COUNT.into() }>, - ) -> Result<(), BenchmarkError> { + fn request_core_count(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { let admin_origin = T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 00ea4c3794589..a338a67d7381b 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -378,9 +378,9 @@ impl Pallet { let config = Configuration::::get().ok_or(Error::::Uninitialized)?; let status = Status::::get().ok_or(Error::::Uninitialized)?; let contrib = - InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownRegion)?; + InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownContribution)?; let end = region_id.begin.saturating_add(contrib.length); - ensure!(status.last_timeslice > end + config.contribution_timeout, Error::::StillValid); + ensure!(status.last_timeslice >= end + config.contribution_timeout, Error::::StillValid); InstaPoolContribution::::remove(region_id); Self::deposit_event(Event::ContributionDropped { region_id }); Ok(()) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index f5c724f0b612c..eb1a7755b8eee 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -425,8 +425,6 @@ pub mod pallet { CorruptWorkplan, /// There is no sale happening currently. NoSales, - /// The price for the sale could not be determined. This indicates a logic error. - IndeterminablePrice, /// The price limit is exceeded. Overpriced, /// There are no cores available. @@ -448,17 +446,11 @@ pub mod pallet { TooManyReservations, /// The maximum amount of leases has already been reached. TooManyLeases, - /// The revenue for the Instantaneous Core Sales of this period is already known. This - /// is unexpected and indicates a logic error. - RevenueAlreadyKnown, /// The revenue for the Instantaneous Core Sales of this period is not (yet) known and thus /// this operation cannot proceed. UnknownRevenue, /// The identified contribution to the Instantaneous Core Pool is unknown. UnknownContribution, - /// The recorded contributions to the Instantaneous Core Pool are invalid. This is - /// unexpected and indicates a logic error. - InvalidContributions, /// The workload assigned for renewal is incomplete. This is unexpected and indicates a /// logic error. IncompleteAssignment, diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index ae8139ffa0958..59aac72e5048d 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -35,6 +35,68 @@ fn basic_initialize_works() { }); } +#[test] +fn drop_region_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Provisional)); + advance_to(11); + assert_noop!(Broker::do_drop_region(region), Error::::StillValid); + advance_to(12); + // assignment worked. + let just_1001 = vec![(Task(1001), 57600)]; + let just_pool = vec![(Pool, 57600)]; + assert_eq!( + CoretimeTrace::get(), + vec![ + (6, AssignCore { core: 0, begin: 8, assignment: just_1001, end_hint: None }), + (12, AssignCore { core: 0, begin: 14, assignment: just_pool, end_hint: None }), + ] + ); + // `region` still exists as it was never finalized. + assert_eq!(Regions::::iter().count(), 1); + assert_ok!(Broker::do_drop_region(region)); + assert_eq!(Regions::::iter().count(), 0); + assert_noop!(Broker::do_drop_region(region), Error::::UnknownRegion); + }); +} + +#[test] +fn drop_renewal_works() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Final)); + advance_to(11); + let e = Error::::StillValid; + assert_noop!(Broker::do_drop_renewal(region.core, region.begin + 3), e); + advance_to(12); + assert_ok!(Broker::do_drop_renewal(region.core, region.begin + 3)); + let e = Error::::UnknownRenewal; + assert_noop!(Broker::do_drop_renewal(region.core, region.begin + 3), e); + }); +} + +#[test] +fn drop_contribution_works() { + TestExt::new().contribution_timeout(3).endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_pool(region, Some(1), 1, Final)); + assert_eq!(InstaPoolContribution::::iter().count(), 1); + advance_to(19); + assert_noop!(Broker::do_drop_contribution(region), Error::::StillValid); + advance_to(20); + assert_ok!(Broker::do_drop_contribution(region)); + assert_eq!(InstaPoolContribution::::iter().count(), 0); + assert_noop!(Broker::do_drop_contribution(region), Error::::UnknownContribution); + }); +} + #[test] fn request_core_count_works() { TestExt::new().execute_with(|| { From 5ce6b7930057d7aa00e29fbff788f1efeb9dc7b8 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 17:08:35 +0200 Subject: [PATCH 065/131] Drop history test --- frame/broker/src/tests.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 59aac72e5048d..24feb96b7a565 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -97,6 +97,44 @@ fn drop_contribution_works() { }); } +#[test] +fn drop_history_works() { + TestExt::new() + .contribution_timeout(3) + .endow(1, 1000) + .endow(2, 10) + .execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let mut region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_ok!(Broker::do_pool(region, Some(1), 1, Final)); + assert_ok!(Broker::do_purchase_credit(1, 20, 1)); + advance_to(8); + assert_ok!(TestCoretimeProvider::spend_instantaneous(2, 10)); + advance_to(15); + assert_eq!(InstaPoolHistory::::iter().count(), 3); + assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); + advance_to(16); + assert_ok!(Broker::do_drop_history(region)); + assert_eq!(InstaPoolHistory::::iter().count(), 2); + assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); + advance_to(17); + region.begin += 1; + assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); + advance_to(18); + assert_ok!(Broker::do_drop_history(region)); + assert_eq!(InstaPoolHistory::::iter().count(), 1); + assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); + advance_to(19); + region.begin += 1; + assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); + advance_to(20); + assert_ok!(Broker::do_drop_history(region)); + assert_eq!(InstaPoolHistory::::iter().count(), 0); + assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); + }); +} + #[test] fn request_core_count_works() { TestExt::new().execute_with(|| { From 8838982e14d054239bbd53dd28115d7f0e6aa9ee Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 18 Jul 2023 17:20:16 +0200 Subject: [PATCH 066/131] Rename and CORE_MASK_BITS constant --- frame/broker/src/{core_part.rs => core_mask.rs} | 3 +++ frame/broker/src/lib.rs | 4 ++-- frame/broker/src/types.rs | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) rename frame/broker/src/{core_part.rs => core_mask.rs} (97%) diff --git a/frame/broker/src/core_part.rs b/frame/broker/src/core_mask.rs similarity index 97% rename from frame/broker/src/core_part.rs rename to frame/broker/src/core_mask.rs index 21a39fe24022b..fea8e40f0c323 100644 --- a/frame/broker/src/core_part.rs +++ b/frame/broker/src/core_mask.rs @@ -3,6 +3,9 @@ use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, use scale_info::TypeInfo; use sp_core::RuntimeDebug; +/// The number of bits in the `CoreMask`. +pub const CORE_MASK_BITS: usize = 80; + // TODO: Use BitArr instead; for this, we'll need to ensure Codec is impl'ed for `BitArr`. #[derive( Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen, diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index eb1a7755b8eee..d0c5bbc89d1b9 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -22,7 +22,7 @@ pub use pallet::*; mod adapt_price; mod benchmarking; -mod core_part; +mod core_mask; mod coretime_interface; mod dispatchable_impls; mod mock; @@ -37,7 +37,7 @@ pub mod weights; pub use weights::WeightInfo; pub use adapt_price::*; -pub use core_part::*; +pub use core_mask::*; pub use coretime_interface::*; pub use nonfungible_impl::*; pub use types::*; diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 15f08937e3c47..050c23b6e964d 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,4 +1,4 @@ -use crate::{Config, CoreAssignment, CoreIndex, CoreMask, CoretimeInterface, TaskId}; +use crate::{Config, CoreAssignment, CoreIndex, CoreMask, CORE_MASK_BITS, CoretimeInterface, TaskId}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::fungible::Inspect; use frame_system::Config as SConfig; @@ -78,7 +78,7 @@ pub struct ScheduleItem { /// The job that the Core should be doing. pub assignment: CoreAssignment, } -pub type Schedule = BoundedVec>; +pub type Schedule = BoundedVec>; /// The record body of a Region which was contributed to the Instantaneous Coretime Pool. This helps /// with making pro rata payments to contributors. From bcffbe5908867996843533b93cbfc01eb9949fc1 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:20:48 +0200 Subject: [PATCH 067/131] Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index a338a67d7381b..42b22bbc2048e 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -89,7 +89,7 @@ impl Pallet { ensure!(price_limit >= price, Error::::Overpriced); Self::charge(&who, price)?; - let core = sale.first_core + sale.cores_sold; + let core = sale.first_core.saturating_add(sale.cores_sold); sale.cores_sold.saturating_inc(); if sale.cores_sold <= sale.ideal_cores_sold || sale.sellout_price.is_none() { sale.sellout_price = Some(price); From ba8c4a111a7b3effd074731374b721f13cf15fa9 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:20:56 +0200 Subject: [PATCH 068/131] Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 42b22bbc2048e..0a57c5e043723 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -63,7 +63,7 @@ impl Pallet { price, sellout_price: None, region_begin: commit_timeslice, - region_end: commit_timeslice + config.region_length, + region_end: commit_timeslice.saturating_add(config.region_length), first_core: 0, ideal_cores_sold: 0, cores_offered: 0, From 80f5d7b8f4c9bc5bc6e24193ef865455fdbfab12 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:22:48 +0200 Subject: [PATCH 069/131] Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 0a57c5e043723..ae4d4fbc6463b 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -116,7 +116,7 @@ impl Pallet { record.completion.drain_complete().ok_or(Error::::IncompleteAssignment)?; let old_core = core; - let core = sale.first_core + sale.cores_sold; + let core = sale.first_core.saturating_add(sale.cores_sold); Self::charge(&who, record.price)?; Self::deposit_event(Event::Renewed { who, From 8d6af157c3c850d4b3714e0eac126e00e6d844c1 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:23:12 +0200 Subject: [PATCH 070/131] Update frame/broker/src/utility_impls.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/utility_impls.rs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs index 55f56db9770de..d2a5b1d4970a9 100644 --- a/frame/broker/src/utility_impls.rs +++ b/frame/broker/src/utility_impls.rs @@ -102,22 +102,3 @@ impl Pallet { } } -pub fn lerp, S: TryInto + TryFrom + Bounded>( - v: T, - a: T, - d: T, - x: S, - y: S, -) -> Option { - use sp_arithmetic::{ - helpers_128bit::multiply_by_rational_with_rounding, Rounding::NearestPrefUp, - }; - let v: u128 = v.try_into().ok()?; - let a: u128 = a.try_into().ok()?; - let d: u128 = d.try_into().ok()?; - let r: u128 = x.try_into().ok()?; - let s: u128 = y.try_into().ok()?; - let rsd = r.max(s) - r.min(s); - let td = multiply_by_rational_with_rounding(rsd, (v.max(a) - a).min(d), d, NearestPrefUp)?; - if r < s { r + td } else { r - td }.try_into().ok() -} From 5aa621ccd4481b1584217901009e5a393ec217b2 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:23:41 +0200 Subject: [PATCH 071/131] Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index ae4d4fbc6463b..07d9fbefcd971 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -380,7 +380,7 @@ impl Pallet { let contrib = InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownContribution)?; let end = region_id.begin.saturating_add(contrib.length); - ensure!(status.last_timeslice >= end + config.contribution_timeout, Error::::StillValid); + ensure!(status.last_timeslice > end.saturating_add(config.contribution_timeout), Error::::StillValid); InstaPoolContribution::::remove(region_id); Self::deposit_event(Event::ContributionDropped { region_id }); Ok(()) From 0ab7449bdf65aee4e91d7a3152b6c47f662318bc Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 18 Jul 2023 17:24:11 +0200 Subject: [PATCH 072/131] Update frame/broker/src/mock.rs Co-authored-by: Oliver Tale-Yazdi --- frame/broker/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 6b80920a4eec2..d2ec80893b5e6 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -126,7 +126,7 @@ impl CoretimeInterface for TestCoretimeProvider { NotifyRevenueInfo::mutate(|s| s.insert(0, (when, total))); } fn credit_account(who: Self::AccountId, amount: Self::Balance) { - CoretimeCredit::mutate(|c| *c.entry(who).or_default() += amount); + CoretimeCredit::mutate(|c| c.entry(who).or_default().saturating_accrue(amount)); } fn assign_core( core: CoreIndex, From ad351b438769ff8bf7b6e7e0cf08979c621fb616 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:37:16 +0530 Subject: [PATCH 073/131] Addresses few review comments --- frame/broker/src/benchmarking.rs | 54 ++++++++++++++++++++++++-- frame/broker/src/dispatchable_impls.rs | 5 ++- frame/broker/src/mock.rs | 1 + frame/broker/src/tests.rs | 8 ++-- frame/broker/src/types.rs | 6 ++- frame/broker/src/utility_impls.rs | 3 +- 6 files changed, 65 insertions(+), 12 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 62372d66d8222..3149dbe101d7a 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -33,6 +33,10 @@ use sp_runtime::Saturating; const SEED: u32 = 0; const MAX_CORE_COUNT: u16 = 1_000; +fn assert_last_event(generic_event: ::RuntimeEvent) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + fn new_config_record() -> ConfigRecordOf { ConfigRecord { advance_notice: 2u32.into(), @@ -49,8 +53,11 @@ fn new_config_record() -> ConfigRecordOf { fn new_schedule() -> Schedule { // Max items for worst case let mut items = Vec::new(); - for i in 0..80 { - items.push(ScheduleItem { assignment: Task(i), part: CoreMask::complete() }); + for i in 0..CORE_MASK_BITS { + items.push(ScheduleItem { + assignment: Task(i.try_into().unwrap()), + part: CoreMask::complete(), + }); } Schedule::truncate_from(items) } @@ -187,6 +194,23 @@ mod benches { _(origin as T::RuntimeOrigin, initial_price, n.try_into().unwrap()); assert!(SaleInfo::::get().is_some()); + assert_last_event::( + Event::SaleInitialized { + sale_start: 2u32.into(), + leadin_length: 1u32.into(), + start_price: 20u32.into(), + regular_price: 10u32.into(), + region_begin: 4, + region_end: 7, + ideal_cores_sold: 0, + cores_offered: n + .saturating_sub(T::MaxReservedCores::get()) + .saturating_sub(T::MaxLeasedCores::get()) + .try_into() + .unwrap(), + } + .into(), + ); Ok(()) } @@ -201,9 +225,18 @@ mod benches { T::Currency::set_balance(&caller.clone(), 10u32.into()); #[extrinsic_call] - _(RawOrigin::Signed(caller), 10u32.into()); + _(RawOrigin::Signed(caller.clone()), 10u32.into()); assert_eq!(SaleInfo::::get().unwrap().sellout_price, Some(10u32.into())); + assert_last_event::( + Event::Purchased { + who: caller, + region_id: RegionId { begin: 4, core: 10, part: CoreMask::complete() }, + price: 10u32.into(), + duration: 3u32.into(), + } + .into(), + ); Ok(()) } @@ -287,6 +320,21 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region, 0x00000_fffff_fffff_00000.into()); + assert_last_event::( + Event::Interlaced { + old_region_id: RegionId { begin: 4, core: 10, part: CoreMask::complete() }, + new_region_ids: ( + RegionId { begin: 4, core: 10, part: 0x00000_fffff_fffff_00000.into() }, + RegionId { + begin: 4, + core: 10, + part: CoreMask::complete() ^ 0x00000_fffff_fffff_00000.into(), + }, + ), + } + .into(), + ); + Ok(()) } diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 07d9fbefcd971..723379db17c3c 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -380,7 +380,10 @@ impl Pallet { let contrib = InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownContribution)?; let end = region_id.begin.saturating_add(contrib.length); - ensure!(status.last_timeslice > end.saturating_add(config.contribution_timeout), Error::::StillValid); + ensure!( + status.last_timeslice > end.saturating_add(config.contribution_timeout), + Error::::StillValid + ); InstaPoolContribution::::remove(region_id); Self::deposit_event(Event::ContributionDropped { region_id }); Ok(()) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index d2ec80893b5e6..cac28576b2d86 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -33,6 +33,7 @@ use sp_core::{ConstU16, ConstU32, ConstU64, H256}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, Identity, IdentityLookup}, + Saturating, }; use sp_std::collections::btree_map::BTreeMap; diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 24feb96b7a565..06cfab584f84b 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -17,7 +17,7 @@ #![cfg(test)] -use crate::{core_part::*, mock::*, *}; +use crate::{core_mask::*, mock::*, *}; use frame_support::{ assert_noop, assert_ok, traits::nonfungible::{Inspect as NftInspect, Transfer}, @@ -115,21 +115,21 @@ fn drop_history_works() { assert_eq!(InstaPoolHistory::::iter().count(), 3); assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); advance_to(16); - assert_ok!(Broker::do_drop_history(region)); + assert_ok!(Broker::do_drop_history(region.begin)); assert_eq!(InstaPoolHistory::::iter().count(), 2); assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); advance_to(17); region.begin += 1; assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); advance_to(18); - assert_ok!(Broker::do_drop_history(region)); + assert_ok!(Broker::do_drop_history(region.begin)); assert_eq!(InstaPoolHistory::::iter().count(), 1); assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); advance_to(19); region.begin += 1; assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); advance_to(20); - assert_ok!(Broker::do_drop_history(region)); + assert_ok!(Broker::do_drop_history(region.begin)); assert_eq!(InstaPoolHistory::::iter().count(), 0); assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); }); diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 050c23b6e964d..1c266a6f05be8 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,4 +1,6 @@ -use crate::{Config, CoreAssignment, CoreIndex, CoreMask, CORE_MASK_BITS, CoretimeInterface, TaskId}; +use crate::{ + Config, CoreAssignment, CoreIndex, CoreMask, CoretimeInterface, TaskId, CORE_MASK_BITS, +}; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::fungible::Inspect; use frame_system::Config as SConfig; @@ -78,7 +80,7 @@ pub struct ScheduleItem { /// The job that the Core should be doing. pub assignment: CoreAssignment, } -pub type Schedule = BoundedVec>; +pub type Schedule = BoundedVec>; /// The record body of a Region which was contributed to the Instantaneous Coretime Pool. This helps /// with making pro rata payments to contributors. diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs index d2a5b1d4970a9..9dd16c5418151 100644 --- a/frame/broker/src/utility_impls.rs +++ b/frame/broker/src/utility_impls.rs @@ -8,7 +8,7 @@ use frame_support::{ }, }; use sp_arithmetic::{ - traits::{Bounded, SaturatedConversion, Saturating}, + traits::{SaturatedConversion, Saturating}, FixedPointNumber, FixedU64, }; use sp_runtime::traits::AccountIdConversion; @@ -101,4 +101,3 @@ impl Pallet { Ok(Some((region_id, region))) } } - From eef284390b4d93502384147a898d9eec64ec856a Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:47:33 +0530 Subject: [PATCH 074/131] Addresses few review comments --- frame/broker/src/benchmarking.rs | 52 +++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 3149dbe101d7a..63e1576c11405 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -82,7 +82,7 @@ fn advance_to(b: u32) { } } -fn setup_and_start_sale() -> Result<(), BenchmarkError> { +fn setup_and_start_sale() -> Result { Configuration::::put(new_config_record::()); // Assume Reservations to be filled for worst case @@ -94,7 +94,10 @@ fn setup_and_start_sale() -> Result<(), BenchmarkError> { Broker::::do_start_sales(10u32.into(), MAX_CORE_COUNT.into()) .map_err(|_| BenchmarkError::Weightless)?; - Ok(()) + Ok(T::MaxReservedCores::get() + .saturating_add(T::MaxLeasedCores::get()) + .try_into() + .unwrap()) } #[benchmarks] @@ -217,7 +220,7 @@ mod benches { #[benchmark] fn purchase() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -231,7 +234,7 @@ mod benches { assert_last_event::( Event::Purchased { who: caller, - region_id: RegionId { begin: 4, core: 10, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, price: 10u32.into(), duration: 3u32.into(), } @@ -307,7 +310,7 @@ mod benches { #[benchmark] fn interlace() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -322,12 +325,12 @@ mod benches { assert_last_event::( Event::Interlaced { - old_region_id: RegionId { begin: 4, core: 10, part: CoreMask::complete() }, + old_region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, new_region_ids: ( - RegionId { begin: 4, core: 10, part: 0x00000_fffff_fffff_00000.into() }, + RegionId { begin: 4, core, part: 0x00000_fffff_fffff_00000.into() }, RegionId { begin: 4, - core: 10, + core, part: CoreMask::complete() ^ 0x00000_fffff_fffff_00000.into(), }, ), @@ -358,7 +361,7 @@ mod benches { #[benchmark] fn pool() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -373,6 +376,14 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region, recipient, Final); + assert_last_event::( + Event::Pooled { + region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + duration: 3u32.into(), + } + .into(), + ); + Ok(()) } @@ -427,7 +438,7 @@ mod benches { #[benchmark] fn drop_region() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -442,12 +453,20 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region); + assert_last_event::( + Event::RegionDropped { + region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + duration: 3u32.into(), + } + .into(), + ); + Ok(()) } #[benchmark] fn drop_contribution() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -467,6 +486,13 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region); + assert_last_event::( + Event::ContributionDropped { + region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + } + .into(), + ); + Ok(()) } @@ -478,6 +504,10 @@ mod benches { #[extrinsic_call] _(admin_origin as T::RuntimeOrigin, n.try_into().unwrap()); + assert_last_event::( + Event::CoreCountRequested { core_count: n.try_into().unwrap() }.into(), + ); + Ok(()) } From 5be7e916ec59ea3bfdcc739251d7653d1db49334 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 10:55:56 +0530 Subject: [PATCH 075/131] Addresses few review comments --- frame/broker/src/benchmarking.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 63e1576c11405..4a201ac78f34f 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -343,7 +343,7 @@ mod benches { #[benchmark] fn assign() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -356,6 +356,18 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region, 1000, Final); + let workplan_key = (region.begin, region.core); + assert!(Workplan::::get(workplan_key).is_some()); + + assert_last_event::( + Event::Assigned { + region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + task: 1000, + duration: 3u32.into(), + } + .into(), + ); + Ok(()) } @@ -376,6 +388,9 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region, recipient, Final); + let workplan_key = (region.begin, region.core); + assert!(Workplan::::get(workplan_key).is_some()); + assert_last_event::( Event::Pooled { region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, @@ -410,7 +425,6 @@ mod benches { Ok(()) } - // Todo: Check further for worst case #[benchmark] fn purchase_credit() -> Result<(), BenchmarkError> { setup_and_start_sale::()?; @@ -431,7 +445,11 @@ mod benches { let beneficiary: RelayAccountIdOf = account("beneficiary", 0, SEED); #[extrinsic_call] - _(RawOrigin::Signed(caller), 20u32.into(), beneficiary); + _(RawOrigin::Signed(caller.clone()), 20u32.into(), beneficiary.clone()); + + assert_last_event::( + Event::CreditPurchased { who: caller, beneficiary, amount: 20u32.into() }.into(), + ); Ok(()) } From 6b6ea4f29f38c45991dd57bf7e3827fb5498047a Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 14:17:40 +0530 Subject: [PATCH 076/131] Merge --- primitives/weights/src/weight_meter.rs | 113 +++++++++++++++++++++---- 1 file changed, 98 insertions(+), 15 deletions(-) diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 6accf42ae8fe4..49d96178004a2 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -32,18 +32,21 @@ use sp_arithmetic::Perbill; /// /// // The weight is limited to (10, 0). /// let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); -/// // There is enough weight remaining for an operation with (5, 0) weight. -/// assert!(meter.check_accrue(Weight::from_parts(5, 0))); -/// // There is not enough weight remaining for an operation with (6, 0) weight. -/// assert!(!meter.check_accrue(Weight::from_parts(6, 0))); +/// // There is enough weight remaining for an operation with (6, 0) weight. +/// assert!(meter.try_consume(Weight::from_parts(6, 0)).is_ok()); +/// assert_eq!(meter.remaining(), Weight::from_parts(4, 0)); +/// // There is not enough weight remaining for an operation with (5, 0) weight. +/// assert!(!meter.try_consume(Weight::from_parts(5, 0)).is_ok()); +/// // The total limit is obviously unchanged: +/// assert_eq!(meter.limit(), Weight::from_parts(10, 0)); /// ``` #[derive(Debug, Clone)] pub struct WeightMeter { /// The already consumed weight. - pub consumed: Weight, + consumed: Weight, /// The maximal consumable weight. - pub limit: Weight, + limit: Weight, } impl WeightMeter { @@ -57,6 +60,16 @@ impl WeightMeter { Self::from_limit(Weight::MAX) } + /// The already consumed weight. + pub fn consumed(&self) -> Weight { + self.consumed + } + + /// The limit can ever be accrued. + pub fn limit(&self) -> Weight { + self.limit + } + /// The remaining weight that can still be consumed. pub fn remaining(&self) -> Weight { self.limit.saturating_sub(self.consumed) @@ -65,6 +78,28 @@ impl WeightMeter { /// The ratio of consumed weight to the limit. /// /// Calculates one ratio per component and returns the largest. + /// + /// # Example + /// ```rust + /// use sp_weights::{Weight, WeightMeter}; + /// use sp_arithmetic::Perbill; + /// + /// let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 20)); + /// // Nothing consumed so far: + /// assert_eq!(meter.consumed_ratio(), Perbill::from_percent(0)); + /// meter.consume(Weight::from_parts(5, 5)); + /// // The ref-time is the larger ratio: + /// assert_eq!(meter.consumed_ratio(), Perbill::from_percent(50)); + /// meter.consume(Weight::from_parts(1, 10)); + /// // Now the larger ratio is proof-size: + /// assert_eq!(meter.consumed_ratio(), Perbill::from_percent(75)); + /// // Eventually it reaches 100%: + /// meter.consume(Weight::from_parts(4, 0)); + /// assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); + /// // Saturating the second component won't change anything anymore: + /// meter.consume(Weight::from_parts(0, 5)); + /// assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); + /// ``` pub fn consumed_ratio(&self) -> Perbill { let time = Perbill::from_rational(self.consumed.ref_time(), self.limit.ref_time()); let pov = Perbill::from_rational(self.consumed.proof_size(), self.limit.proof_size()); @@ -72,14 +107,12 @@ impl WeightMeter { } /// Consume some weight and defensively fail if it is over the limit. Saturate in any case. - #[deprecated = "Use `consume` instead"] + #[deprecated(note = "Use `consume` instead. Will be removed after December 2023.")] pub fn defensive_saturating_accrue(&mut self, w: Weight) { self.consume(w); } /// Consume some weight and defensively fail if it is over the limit. Saturate in any case. - /// - /// This is provided as a less noisy version of `defensive_saturating_accrue`. pub fn consume(&mut self, w: Weight) { self.consumed.saturating_accrue(w); debug_assert!(self.consumed.all_lte(self.limit), "Weight counter overflow"); @@ -87,13 +120,14 @@ impl WeightMeter { /// Consume the given weight after checking that it can be consumed and return `true`. Otherwise /// do nothing and return `false`. - #[deprecated = "Use `try_consume` instead"] + #[deprecated(note = "Use `try_consume` instead. Will be removed after December 2023.")] pub fn check_accrue(&mut self, w: Weight) -> bool { self.try_consume(w).is_ok() } - /// Consume the given weight after checking that it can be consumed and return `Ok`. Otherwise - /// do nothing and return `Err`. + /// Consume the given weight after checking that it can be consumed. + /// + /// Returns `Ok` if the weight can be consumed or otherwise an `Err`. pub fn try_consume(&mut self, w: Weight) -> Result<(), ()> { self.consumed.checked_add(&w).map_or(Err(()), |test| { if test.any_gt(self.limit) { @@ -106,9 +140,9 @@ impl WeightMeter { } /// Check if the given weight can be consumed. - #[deprecated = "Use `can_consume` instead"] + #[deprecated(note = "Use `can_consume` instead. Will be removed after December 2023.")] pub fn can_accrue(&self, w: Weight) -> bool { - self.consumed.checked_add(&w).map_or(false, |t| t.all_lte(self.limit)) + self.can_consume(w) } /// Check if the given weight can be consumed. @@ -120,6 +154,7 @@ impl WeightMeter { #[cfg(test)] mod tests { use crate::*; + use sp_arithmetic::traits::Zero; #[test] fn weight_meter_remaining_works() { @@ -201,4 +236,52 @@ mod tests { assert!(meter.check_accrue(Weight::from_parts(0, 4))); assert_eq!(meter.consumed_ratio(), Perbill::from_percent(100)); } -} + + #[test] + fn try_consume_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); + + assert!(meter.try_consume(Weight::from_parts(11, 0)).is_err()); + assert!(meter.consumed().is_zero(), "No modification"); + + assert!(meter.try_consume(Weight::from_parts(9, 0)).is_ok()); + assert!(meter.try_consume(Weight::from_parts(2, 0)).is_err()); + assert!(meter.try_consume(Weight::from_parts(1, 0)).is_ok()); + assert!(meter.remaining().is_zero()); + assert_eq!(meter.consumed(), Weight::from_parts(10, 0)); + } + + #[test] + fn can_consume_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); + + assert!(!meter.can_consume(Weight::from_parts(11, 0))); + assert!(meter.consumed().is_zero(), "No modification"); + + assert!(meter.can_consume(Weight::from_parts(9, 0))); + meter.consume(Weight::from_parts(9, 0)); + assert!(!meter.can_consume(Weight::from_parts(2, 0))); + assert!(meter.can_consume(Weight::from_parts(1, 0))); + } + + #[test] + #[cfg(debug_assertions)] + fn consume_works() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(5, 10)); + + meter.consume(Weight::from_parts(4, 0)); + assert_eq!(meter.remaining(), Weight::from_parts(1, 10)); + meter.consume(Weight::from_parts(1, 0)); + assert_eq!(meter.remaining(), Weight::from_parts(0, 10)); + meter.consume(Weight::from_parts(0, 10)); + assert_eq!(meter.consumed(), Weight::from_parts(5, 10)); + } + + #[test] + #[cfg(debug_assertions)] + #[should_panic(expected = "Weight counter overflow")] + fn consume_defensive_fail() { + let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); + let _ = meter.consume(Weight::from_parts(11, 0)); + } +} \ No newline at end of file From 02cbe447c908b67046ae20e852fe1d260e1a1d56 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 14:19:16 +0530 Subject: [PATCH 077/131] Merge --- frame/broker/src/tick_impls.rs | 2 +- primitives/weights/src/weight_meter.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 47ff3df05a023..efeb825deedba 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -64,7 +64,7 @@ impl Pallet { Status::::put(&status); - meter.consumed + meter.consumed() } fn process_core_count(status: &mut StatusRecord) -> bool { diff --git a/primitives/weights/src/weight_meter.rs b/primitives/weights/src/weight_meter.rs index 49d96178004a2..3b0b21ea8799a 100644 --- a/primitives/weights/src/weight_meter.rs +++ b/primitives/weights/src/weight_meter.rs @@ -284,4 +284,4 @@ mod tests { let mut meter = WeightMeter::from_limit(Weight::from_parts(10, 0)); let _ = meter.consume(Weight::from_parts(11, 0)); } -} \ No newline at end of file +} From 8732e1165a7cd2ca8da0b8043155d1a9d971f91e Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 19 Jul 2023 08:54:59 +0000 Subject: [PATCH 078/131] ".git/.scripts/commands/fmt/fmt.sh" --- frame/broker/src/mock.rs | 3 +-- frame/broker/src/types.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index e1d26f6242c29..ddeca4941494f 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -31,9 +31,8 @@ use frame_system::{EnsureRoot, EnsureSignedBy}; use sp_arithmetic::Perbill; use sp_core::{ConstU16, ConstU32, ConstU64, H256}; use sp_runtime::{ - BuildStorage, traits::{BlakeTwo256, Identity, IdentityLookup}, - Saturating, + BuildStorage, Saturating, }; use sp_std::collections::btree_map::BTreeMap; diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 6e09473c887f1..7e9e3dea4513e 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -3,8 +3,7 @@ use crate::{ }; use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::fungible::Inspect; -use frame_system::Config as SConfig; -use frame_system::pallet_prelude::BlockNumberFor; +use frame_system::{pallet_prelude::BlockNumberFor, Config as SConfig}; use scale_info::TypeInfo; use sp_arithmetic::Perbill; use sp_core::{ConstU32, RuntimeDebug}; From 6ffb4aa8535824054cee9883abf97f0346501b6c Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:24:22 +0530 Subject: [PATCH 079/131] Integrates broker in kitchensink --- Cargo.lock | 1 + bin/node/runtime/Cargo.toml | 4 ++++ bin/node/runtime/src/lib.rs | 32 ++++++++++++++++++++++++++ frame/broker/Cargo.toml | 11 +++++---- frame/broker/src/coretime_interface.rs | 4 ++-- frame/broker/src/lib.rs | 4 +++- frame/broker/src/nonfungible_impl.rs | 1 + frame/broker/src/tick_impls.rs | 1 + 8 files changed, 51 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 038a095d73dc7..69f578fc56688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4094,6 +4094,7 @@ dependencies = [ "pallet-bags-list", "pallet-balances", "pallet-bounties", + "pallet-broker", "pallet-child-bounties", "pallet-collective", "pallet-contracts", diff --git a/bin/node/runtime/Cargo.toml b/bin/node/runtime/Cargo.toml index 30f0052c6eaa6..7d94ad6dbdbd7 100644 --- a/bin/node/runtime/Cargo.toml +++ b/bin/node/runtime/Cargo.toml @@ -66,6 +66,7 @@ pallet-babe = { version = "4.0.0-dev", default-features = false, path = "../../. pallet-bags-list = { version = "4.0.0-dev", default-features = false, path = "../../../frame/bags-list" } pallet-balances = { version = "4.0.0-dev", default-features = false, path = "../../../frame/balances" } pallet-bounties = { version = "4.0.0-dev", default-features = false, path = "../../../frame/bounties" } +pallet-broker = { version = "0.1.0", default-features = false, path = "../../../frame/broker" } pallet-child-bounties = { version = "4.0.0-dev", default-features = false, path = "../../../frame/child-bounties" } pallet-collective = { version = "4.0.0-dev", default-features = false, path = "../../../frame/collective" } pallet-contracts = { version = "4.0.0-dev", default-features = false, path = "../../../frame/contracts" } @@ -153,6 +154,7 @@ std = [ "pallet-bags-list/std", "pallet-balances/std", "pallet-bounties/std", + "pallet-broker/std", "sp-block-builder/std", "codec/std", "scale-info/std", @@ -249,6 +251,7 @@ runtime-benchmarks = [ "pallet-bags-list/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-bounties/runtime-benchmarks", + "pallet-broker/runtime-benchmarks", "pallet-child-bounties/runtime-benchmarks", "pallet-collective/runtime-benchmarks", "pallet-contracts/runtime-benchmarks", @@ -313,6 +316,7 @@ try-runtime = [ "pallet-bags-list/try-runtime", "pallet-balances/try-runtime", "pallet-bounties/try-runtime", + "pallet-broker/try-runtime", "pallet-child-bounties/try-runtime", "pallet-collective/try-runtime", "pallet-contracts/try-runtime", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index e6c52216b7910..242611acb3a54 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1868,6 +1868,36 @@ impl pallet_statement::Config for Runtime { type MaxAllowedBytes = MaxAllowedBytes; } +parameter_types! { + pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); +} + +use frame_support::traits::fungible::{Balanced, Credit}; + +pub struct IntoAuthor; +impl OnUnbalanced> for IntoAuthor { + fn on_nonzero_unbalanced(credit: Credit) { + if let Some(author) = Authorship::author() { + let _ = >::resolve(&author, credit); + } + } +} + +impl pallet_broker::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Currency = Balances; + type OnRevenue = IntoAuthor; + type TimeslicePeriod = ConstU32<2>; + type MaxLeasedCores = ConstU32<5>; + type MaxReservedCores = ConstU32<5>; + type Coretime = (); + type ConvertBalance = sp_runtime::traits::Identity; + type WeightInfo = (); + type PalletId = BrokerPalletId; + type AdminOrigin = EnsureRoot; + type PriceAdapter = pallet_broker::Linear; +} + construct_runtime!( pub struct Runtime { @@ -1941,6 +1971,7 @@ construct_runtime!( MessageQueue: pallet_message_queue, Pov: frame_benchmarking_pallet_pov, Statement: pallet_statement, + Broker: pallet_broker, } ); @@ -2021,6 +2052,7 @@ mod benches { [pallet_bags_list, VoterList] [pallet_balances, Balances] [pallet_bounties, Bounties] + [pallet_broker, Broker] [pallet_child_bounties, ChildBounties] [pallet_collective, Council] [pallet_conviction_voting, ConvictionVoting] diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index af05d2d65a450..17f73cce52e99 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -15,10 +15,10 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive"] } scale-info = { version = "2.0.0", default-features = false, features = ["derive"] } bitvec = "1" -sp-std = { version = "8.0.0", path = "../../primitives/std" } -sp-arithmetic = { version = "16.0.0", path = "../../primitives/arithmetic" } -sp-core = { version = "21.0.0", path = "../../primitives/core" } -sp-runtime = { version = "24.0.0", path = "../../primitives/runtime" } +sp-std = { version = "8.0.0", default-features = false, path = "../../primitives/std" } +sp-arithmetic = { version = "16.0.0", default-features = false, path = "../../primitives/arithmetic" } +sp-core = { version = "21.0.0", default-features = false, path = "../../primitives/core" } +sp-runtime = { version = "24.0.0", default-features = false, path = "../../primitives/runtime" } frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } @@ -36,6 +36,9 @@ std = [ "frame-system/std", "scale-info/std", "sp-runtime/std", + "sp-arithmetic/std", + "sp-core/std", + "sp-std/std", ] runtime-benchmarks = [ diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 1e5ebd34694c5..d7ab7fd504ee0 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -3,7 +3,7 @@ use frame_support::Parameter; use scale_info::TypeInfo; use sp_arithmetic::traits::AtLeast32BitUnsigned; use sp_core::RuntimeDebug; -use sp_std::fmt::Debug; +use sp_std::{fmt::Debug, vec::Vec}; /// Index of a Polkadot Core. pub type CoreIndex = u16; @@ -52,7 +52,7 @@ pub trait CoretimeInterface { } impl CoretimeInterface for () { type AccountId = (); - type Balance = u64; + type Balance = u128; type BlockNumber = u32; fn latest() -> Self::BlockNumber { 0 diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 70fc708b06a04..dfae6a33e83e4 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -25,9 +25,10 @@ mod benchmarking; mod core_mask; mod coretime_interface; mod dispatchable_impls; -mod mock; mod nonfungible_impl; +#[cfg(test)] mod test_fungibles; +#[cfg(test)] mod tests; mod tick_impls; mod types; @@ -56,6 +57,7 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; use sp_runtime::traits::{Convert, ConvertBack}; + use sp_std::vec::Vec; #[pallet::pallet] pub struct Pallet(_); diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index e4537a6da5684..ed96ce38c0837 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -3,6 +3,7 @@ use frame_support::{ pallet_prelude::{DispatchResult, *}, traits::nonfungible::{Inspect, Transfer}, }; +use sp_std::vec::Vec; impl Inspect for Pallet { type ItemId = u128; diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index efeb825deedba..6622ea348eb07 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -5,6 +5,7 @@ use sp_arithmetic::{ FixedPointNumber, }; use sp_runtime::traits::ConvertBack; +use sp_std::{vec, vec::Vec}; use CompletionStatus::Complete; impl Pallet { From 053bc3f3b40f747002c02f9406d3a09f553af328 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 16:31:38 +0530 Subject: [PATCH 080/131] Minor update --- bin/node/runtime/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 242611acb3a54..f483a931a5f92 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -34,7 +34,7 @@ use frame_support::{ pallet_prelude::Get, parameter_types, traits::{ - fungible::ItemOf, + fungible::{Balanced, Credit, ItemOf}, tokens::{nonfungibles_v2::Inspect, GetSalary, PayFromAccount}, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, @@ -1872,8 +1872,6 @@ parameter_types! { pub const BrokerPalletId: PalletId = PalletId(*b"py/broke"); } -use frame_support::traits::fungible::{Balanced, Credit}; - pub struct IntoAuthor; impl OnUnbalanced> for IntoAuthor { fn on_nonzero_unbalanced(credit: Credit) { From db5db14620c60abe7b36768d7d97291a13184b43 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 21:42:04 +0530 Subject: [PATCH 081/131] Fixes typo --- frame/broker/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index dfae6a33e83e4..2b5343bb62b1f 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -26,6 +26,7 @@ mod core_mask; mod coretime_interface; mod dispatchable_impls; mod nonfungible_impl; +mod mock; #[cfg(test)] mod test_fungibles; #[cfg(test)] From 9645b1ffca33bd8b1bc63167beb86ee539588529 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 21:45:59 +0530 Subject: [PATCH 082/131] Moves balance back to u64 --- frame/broker/src/coretime_interface.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index d7ab7fd504ee0..009c8b42107d1 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -52,7 +52,7 @@ pub trait CoretimeInterface { } impl CoretimeInterface for () { type AccountId = (); - type Balance = u128; + type Balance = u64; type BlockNumber = u32; fn latest() -> Self::BlockNumber { 0 From cd60c546eed8990922dddb2392cbcb866960aecc Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:17:57 +0530 Subject: [PATCH 083/131] Fixes kitchensink build --- bin/node/runtime/src/lib.rs | 18 +++++++++++++++--- frame/broker/src/lib.rs | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index f483a931a5f92..2d9250c08ab2a 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -74,8 +74,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, ConvertBack, ConvertInto, + NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perbill, Percent, Permill, Perquintill, @@ -1881,6 +1881,18 @@ impl OnUnbalanced> for IntoAuthor { } } +pub struct BalanceToCoretimeBalance; +impl Convert for BalanceToCoretimeBalance { + fn convert(balance: Balance) -> u64 { + balance.try_into().unwrap_or(u64::max_value()) + } +} +impl ConvertBack for BalanceToCoretimeBalance { + fn convert_back(n: u64) -> Balance { + Balance::from(n) + } +} + impl pallet_broker::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; @@ -1889,7 +1901,7 @@ impl pallet_broker::Config for Runtime { type MaxLeasedCores = ConstU32<5>; type MaxReservedCores = ConstU32<5>; type Coretime = (); - type ConvertBalance = sp_runtime::traits::Identity; + type ConvertBalance = BalanceToCoretimeBalance; type WeightInfo = (); type PalletId = BrokerPalletId; type AdminOrigin = EnsureRoot; diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 2b5343bb62b1f..b599cb6ce037e 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -25,8 +25,8 @@ mod benchmarking; mod core_mask; mod coretime_interface; mod dispatchable_impls; -mod nonfungible_impl; mod mock; +mod nonfungible_impl; #[cfg(test)] mod test_fungibles; #[cfg(test)] From ad24d8d33b28a16581947efe9da482fc61869ec6 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 20 Jul 2023 11:50:44 +0530 Subject: [PATCH 084/131] Fixes worst case for assign --- frame/broker/src/benchmarking.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 4a201ac78f34f..c5ca91bcd3d68 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -103,7 +103,7 @@ fn setup_and_start_sale() -> Result { #[benchmarks] mod benches { use super::*; - use crate::Finality::Final; + use crate::Finality::*; #[benchmark] fn configure() -> Result<(), BenchmarkError> { @@ -354,11 +354,13 @@ mod benches { .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(RawOrigin::Signed(caller), region, 1000, Final); + _(RawOrigin::Signed(caller), region, 1000, Provisional); let workplan_key = (region.begin, region.core); assert!(Workplan::::get(workplan_key).is_some()); + assert!(Regions::::get(region).is_some()); + assert_last_event::( Event::Assigned { region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, From f81e09daa14c49a071a3313a35da4338ee5e10d9 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:35:01 +0530 Subject: [PATCH 085/131] Adds benchmark for process_core_count --- frame/broker/src/benchmarking.rs | 20 ++++++++++++++++++++ frame/broker/src/tick_impls.rs | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index c5ca91bcd3d68..f91d4f8969832 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -531,6 +531,26 @@ mod benches { Ok(()) } + #[benchmark] + fn process_core_count(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + let core_count = n.try_into().unwrap(); + + Broker::::do_request_core_count(core_count).map_err(|_| BenchmarkError::Weightless)?; + + let mut status = Status::::get().ok_or(BenchmarkError::Weightless)?; + + #[block] + { + Broker::::process_core_count(&mut status); + } + + assert_last_event::(Event::CoreCountChanged { core_count }.into()); + + Ok(()) + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 6622ea348eb07..4da01582c6051 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -68,7 +68,7 @@ impl Pallet { meter.consumed() } - fn process_core_count(status: &mut StatusRecord) -> bool { + pub(crate) fn process_core_count(status: &mut StatusRecord) -> bool { if let Some(core_count) = T::Coretime::check_notify_core_count() { status.core_count = core_count; Self::deposit_event(Event::::CoreCountChanged { core_count }); From 98c8ad1bf9989f7f6245f288e056b449cb003db8 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 20 Jul 2023 17:52:57 +0530 Subject: [PATCH 086/131] Adds a couple of more benchmarks --- frame/broker/src/benchmarking.rs | 71 ++++++++++++++++++++++++++++++++ frame/broker/src/tick_impls.rs | 2 +- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index f91d4f8969832..cc42213287aa8 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -551,6 +551,77 @@ mod benches { Ok(()) } + #[benchmark] + fn rotate_sale(n: Linear<0, { MAX_CORE_COUNT.into() }>) { + let core_count = n.try_into().unwrap(); + let config = new_config_record::(); + + let now = frame_system::Pallet::::block_number(); + let price = 10u32.into(); + let commit_timeslice = Broker::::latest_timeslice_ready_to_commit(&config); + let sale = SaleInfoRecordOf:: { + sale_start: now, + leadin_length: Zero::zero(), + price, + sellout_price: None, + region_begin: commit_timeslice, + region_end: commit_timeslice.saturating_add(config.region_length), + first_core: 0, + ideal_cores_sold: 0, + cores_offered: 0, + cores_sold: 0, + }; + + let status = StatusRecord { + core_count, + private_pool_size: 0, + system_pool_size: 0, + last_committed_timeslice: commit_timeslice.saturating_sub(1), + last_timeslice: Broker::::current_timeslice(), + }; + + // Assume Reservations to be filled for worst case + setup_reservations::(T::MaxReservedCores::get()); + + // Assume Leases to be filled for worst case + setup_leases::(T::MaxLeasedCores::get(), 1, 10); + + #[block] + { + Broker::::rotate_sale(sale, &config, &status); + } + + assert!(SaleInfo::::get().is_some()); + assert_last_event::( + Event::SaleInitialized { + sale_start: 2u32.into(), + leadin_length: 1u32.into(), + start_price: 20u32.into(), + regular_price: 10u32.into(), + region_begin: 4, + region_end: 7, + ideal_cores_sold: 0, + cores_offered: n + .saturating_sub(T::MaxReservedCores::get()) + .saturating_sub(T::MaxLeasedCores::get()) + .try_into() + .unwrap(), + } + .into(), + ); + } + + #[benchmark] + fn request_revenue_info_at() { + let current_timeslice = Broker::::current_timeslice(); + let rc_block = T::TimeslicePeriod::get() * current_timeslice.into(); + + #[block] + { + T::Coretime::request_revenue_info_at(rc_block); + } + } + // Implements a test for each benchmark. Execute with: // `cargo test -p pallet-broker --features runtime-benchmarks`. impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 4da01582c6051..911c9c584410f 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -77,7 +77,7 @@ impl Pallet { false } - fn process_revenue() -> bool { + pub(crate) fn process_revenue() -> bool { let (until, amount) = match T::Coretime::check_notify_revenue_info() { Some(x) => x, None => return false, From 140e80b5c8cdc52389a66c42bd31094ed1d3eac7 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 10:31:10 +0530 Subject: [PATCH 087/131] Adds an assert for partition --- frame/broker/src/benchmarking.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index cc42213287aa8..7a6a3e7d8c55f 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -292,7 +292,7 @@ mod benches { #[benchmark] fn partition() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + let core = setup_and_start_sale::()?; advance_to::(2); @@ -305,6 +305,17 @@ mod benches { #[extrinsic_call] _(RawOrigin::Signed(caller), region, 2); + assert_last_event::( + Event::Partitioned { + old_region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + new_region_ids: ( + RegionId { begin: 4, core, part: CoreMask::complete() }, + RegionId { begin: 6, core, part: CoreMask::complete() }, + ), + } + .into(), + ); + Ok(()) } From 64079a7c523c0f4418c6322fa6ff8c55d0b98244 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 10:58:44 +0530 Subject: [PATCH 088/131] Uses max_timeslices as input in claim_revenue benchmark --- frame/broker/src/benchmarking.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 7a6a3e7d8c55f..c40d2bb0dde2c 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -416,8 +416,10 @@ mod benches { } #[benchmark] - fn claim_revenue() -> Result<(), BenchmarkError> { - setup_and_start_sale::()?; + fn claim_revenue( + m: Linear<0, { new_config_record::().region_length }>, + ) -> Result<(), BenchmarkError> { + let core = setup_and_start_sale::()?; advance_to::(2); @@ -429,11 +431,24 @@ mod benches { let recipient: T::AccountId = account("recipient", 0, SEED); - Broker::::do_pool(region, None, recipient, Final) + Broker::::do_pool(region, None, recipient.clone(), Final) .map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(RawOrigin::Signed(caller), region, 100); + _(RawOrigin::Signed(caller), region, m); + + assert_last_event::( + Event::RevenueClaimPaid { + who: recipient, + amount: 0u32.into(), // Todo: fix the conditions for this benchmark + next: if m < new_config_record::().region_length { + Some(RegionId { begin: 4.saturating_add(m), core, part: CoreMask::complete() }) + } else { + None + }, + } + .into(), + ); Ok(()) } From d4e397b3a58a6aa8eef731976c5f5db5ebefcdeb Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:09:54 +0530 Subject: [PATCH 089/131] Adds benchmark for drop_renewal --- frame/broker/src/benchmarking.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index c40d2bb0dde2c..1cdbb30941b66 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -542,6 +542,31 @@ mod benches { Ok(()) } + #[benchmark] + fn drop_renewal() -> Result<(), BenchmarkError> { + let core = setup_and_start_sale::()?; + let when = 5u32.into(); + + advance_to::(10); + + let id = AllowedRenewalId { core, when }; + let record = AllowedRenewalRecord { + price: 1u32.into(), + completion: CompletionStatus::Complete(new_schedule()), + }; + AllowedRenewals::::insert(id, record); + + let caller: T::AccountId = whitelisted_caller(); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), core, when); + + assert!(AllowedRenewals::::get(id).is_none()); + assert_last_event::(Event::AllowedRenewalDropped { core, when }.into()); + + Ok(()) + } + #[benchmark] fn request_core_count(n: Linear<0, { MAX_CORE_COUNT.into() }>) -> Result<(), BenchmarkError> { let admin_origin = From 000181c7078c27ecd8d6d8c334f16c26928883cc Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:31:49 +0530 Subject: [PATCH 090/131] Adds benchmark for process_core_schedule --- frame/broker/src/benchmarking.rs | 22 ++++++++++++++++++++++ frame/broker/src/tick_impls.rs | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 1cdbb30941b66..cf73a18df45e1 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -662,6 +662,28 @@ mod benches { ); } + #[benchmark] + fn process_core_schedule() { + let timeslice = 10u32.into(); + let core = 5u16.into(); + let rc_begin = 1u32.into(); + + Workplan::::insert((timeslice, core), new_schedule()); + + #[block] + { + Broker::::process_core_schedule(timeslice, rc_begin, core); + } + + assert_eq!(Workload::::get(core).len(), CORE_MASK_BITS); + + let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = vec![]; + for i in 0..CORE_MASK_BITS { + assignment.push((CoreAssignment::Task(i.try_into().unwrap()), 57600)); + } + assert_last_event::(Event::CoreAssigned { core, when: rc_begin, assignment }.into()); + } + #[benchmark] fn request_revenue_info_at() { let current_timeslice = Broker::::current_timeslice(); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 911c9c584410f..6f289d2b8d042 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -267,7 +267,7 @@ impl Pallet { } /// Schedule cores for the given `timeslice`. - fn process_core_schedule( + pub(crate) fn process_core_schedule( timeslice: Timeslice, rc_begin: RelayBlockNumberOf, core: CoreIndex, From 03f288143dcfd9e687fb5a7126532e50c9310cb3 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 11:41:29 +0530 Subject: [PATCH 091/131] Adds benchmark for process_pool --- frame/broker/src/benchmarking.rs | 27 +++++++++++++++++++++++++++ frame/broker/src/tick_impls.rs | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index cf73a18df45e1..f2a7116be8d97 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -662,6 +662,33 @@ mod benches { ); } + #[benchmark] + fn process_pool() { + let when = 10u32.into(); + let private_pool_size = 5u32.into(); + let system_pool_size = 4u32.into(); + + let config = new_config_record::(); + let commit_timeslice = Broker::::latest_timeslice_ready_to_commit(&config); + let mut status = StatusRecord { + core_count: 5u16.into(), + private_pool_size, + system_pool_size, + last_committed_timeslice: commit_timeslice.saturating_sub(1), + last_timeslice: Broker::::current_timeslice(), + }; + + #[block] + { + Broker::::process_pool(when, &mut status); + } + + assert!(InstaPoolHistory::::get(when).is_some()); + assert_last_event::( + Event::HistoryInitialized { when, private_pool_size, system_pool_size }.into(), + ); + } + #[benchmark] fn process_core_schedule() { let timeslice = 10u32.into(); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 6f289d2b8d042..9c81cc387baf0 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -247,7 +247,7 @@ impl Pallet { Some(()) } - fn process_pool(when: Timeslice, status: &mut StatusRecord) { + pub(crate) fn process_pool(when: Timeslice, status: &mut StatusRecord) { let pool_io = InstaPoolIo::::take(when); status.private_pool_size = (status.private_pool_size as SignedCoreMaskBitCount) .saturating_add(pool_io.private) as CoreMaskBitCount; From 92892c39d8cc3d8e9f0b20be9da872f32f643765 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Fri, 21 Jul 2023 16:39:42 +0530 Subject: [PATCH 092/131] Adds assertion for transfer --- frame/broker/src/benchmarking.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index f2a7116be8d97..6c6783f0ca6d4 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -285,7 +285,17 @@ mod benches { let recipient: T::AccountId = account("recipient", 0, SEED); #[extrinsic_call] - _(RawOrigin::Signed(caller), region, recipient); + _(RawOrigin::Signed(caller.clone()), region, recipient.clone()); + + assert_last_event::( + Event::Transferred { + region_id: region, + old_owner: caller, + owner: recipient, + duration: 3u32.into(), + } + .into(), + ); Ok(()) } From c59344795b0d3b1ad2860e6d578903dd48df3a88 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sun, 23 Jul 2023 11:54:01 +0530 Subject: [PATCH 093/131] Fixes benchmark for broker in kitchensink --- bin/node/runtime/src/lib.rs | 45 ++++++++++++++++------- frame/broker/src/benchmarking.rs | 61 +++++++++++++++++++++++++------- 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2d9250c08ab2a..547b46b226af9 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -55,6 +55,7 @@ use frame_system::{ pub use node_primitives::{AccountId, Signature}; use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Moment, Nonce}; use pallet_asset_conversion::{NativeOrAssetId, NativeOrAssetIdConverter}; +use pallet_broker::{CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600}; #[cfg(feature = "runtime-benchmarks")] use pallet_contracts::NoopMigration; use pallet_election_provider_multi_phase::SolutionAccuracyOf; @@ -74,8 +75,8 @@ use sp_runtime::{ curve::PiecewiseLinear, generic, impl_opaque_keys, traits::{ - self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertBack, ConvertInto, - NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup, + self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, NumberFor, + OpaqueKeys, SaturatedConversion, StaticLookup, }, transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perbill, Percent, Permill, Perquintill, @@ -1881,15 +1882,35 @@ impl OnUnbalanced> for IntoAuthor { } } -pub struct BalanceToCoretimeBalance; -impl Convert for BalanceToCoretimeBalance { - fn convert(balance: Balance) -> u64 { - balance.try_into().unwrap_or(u64::max_value()) - } +parameter_types! { + pub storage CoreCount: CoreIndex = 20; } -impl ConvertBack for BalanceToCoretimeBalance { - fn convert_back(n: u64) -> Balance { - Balance::from(n) + +pub struct CoretimeProvider; +impl CoretimeInterface for CoretimeProvider { + type AccountId = AccountId; + type Balance = Balance; + type BlockNumber = BlockNumber; + fn latest() -> Self::BlockNumber { + System::block_number() + } + fn request_core_count(count: CoreIndex) { + CoreCount::set(&count); + } + fn request_revenue_info_at(_when: Self::BlockNumber) {} + fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} + fn assign_core( + _core: CoreIndex, + _begin: Self::BlockNumber, + _assignment: Vec<(CoreAssignment, PartsOf57600)>, + _end_hint: Option, + ) { + } + fn check_notify_core_count() -> Option { + Some(CoreCount::get()) + } + fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { + None } } @@ -1900,8 +1921,8 @@ impl pallet_broker::Config for Runtime { type TimeslicePeriod = ConstU32<2>; type MaxLeasedCores = ConstU32<5>; type MaxReservedCores = ConstU32<5>; - type Coretime = (); - type ConvertBalance = BalanceToCoretimeBalance; + type Coretime = CoretimeProvider; + type ConvertBalance = traits::Identity; type WeightInfo = (); type PalletId = BrokerPalletId; type AdminOrigin = EnsureRoot; diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 6c6783f0ca6d4..a0e6e85429448 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -23,7 +23,10 @@ use crate::{CoreAssignment::Task, Pallet as Broker}; use frame_benchmarking::v2::*; use frame_support::{ storage::bounded_vec::BoundedVec, - traits::{fungible::Mutate, EnsureOrigin, Hooks}, + traits::{ + fungible::{Inspect, Mutate}, + EnsureOrigin, Hooks, + }, }; use frame_system::{Pallet as System, RawOrigin}; use sp_arithmetic::Perbill; @@ -225,7 +228,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); #[extrinsic_call] _(RawOrigin::Signed(caller.clone()), 10u32.into()); @@ -251,7 +257,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 20u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(20u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -277,7 +286,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -307,7 +319,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -336,7 +351,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -369,7 +387,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -401,7 +422,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -434,7 +458,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -470,7 +497,11 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 30u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); + T::Currency::set_balance(&Broker::::account_id(), T::Currency::minimum_balance()); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -499,7 +530,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -527,7 +561,10 @@ mod benches { advance_to::(2); let caller: T::AccountId = whitelisted_caller(); - T::Currency::set_balance(&caller.clone(), 10u32.into()); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(10u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; From 0d281002c63adbf5a7bf86c22675ea5ce10b6e3c Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sun, 23 Jul 2023 13:16:43 +0530 Subject: [PATCH 094/131] Adds todo for process_revenue benchmark --- frame/broker/src/benchmarking.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index a0e6e85429448..74c2b5cc610c1 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -499,7 +499,7 @@ mod benches { let caller: T::AccountId = whitelisted_caller(); T::Currency::set_balance( &caller.clone(), - T::Currency::minimum_balance().saturating_add(10u32.into()), + T::Currency::minimum_balance().saturating_add(30u32.into()), ); T::Currency::set_balance(&Broker::::account_id(), T::Currency::minimum_balance()); @@ -649,6 +649,15 @@ mod benches { Ok(()) } + // Todo: Update Coretime implementation for worst case + #[benchmark] + fn process_revenue() { + #[block] + { + Broker::::process_revenue(); + } + } + #[benchmark] fn rotate_sale(n: Linear<0, { MAX_CORE_COUNT.into() }>) { let core_count = n.try_into().unwrap(); From b44a3b108e716bfc8f627a2358b5ad63d7215f04 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sun, 23 Jul 2023 14:42:14 +0530 Subject: [PATCH 095/131] Minor update --- bin/node/runtime/src/lib.rs | 2 +- frame/broker/src/benchmarking.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 547b46b226af9..a8b746acc20e7 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1910,7 +1910,7 @@ impl CoretimeInterface for CoretimeProvider { Some(CoreCount::get()) } fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { - None + Some((10u32.into(), 0u32.into())) } } diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 74c2b5cc610c1..649bd02fba544 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -649,13 +649,17 @@ mod benches { Ok(()) } - // Todo: Update Coretime implementation for worst case + // Todo: Fix conditions for worst case #[benchmark] fn process_revenue() { #[block] { Broker::::process_revenue(); } + + assert_last_event::( + Event::HistoryDropped { when: 5u32.into(), revenue: 0u32.into() }.into(), + ); } #[benchmark] From 93088729a77ffe91bbe9849ff485999bd2bfcb65 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 14:52:17 +0100 Subject: [PATCH 096/131] Fix for pool revenue history --- frame/broker/src/dispatchable_impls.rs | 6 ++-- frame/broker/src/lib.rs | 2 ++ frame/broker/src/mock.rs | 3 ++ frame/broker/src/tests.rs | 47 ++++++++++++++++++++------ frame/broker/src/tick_impls.rs | 10 +++--- 5 files changed, 50 insertions(+), 18 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 723379db17c3c..271935cceafe9 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -3,7 +3,7 @@ use frame_support::{ pallet_prelude::{DispatchResult, *}, traits::{fungible::Mutate, tokens::Preservation::Expendable, DefensiveResult}, }; -use sp_arithmetic::traits::{Saturating, Zero}; +use sp_arithmetic::traits::{Saturating, Zero, CheckedDiv}; use sp_runtime::traits::Convert; use CompletionStatus::{Complete, Partial}; @@ -319,8 +319,8 @@ impl Pallet { Some(x) => x, None => break, }; - let p = total_payout.saturating_mul(contributed_parts.into()) / - pool_record.private_contributions.into(); + let p = total_payout.saturating_mul(contributed_parts.into()) + .checked_div(&pool_record.private_contributions.into()).unwrap_or_default(); payout.saturating_accrue(p); pool_record.private_contributions.saturating_reduce(contributed_parts); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index dfae6a33e83e4..d46c383116e33 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -27,6 +27,8 @@ mod coretime_interface; mod dispatchable_impls; mod nonfungible_impl; #[cfg(test)] +mod mock; +#[cfg(test)] mod test_fungibles; #[cfg(test)] mod tests; diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index ddeca4941494f..3366678741eb6 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -107,6 +107,9 @@ impl CoretimeInterface for TestCoretimeProvider { NotifyCoreCount::mutate(|s| s.insert(0, count)); } fn request_revenue_info_at(when: Self::BlockNumber) { + if when > Self::latest() { + panic!("Asking for revenue info in the future {:?} {:?}", when, Self::latest()); + } let mut total = 0; CoretimeSpending::mutate(|s| { s.retain(|(n, a)| { diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 06cfab584f84b..6dc3b83d4cd37 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -100,37 +100,62 @@ fn drop_contribution_works() { #[test] fn drop_history_works() { TestExt::new() - .contribution_timeout(3) + .contribution_timeout(4) .endow(1, 1000) - .endow(2, 10) + .endow(2, 30) .execute_with(|| { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let mut region = Broker::do_purchase(1, u64::max_value()).unwrap(); + // Place region in pool. Active in pool timeslices 4, 5, 6 = rcblocks 8, 10, 12; we + // expect to make/receive revenue reports on blocks 10, 12, 14. assert_ok!(Broker::do_pool(region, Some(1), 1, Final)); - assert_ok!(Broker::do_purchase_credit(1, 20, 1)); + assert_ok!(Broker::do_purchase_credit(2, 30, 2)); + advance_to(6); + // In the stable state with no pending payouts, we expect to see 3 items in + // InstaPoolHistory here since there is a latency of 1 timeslice (for generating the + // revenue report), the forward notice period (equivalent to another timeslice) and a + // block between the revenue report being requested and the response being processed. + assert_eq!(InstaPoolHistory::::iter().count(), 3); + advance_to(7); + // One block later, the most recent report will have been processed, so the effective + // queue drops to 2 items. + assert_eq!(InstaPoolHistory::::iter().count(), 2); advance_to(8); + assert_eq!(InstaPoolHistory::::iter().count(), 3); assert_ok!(TestCoretimeProvider::spend_instantaneous(2, 10)); - advance_to(15); + advance_to(10); assert_eq!(InstaPoolHistory::::iter().count(), 3); - assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); + assert_ok!(TestCoretimeProvider::spend_instantaneous(2, 10)); + advance_to(12); + assert_eq!(InstaPoolHistory::::iter().count(), 4); + assert_ok!(TestCoretimeProvider::spend_instantaneous(2, 10)); + advance_to(14); + assert_eq!(InstaPoolHistory::::iter().count(), 5); advance_to(16); - assert_ok!(Broker::do_drop_history(region.begin)); - assert_eq!(InstaPoolHistory::::iter().count(), 2); - assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); + assert_eq!(InstaPoolHistory::::iter().count(), 6); advance_to(17); - region.begin += 1; assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); advance_to(18); + assert_eq!(InstaPoolHistory::::iter().count(), 6); + // Block 18 is 8 blocks ()= 4 timeslices = contribution timeout) after first region. + // Its revenue should now be droppable. assert_ok!(Broker::do_drop_history(region.begin)); - assert_eq!(InstaPoolHistory::::iter().count(), 1); + assert_eq!(InstaPoolHistory::::iter().count(), 5); assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); advance_to(19); region.begin += 1; assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); advance_to(20); assert_ok!(Broker::do_drop_history(region.begin)); - assert_eq!(InstaPoolHistory::::iter().count(), 0); + assert_eq!(InstaPoolHistory::::iter().count(), 4); + assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); + advance_to(21); + region.begin += 1; + assert_noop!(Broker::do_drop_history(region.begin), Error::::StillValid); + advance_to(22); + assert_ok!(Broker::do_drop_history(region.begin)); + assert_eq!(InstaPoolHistory::::iter().count(), 3); assert_noop!(Broker::do_drop_history(region.begin), Error::::NoHistory); }); } diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 6622ea348eb07..99c144651a406 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -1,7 +1,7 @@ use super::*; use frame_support::{pallet_prelude::*, weights::WeightMeter}; use sp_arithmetic::{ - traits::{SaturatedConversion, Saturating, Zero}, + traits::{SaturatedConversion, Saturating, Zero, One}, FixedPointNumber, }; use sp_runtime::traits::ConvertBack; @@ -57,10 +57,11 @@ impl Pallet { let current_timeslice = Self::current_timeslice(); if status.last_timeslice < current_timeslice { - let rc_block = T::TimeslicePeriod::get() * current_timeslice.into(); + // TODO: FIX: this should be the block directly after the end of the timeslice. + status.last_timeslice.saturating_inc(); + let rc_block = T::TimeslicePeriod::get() * status.last_timeslice.into(); T::Coretime::request_revenue_info_at(rc_block); meter.consume(T::WeightInfo::request_revenue_info_at()); - status.last_timeslice.saturating_inc(); } Status::::put(&status); @@ -82,7 +83,8 @@ impl Pallet { Some(x) => x, None => return false, }; - let when: Timeslice = (until / T::TimeslicePeriod::get()).saturated_into(); + // TODO: FIX: this should be the block directly after the end of the timeslice. + let when: Timeslice = (until / T::TimeslicePeriod::get()).saturating_sub(One::one()).saturated_into(); let mut revenue = T::ConvertBalance::convert_back(amount); if revenue.is_zero() { Self::deposit_event(Event::::HistoryDropped { when, revenue }); From bf8e09485e3172ba6cd6e69b905ff45c55f5023c Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 14:53:42 +0100 Subject: [PATCH 097/131] remove TODOs --- frame/broker/src/tick_impls.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 25b2e17fe6504..5d93f78e22af1 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -57,7 +57,6 @@ impl Pallet { let current_timeslice = Self::current_timeslice(); if status.last_timeslice < current_timeslice { - // TODO: FIX: this should be the block directly after the end of the timeslice. status.last_timeslice.saturating_inc(); let rc_block = T::TimeslicePeriod::get() * status.last_timeslice.into(); T::Coretime::request_revenue_info_at(rc_block); @@ -83,7 +82,6 @@ impl Pallet { Some(x) => x, None => return false, }; - // TODO: FIX: this should be the block directly after the end of the timeslice. let when: Timeslice = (until / T::TimeslicePeriod::get()).saturating_sub(One::one()).saturated_into(); let mut revenue = T::ConvertBalance::convert_back(amount); if revenue.is_zero() { From 1ade824fe6957276a76343bf24db6271c3e3a787 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 18:16:43 +0100 Subject: [PATCH 098/131] Fix tests --- frame/broker/src/benchmarking.rs | 2 +- frame/broker/src/dispatchable_impls.rs | 2 +- frame/broker/src/lib.rs | 1 - frame/broker/src/tests.rs | 2 ++ 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 649bd02fba544..6e2bb453bae22 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -658,7 +658,7 @@ mod benches { } assert_last_event::( - Event::HistoryDropped { when: 5u32.into(), revenue: 0u32.into() }.into(), + Event::HistoryDropped { when: 4u32.into(), revenue: 0u32.into() }.into(), ); } diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 271935cceafe9..39bac9dc04628 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -381,7 +381,7 @@ impl Pallet { InstaPoolContribution::::get(®ion_id).ok_or(Error::::UnknownContribution)?; let end = region_id.begin.saturating_add(contrib.length); ensure!( - status.last_timeslice > end.saturating_add(config.contribution_timeout), + status.last_timeslice >= end.saturating_add(config.contribution_timeout), Error::::StillValid ); InstaPoolContribution::::remove(region_id); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 4db2e303dffbe..d46c383116e33 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -25,7 +25,6 @@ mod benchmarking; mod core_mask; mod coretime_interface; mod dispatchable_impls; -mod mock; mod nonfungible_impl; #[cfg(test)] mod mock; diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 6dc3b83d4cd37..893907888f518 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -86,6 +86,8 @@ fn drop_contribution_works() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + // Place region in pool. Active in pool timeslices 4, 5, 6 = rcblocks 8, 10, 12; we + // expect the contribution record to timeout 3 timeslices following 7 = 10 assert_ok!(Broker::do_pool(region, Some(1), 1, Final)); assert_eq!(InstaPoolContribution::::iter().count(), 1); advance_to(19); From c0b60ccbfd452b8e12a591c0d49ba40c385f3508 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 18:26:23 +0100 Subject: [PATCH 099/131] Document CoretimeInterface --- frame/broker/src/coretime_interface.rs | 57 ++++++++++++++++++++++++++ frame/broker/src/dispatchable_impls.rs | 8 ++-- frame/broker/src/lib.rs | 2 +- frame/broker/src/tick_impls.rs | 5 ++- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 009c8b42107d1..3ba181bd806e5 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -27,9 +27,18 @@ pub enum CoreAssignment { Task(TaskId), } +/// Type able to accept Coretime scheduling instructions and provide certain usage information. +/// Generally implemented by the Relay-chain or some means of communicating with it. +/// +/// The trait representation of RFC#5 https://github.com/polkadot-fellows/RFCs/pull/5. pub trait CoretimeInterface { + /// A (Relay-chain-side) account ID. type AccountId: Parameter; + + /// A (Relay-chain-side) balance. type Balance; + + /// A (Relay-chain-side) block number. type BlockNumber: AtLeast32BitUnsigned + Copy + TypeInfo @@ -37,19 +46,67 @@ pub trait CoretimeInterface { + Decode + MaxEncodedLen + Debug; + + /// Return the latest block number on the Relay-chain. fn latest() -> Self::BlockNumber; + + /// Requests the Relay-chain to alter the number of schedulable cores to `count`. Under normal + /// operation, the Relay-chain SHOULD send a `notify_core_count(count)` message back. fn request_core_count(count: CoreIndex); + + /// Requests that the Relay-chain send a `notify_revenue` message back at or soon after + /// Relay-chain block number `when` whose `until` parameter is equal to `when`. + /// + /// `when` may never be greater than the result of `Self::latest()`. + /// The period in to the past which `when` is allowed to be may be limited; if so the limit + /// should be understood on a channel outside of this proposal. In the case that the request + /// cannot be serviced because `when` is too old a block then a `notify_revenue` message must + /// still be returned, but its `revenue` field may be `None`. fn request_revenue_info_at(when: Self::BlockNumber); + + /// Instructs the Relay-chain to add the `amount` of DOT to the Instantaneous Coretime Market + /// Credit account of `who`. + /// + /// It is expected that Instantaneous Coretime Market Credit on the Relay-chain is NOT + /// transferrable and only redeemable when used to assign cores in the Instantaneous Coretime + /// Pool. fn credit_account(who: Self::AccountId, amount: Self::Balance); + + /// Instructs the Relay-chain to ensure that the core indexed as `core` is utilised for a number + /// of assignments in specific ratios given by `assignment` starting as soon after `begin` as + /// possible. Core assignments take the form of a `CoreAssignment` value which can either task + /// the core to a `ParaId` value or indicate that the core should be used in the Instantaneous + /// Pool. Each assignment comes with a ratio value, represented as the numerator of the fraction + /// with a denominator of 57,600. + /// + /// If `end_hint` is `Some` and the inner is greater than the current block number, then the + /// Relay-chain should optimize in the expectation of receiving a new `assign_core(core, ...)` + /// message at or prior to the block number of the inner value. Specific functionality should + /// remain unchanged regardless of the `end_hint` value. fn assign_core( core: CoreIndex, begin: Self::BlockNumber, assignment: Vec<(CoreAssignment, PartsOf57600)>, end_hint: Option, ); + + /// Indicate that from this block onwards, the range of acceptable values of the `core` + /// parameter of `assign_core` message is `[0, count)`. `assign_core` will be a no-op if + /// provided with a value for `core` outside of this range. fn check_notify_core_count() -> Option; + + /// Provide the amount of revenue accumulated from Instantaneous Coretime Sales from Relay-chain + /// block number `last_until` to `until`, not including `until` itself. `last_until` is defined + /// as being the `until` argument of the last `notify_revenue` message sent, or zero for the + /// first call. If `revenue` is `None`, this indicates that the information is no longer + /// available. + /// + /// This explicitly disregards the possibility of multiple parachains requesting and being + /// notified of revenue information. The Relay-chain must be configured to ensure that only a + /// single revenue information destination exists. fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)>; } + impl CoretimeInterface for () { type AccountId = (); type Balance = u64; diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 39bac9dc04628..9e6364a55abd8 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -3,7 +3,7 @@ use frame_support::{ pallet_prelude::{DispatchResult, *}, traits::{fungible::Mutate, tokens::Preservation::Expendable, DefensiveResult}, }; -use sp_arithmetic::traits::{Saturating, Zero, CheckedDiv}; +use sp_arithmetic::traits::{CheckedDiv, Saturating, Zero}; use sp_runtime::traits::Convert; use CompletionStatus::{Complete, Partial}; @@ -319,8 +319,10 @@ impl Pallet { Some(x) => x, None => break, }; - let p = total_payout.saturating_mul(contributed_parts.into()) - .checked_div(&pool_record.private_contributions.into()).unwrap_or_default(); + let p = total_payout + .saturating_mul(contributed_parts.into()) + .checked_div(&pool_record.private_contributions.into()) + .unwrap_or_default(); payout.saturating_accrue(p); pool_record.private_contributions.saturating_reduce(contributed_parts); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index d46c383116e33..2ea2f4afb27f1 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -25,9 +25,9 @@ mod benchmarking; mod core_mask; mod coretime_interface; mod dispatchable_impls; -mod nonfungible_impl; #[cfg(test)] mod mock; +mod nonfungible_impl; #[cfg(test)] mod test_fungibles; #[cfg(test)] diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 5d93f78e22af1..76c2afc56294e 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -1,7 +1,7 @@ use super::*; use frame_support::{pallet_prelude::*, weights::WeightMeter}; use sp_arithmetic::{ - traits::{SaturatedConversion, Saturating, Zero, One}, + traits::{One, SaturatedConversion, Saturating, Zero}, FixedPointNumber, }; use sp_runtime::traits::ConvertBack; @@ -82,7 +82,8 @@ impl Pallet { Some(x) => x, None => return false, }; - let when: Timeslice = (until / T::TimeslicePeriod::get()).saturating_sub(One::one()).saturated_into(); + let when: Timeslice = + (until / T::TimeslicePeriod::get()).saturating_sub(One::one()).saturated_into(); let mut revenue = T::ConvertBalance::convert_back(amount); if revenue.is_zero() { Self::deposit_event(Event::::HistoryDropped { when, revenue }); From 3eb4a9b2352707209a7f27e57a03a9ba5012fa2d Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 18:33:28 +0100 Subject: [PATCH 100/131] rename part to mask --- frame/broker/src/benchmarking.rs | 26 +++++++++++++------------- frame/broker/src/dispatchable_impls.rs | 20 ++++++++++---------- frame/broker/src/nonfungible_impl.rs | 2 +- frame/broker/src/tests.rs | 12 ++++++------ frame/broker/src/tick_impls.rs | 14 +++++++------- frame/broker/src/types.rs | 10 +++++----- frame/broker/src/utility_impls.rs | 4 ++-- 7 files changed, 44 insertions(+), 44 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 6e2bb453bae22..1625c8a8c6f43 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -59,7 +59,7 @@ fn new_schedule() -> Schedule { for i in 0..CORE_MASK_BITS { items.push(ScheduleItem { assignment: Task(i.try_into().unwrap()), - part: CoreMask::complete(), + mask: CoreMask::complete(), }); } Schedule::truncate_from(items) @@ -240,7 +240,7 @@ mod benches { assert_last_event::( Event::Purchased { who: caller, - region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, price: 10u32.into(), duration: 3u32.into(), } @@ -332,10 +332,10 @@ mod benches { assert_last_event::( Event::Partitioned { - old_region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + old_region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, new_region_ids: ( - RegionId { begin: 4, core, part: CoreMask::complete() }, - RegionId { begin: 6, core, part: CoreMask::complete() }, + RegionId { begin: 4, core, mask: CoreMask::complete() }, + RegionId { begin: 6, core, mask: CoreMask::complete() }, ), } .into(), @@ -364,13 +364,13 @@ mod benches { assert_last_event::( Event::Interlaced { - old_region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + old_region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, new_region_ids: ( - RegionId { begin: 4, core, part: 0x00000_fffff_fffff_00000.into() }, + RegionId { begin: 4, core, mask: 0x00000_fffff_fffff_00000.into() }, RegionId { begin: 4, core, - part: CoreMask::complete() ^ 0x00000_fffff_fffff_00000.into(), + mask: CoreMask::complete() ^ 0x00000_fffff_fffff_00000.into(), }, ), } @@ -405,7 +405,7 @@ mod benches { assert_last_event::( Event::Assigned { - region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, task: 1000, duration: 3u32.into(), } @@ -440,7 +440,7 @@ mod benches { assert_last_event::( Event::Pooled { - region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, duration: 3u32.into(), } .into(), @@ -479,7 +479,7 @@ mod benches { who: recipient, amount: 0u32.into(), // Todo: fix the conditions for this benchmark next: if m < new_config_record::().region_length { - Some(RegionId { begin: 4.saturating_add(m), core, part: CoreMask::complete() }) + Some(RegionId { begin: 4.saturating_add(m), core, mask: CoreMask::complete() }) } else { None }, @@ -545,7 +545,7 @@ mod benches { assert_last_event::( Event::RegionDropped { - region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, duration: 3u32.into(), } .into(), @@ -581,7 +581,7 @@ mod benches { assert_last_event::( Event::ContributionDropped { - region_id: RegionId { begin: 4, core, part: CoreMask::complete() }, + region_id: RegionId { begin: 4, core, mask: CoreMask::complete() }, } .into(), ); diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 9e6364a55abd8..9a935c486aefa 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -203,13 +203,13 @@ impl Pallet { ensure!(check_owner == region.owner, Error::::NotOwner); } - ensure!((pivot & !region_id.part).is_void(), Error::::ExteriorPivot); + ensure!((pivot & !region_id.mask).is_void(), Error::::ExteriorPivot); ensure!(!pivot.is_void(), Error::::VoidPivot); - ensure!(pivot != region_id.part, Error::::CompletePivot); + ensure!(pivot != region_id.mask, Error::::CompletePivot); - let one = RegionId { part: pivot, ..region_id }; + let one = RegionId { mask: pivot, ..region_id }; Regions::::insert(&one, ®ion); - let other = RegionId { part: region_id.part ^ pivot, ..region_id }; + let other = RegionId { mask: region_id.mask ^ pivot, ..region_id }; Regions::::insert(&other, ®ion); let new_region_ids = (one, other); @@ -228,10 +228,10 @@ impl Pallet { let workplan_key = (region_id.begin, region_id.core); let mut workplan = Workplan::::get(&workplan_key).unwrap_or_default(); // Ensure no previous allocations exist. - workplan.retain(|i| (i.part & region_id.part).is_void()); + workplan.retain(|i| (i.mask & region_id.mask).is_void()); if workplan .try_push(ScheduleItem { - part: region_id.part, + mask: region_id.mask, assignment: CoreAssignment::Task(target), }) .is_ok() @@ -248,7 +248,7 @@ impl Pallet { if price == p => w, _ => CoreMask::void(), - } | region_id.part; + } | region_id.mask; let workload = if assigned.is_complete() { Complete(workplan) } else { Partial(assigned) }; let record = AllowedRenewalRecord { price, completion: workload }; @@ -279,11 +279,11 @@ impl Pallet { let mut workplan = Workplan::::get(&workplan_key).unwrap_or_default(); let duration = region.end.saturating_sub(region_id.begin); if workplan - .try_push(ScheduleItem { part: region_id.part, assignment: CoreAssignment::Pool }) + .try_push(ScheduleItem { mask: region_id.mask, assignment: CoreAssignment::Pool }) .is_ok() { Workplan::::insert(&workplan_key, &workplan); - let size = region_id.part.count_ones() as i32; + let size = region_id.mask.count_ones() as i32; InstaPoolIo::::mutate(region_id.begin, |a| a.private.saturating_accrue(size)); InstaPoolIo::::mutate(region.end, |a| a.private.saturating_reduce(size)); let record = ContributionRecord { length: duration, payee }; @@ -301,7 +301,7 @@ impl Pallet { ) -> DispatchResult { let mut contribution = InstaPoolContribution::::take(region).ok_or(Error::::UnknownContribution)?; - let contributed_parts = region.part.count_ones(); + let contributed_parts = region.mask.count_ones(); Self::deposit_event(Event::RevenueClaimBegun { region, max_timeslices }); diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index ed96ce38c0837..4a6d404e39986 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -20,7 +20,7 @@ impl Inspect for Pallet { b"end" => Some(item.end.encode()), b"length" => Some(item.end.saturating_sub(id.begin).encode()), b"core" => Some(id.core.encode()), - b"part" => Some(id.part.encode()), + b"part" => Some(id.mask.encode()), b"owner" => Some(item.owner.encode()), b"paid" => Some(item.paid.encode()), _ => None, diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 893907888f518..28e8caae0d6db 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -332,7 +332,7 @@ fn renewal_works() { #[test] fn instapool_payouts_work() { TestExt::new().endow(1, 1000).execute_with(|| { - let item = ScheduleItem { assignment: Pool, part: CoreMask::complete() }; + let item = ScheduleItem { assignment: Pool, mask: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100, 3)); advance_to(2); @@ -353,7 +353,7 @@ fn instapool_payouts_work() { #[test] fn instapool_partial_core_payouts_work() { TestExt::new().endow(1, 1000).execute_with(|| { - let item = ScheduleItem { assignment: Pool, part: CoreMask::complete() }; + let item = ScheduleItem { assignment: Pool, mask: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); assert_ok!(Broker::do_start_sales(100, 2)); advance_to(2); @@ -378,12 +378,12 @@ fn instapool_partial_core_payouts_work() { #[test] fn initialize_with_system_paras_works() { TestExt::new().execute_with(|| { - let item = ScheduleItem { assignment: Task(1u32), part: CoreMask::complete() }; + let item = ScheduleItem { assignment: Task(1u32), mask: CoreMask::complete() }; assert_ok!(Broker::do_reserve(Schedule::truncate_from(vec![item]))); let items = vec![ - ScheduleItem { assignment: Task(2u32), part: 0xfffff_fffff_00000_00000.into() }, - ScheduleItem { assignment: Task(3u32), part: 0x00000_00000_fffff_00000.into() }, - ScheduleItem { assignment: Task(4u32), part: 0x00000_00000_00000_fffff.into() }, + ScheduleItem { assignment: Task(2u32), mask: 0xfffff_fffff_00000_00000.into() }, + ScheduleItem { assignment: Task(3u32), mask: 0x00000_00000_fffff_00000.into() }, + ScheduleItem { assignment: Task(4u32), mask: 0x00000_00000_00000_fffff.into() }, ]; assert_ok!(Broker::do_reserve(Schedule::truncate_from(items))); assert_ok!(Broker::do_start_sales(100, 2)); diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 76c2afc56294e..bea2edc6f6cfd 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -128,7 +128,7 @@ impl Pallet { let now = frame_system::Pallet::::block_number(); let pool_item = - ScheduleItem { assignment: CoreAssignment::Pool, part: CoreMask::complete() }; + ScheduleItem { assignment: CoreAssignment::Pool, mask: CoreMask::complete() }; let just_pool = Schedule::truncate_from(vec![pool_item]); // Clean up the old sale - we need to use up any unused cores by putting them into the @@ -178,7 +178,7 @@ impl Pallet { let parts: u32 = schedule .iter() .filter(|i| matches!(i.assignment, CoreAssignment::Pool)) - .map(|i| i.part.count_ones()) + .map(|i| i.mask.count_ones()) .sum(); total_pooled.saturating_accrue(parts as i32); @@ -191,9 +191,9 @@ impl Pallet { let mut leases = Leases::::get(); // Can morph to a renewable as long as it's >=begin and ::insert((region_begin, first_core), &schedule); let expiring = until >= region_begin && until < region_end; if expiring { @@ -278,16 +278,16 @@ impl Pallet { None => return, }; let workload = Workload::::get(core); - let parts_used = workplan.iter().map(|i| i.part).fold(CoreMask::void(), |a, i| a | i); + let parts_used = workplan.iter().map(|i| i.mask).fold(CoreMask::void(), |a, i| a | i); let mut workplan = workplan.into_inner(); - workplan.extend(workload.into_iter().filter(|i| (i.part & parts_used).is_void())); + workplan.extend(workload.into_iter().filter(|i| (i.mask & parts_used).is_void())); let workplan = Schedule::truncate_from(workplan); Workload::::insert(core, &workplan); let mut total_used = 0; let mut intermediate = workplan .into_iter() - .map(|i| (i.assignment, i.part.count_ones() as u16 * (57_600 / 80))) + .map(|i| (i.assignment, i.mask.count_ones() as u16 * (57_600 / 80))) .inspect(|i| total_used.saturating_accrue(i.1)) .collect::>(); if total_used < 80 { diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 7e9e3dea4513e..7405b860cc911 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -40,21 +40,21 @@ pub struct RegionId { /// The index of the Polakdot Core on which this Region will be scheduled. pub core: CoreIndex, /// The regularity parts in which this Region will be scheduled. - pub part: CoreMask, + pub mask: CoreMask, } impl From for RegionId { fn from(x: u128) -> Self { - Self { begin: (x >> 96) as u32, core: (x >> 80) as u16, part: x.into() } + Self { begin: (x >> 96) as u32, core: (x >> 80) as u16, mask: x.into() } } } impl From for u128 { fn from(x: RegionId) -> Self { - (x.begin as u128) << 96 | (x.core as u128) << 80 | u128::from(x.part) + (x.begin as u128) << 96 | (x.core as u128) << 80 | u128::from(x.mask) } } #[test] fn region_id_converts_u128() { - let r = RegionId { begin: 0x12345678u32, core: 0xabcdu16, part: 0xdeadbeefcafef00d0123.into() }; + let r = RegionId { begin: 0x12345678u32, core: 0xabcdu16, mask: 0xdeadbeefcafef00d0123.into() }; let u = 0x12345678_abcd_deadbeefcafef00d0123u128; assert_eq!(RegionId::from(u), r); assert_eq!(u128::from(r), u); @@ -76,7 +76,7 @@ pub type RegionRecordOf = RegionRecord<::AccountId, BalanceOf Pallet { owner: T::AccountId, paid: Option>, ) -> RegionId { - let id = RegionId { begin, core, part: CoreMask::complete() }; + let id = RegionId { begin, core, mask: CoreMask::complete() }; let record = RegionRecord { end, owner, paid }; Regions::::insert(&id, &record); id @@ -92,7 +92,7 @@ impl Pallet { } } else { Workplan::::mutate_extant((region_id.begin, region_id.core), |p| { - p.retain(|i| (i.part & region_id.part).is_void()) + p.retain(|i| (i.mask & region_id.mask).is_void()) }); } if finality == Finality::Provisional { From 82c9ebec319f572f18ecbc305ca9da96ea275829 Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 18:37:19 +0100 Subject: [PATCH 101/131] Fixes --- frame/broker/src/tick_impls.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index bea2edc6f6cfd..364107a30f15b 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -290,8 +290,8 @@ impl Pallet { .map(|i| (i.assignment, i.mask.count_ones() as u16 * (57_600 / 80))) .inspect(|i| total_used.saturating_accrue(i.1)) .collect::>(); - if total_used < 80 { - intermediate.push((CoreAssignment::Idle, 80 - total_used)); + if total_used < 57_600 { + intermediate.push((CoreAssignment::Idle, 57_600 - total_used)); } intermediate.sort(); let mut assignment: Vec<(CoreAssignment, PartsOf57600)> = From 856fbad8ef6a6e46ebd03a00d7ce7b9ff714ffad Mon Sep 17 00:00:00 2001 From: Gav Date: Tue, 25 Jul 2023 18:42:32 +0100 Subject: [PATCH 102/131] Grumble --- frame/broker/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 2ea2f4afb27f1..e89bf3c417ce5 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -466,6 +466,8 @@ pub mod pallet { UnknownReservation, /// The renewal record cannot be found. UnknownRenewal, + /// The lease expiry time has already passed. + AlreadyExpired, } #[pallet::hooks] From 7b7cb98c5e95921cadf83ba360f02528db383b5f Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Tue, 25 Jul 2023 18:22:36 +0000 Subject: [PATCH 103/131] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_broker --- frame/broker/src/weights.rs | 778 +++++++++++++++++++++++++++++++++--- 1 file changed, 717 insertions(+), 61 deletions(-) diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index 5ef20d65000e0..944fc9b1e8604 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -15,22 +15,45 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Autogenerated weights for `pallet-broker`. +//! Autogenerated weights for `pallet_broker` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-07-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `runner-ynta1nyy-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// target/production/substrate-node +// benchmark +// pallet +// --steps=50 +// --repeat=20 +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --json-file=/builds/parity/mirrors/substrate/.git/.artifacts/bench.json +// --pallet=pallet_broker +// --chain=dev +// --header=./HEADER-APACHE2 +// --output=./frame/broker/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] +#![allow(missing_docs)] use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use core::marker::PhantomData; -/// Weight functions needed for `pallet-broker`. +/// Weight functions needed for `pallet_broker`. pub trait WeightInfo { fn configure() -> Weight; fn reserve() -> Weight; - fn unreserve() -> Weight; + fn unreserve(n: u32, ) -> Weight; fn set_lease() -> Weight; - fn start_sales() -> Weight; + fn start_sales(n: u32, ) -> Weight; fn purchase() -> Weight; fn renew() -> Weight; fn transfer() -> Weight; @@ -38,76 +61,709 @@ pub trait WeightInfo { fn interlace() -> Weight; fn assign() -> Weight; fn pool() -> Weight; - fn claim_revenue(m: u32,) -> Weight; + fn claim_revenue(m: u32, ) -> Weight; fn purchase_credit() -> Weight; fn drop_region() -> Weight; fn drop_contribution() -> Weight; - fn drop_history() -> Weight; fn drop_renewal() -> Weight; - fn request_core_count() -> Weight; - fn process_core_count() -> Weight; + fn request_core_count(n: u32, ) -> Weight; + fn process_core_count(n: u32, ) -> Weight; fn process_revenue() -> Weight; - fn rotate_sale() -> Weight; + fn rotate_sale(n: u32, ) -> Weight; fn process_pool() -> Weight; fn process_core_schedule() -> Weight; fn request_revenue_info_at() -> Weight; } -/// Weights for `pallet-broker` using the Substrate node and recommended hardware. +/// Weights for `pallet_broker` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - fn configure() -> Weight { Weight::from_parts(123, 456) } - fn reserve() -> Weight { Weight::from_parts(123, 456) } - fn unreserve() -> Weight { Weight::from_parts(123, 456) } - fn set_lease() -> Weight { Weight::from_parts(123, 456) } - fn start_sales() -> Weight { Weight::from_parts(123, 456) } - fn purchase() -> Weight { Weight::from_parts(123, 456) } - fn renew() -> Weight { Weight::from_parts(123, 456) } - fn transfer() -> Weight { Weight::from_parts(123, 456) } - fn partition() -> Weight { Weight::from_parts(123, 456) } - fn interlace() -> Weight { Weight::from_parts(123, 456) } - fn assign() -> Weight { Weight::from_parts(123, 456) } - fn pool() -> Weight { Weight::from_parts(123, 456) } - fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } - fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } - fn drop_region() -> Weight { Weight::from_parts(123, 456) } - fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } - fn drop_history() -> Weight { Weight::from_parts(123, 456) } - fn drop_renewal() -> Weight { Weight::from_parts(123, 456) } - fn request_core_count() -> Weight { Weight::from_parts(123, 456) } - fn process_core_count() -> Weight { Weight::from_parts(123, 456) } - fn process_revenue() -> Weight { Weight::from_parts(123, 456) } - fn rotate_sale() -> Weight { Weight::from_parts(123, 456) } - fn process_pool() -> Weight { Weight::from_parts(123, 456) } - fn process_core_schedule() -> Weight { Weight::from_parts(123, 456) } - fn request_revenue_info_at() -> Weight { Weight::from_parts(123, 456) } + /// Storage: `Broker::Configuration` (r:0 w:1) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + fn configure() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_157_000 picoseconds. + Weight::from_parts(3_478_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Reservations` (r:1 w:1) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `5016` + // Estimated: `7496` + // Minimum execution time: 22_427_000 picoseconds. + Weight::from_parts(23_442_000, 7496) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Reservations` (r:1 w:1) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 4]`. + fn unreserve(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6218` + // Estimated: `7496` + // Minimum execution time: 20_863_000 picoseconds. + Weight::from_parts(22_435_696, 7496) + // Standard Error: 11_196 + .saturating_add(Weight::from_parts(344, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Leases` (r:1 w:1) + /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) + fn set_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `1526` + // Minimum execution time: 12_827_000 picoseconds. + Weight::from_parts(13_470_000, 1526) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, 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::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::Status` (r:0 w:1) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, 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 start_sales(_n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6330` + // Estimated: `8499` + // Minimum execution time: 64_179_000 picoseconds. + Weight::from_parts(67_646_772, 8499) + .saturating_add(T::DbWeight::get().reads(6_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`) + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, 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::Regions` (r:0 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn purchase() -> Weight { + // Proof Size summary in bytes: + // Measured: `568` + // Estimated: `2053` + // Minimum execution time: 49_065_000 picoseconds. + Weight::from_parts(50_220_000, 2053) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// 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: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::AllowedRenewals` (r:1 w:2) + /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, 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::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `686` + // Estimated: `4698` + // Minimum execution time: 75_326_000 picoseconds. + Weight::from_parts(76_193_000, 4698) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 17_564_000 picoseconds. + Weight::from_parts(18_212_000, 3550) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:2) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn partition() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 19_548_000 picoseconds. + Weight::from_parts(20_585_000, 3550) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:2) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn interlace() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 19_603_000 picoseconds. + Weight::from_parts(20_075_000, 3550) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// 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: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn assign() -> Weight { + // Proof Size summary in bytes: + // Measured: `740` + // Estimated: `4681` + // Minimum execution time: 32_255_000 picoseconds. + Weight::from_parts(33_243_000, 4681) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolIo` (r:2 w:2) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolContribution` (r:0 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + fn pool() -> Weight { + // Proof Size summary in bytes: + // Measured: `775` + // Estimated: `5996` + // Minimum execution time: 37_211_000 picoseconds. + Weight::from_parts(38_985_000, 5996) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Broker::InstaPoolContribution` (r:1 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolHistory` (r:3 w:0) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `m` is `[0, 3]`. + fn claim_revenue(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `478 + m * (45 ±0)` + // Estimated: `6196 + m * (2520 ±0)` + // Minimum execution time: 43_370_000 picoseconds. + Weight::from_parts(46_106_878, 6196) + // Standard Error: 76_802 + .saturating_add(Weight::from_parts(3_803_718, 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(2_u64)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(m.into())) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn purchase_credit() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 44_947_000 picoseconds. + Weight::from_parts(45_909_000, 3593) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn drop_region() -> Weight { + // Proof Size summary in bytes: + // Measured: `603` + // Estimated: `3550` + // Minimum execution time: 31_169_000 picoseconds. + Weight::from_parts(32_139_000, 3550) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// 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: `Broker::InstaPoolContribution` (r:1 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + fn drop_contribution() -> Weight { + // Proof Size summary in bytes: + // Measured: `601` + // Estimated: `3533` + // Minimum execution time: 34_722_000 picoseconds. + Weight::from_parts(36_341_000, 3533) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::AllowedRenewals` (r:1 w:1) + /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + fn drop_renewal() -> Weight { + // Proof Size summary in bytes: + // Measured: `525` + // Estimated: `4698` + // Minimum execution time: 26_324_000 picoseconds. + Weight::from_parts(27_763_000, 4698) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) + /// The range of component `n` is `[0, 1000]`. + fn request_core_count(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_928_000 picoseconds. + Weight::from_parts(7_661_845, 0) + // Standard Error: 23 + .saturating_add(Weight::from_parts(37, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) + /// The range of component `n` is `[0, 1000]`. + fn process_core_count(_n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `97` + // Estimated: `3562` + // Minimum execution time: 7_279_000 picoseconds. + Weight::from_parts(7_867_446, 3562) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + fn process_revenue() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_005_000 picoseconds. + Weight::from_parts(6_416_000, 0) + .saturating_add(T::DbWeight::get().writes(1_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: 47_284_000 picoseconds. + Weight::from_parts(49_700_704, 8499) + // Standard Error: 121 + .saturating_add(Weight::from_parts(35, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(15_u64)) + } + /// Storage: `Broker::InstaPoolIo` (r:1 w:0) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + fn process_pool() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3493` + // Minimum execution time: 9_651_000 picoseconds. + Weight::from_parts(10_076_000, 3493) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workload` (r:1 w:1) + /// Proof: `Broker::Workload` (`max_values`: None, `max_size`: Some(1212), added: 3687, mode: `MaxEncodedLen`) + fn process_core_schedule() -> Weight { + // Proof Size summary in bytes: + // Measured: `1423` + // Estimated: `4681` + // Minimum execution time: 20_975_000 picoseconds. + Weight::from_parts(21_846_000, 4681) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } + fn request_revenue_info_at() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 170_000 picoseconds. + Weight::from_parts(208_000, 0) + } } -// For backwards compatibility and tests +// For backwards compatibility and tests. impl WeightInfo for () { - fn configure() -> Weight { Weight::from_parts(123, 456) } - fn reserve() -> Weight { Weight::from_parts(123, 456) } - fn unreserve() -> Weight { Weight::from_parts(123, 456) } - fn set_lease() -> Weight { Weight::from_parts(123, 456) } - fn start_sales() -> Weight { Weight::from_parts(123, 456) } - fn purchase() -> Weight { Weight::from_parts(123, 456) } - fn renew() -> Weight { Weight::from_parts(123, 456) } - fn transfer() -> Weight { Weight::from_parts(123, 456) } - fn partition() -> Weight { Weight::from_parts(123, 456) } - fn interlace() -> Weight { Weight::from_parts(123, 456) } - fn assign() -> Weight { Weight::from_parts(123, 456) } - fn pool() -> Weight { Weight::from_parts(123, 456) } - fn claim_revenue(_: u32,) -> Weight { Weight::from_parts(123, 456) } - fn purchase_credit() -> Weight { Weight::from_parts(123, 456) } - fn drop_region() -> Weight { Weight::from_parts(123, 456) } - fn drop_contribution() -> Weight { Weight::from_parts(123, 456) } - fn drop_history() -> Weight { Weight::from_parts(123, 456) } - fn drop_renewal() -> Weight { Weight::from_parts(123, 456) } - fn request_core_count() -> Weight { Weight::from_parts(123, 456) } - fn process_core_count() -> Weight { Weight::from_parts(123, 456) } - fn process_revenue() -> Weight { Weight::from_parts(123, 456) } - fn rotate_sale() -> Weight { Weight::from_parts(123, 456) } - fn process_pool() -> Weight { Weight::from_parts(123, 456) } - fn process_core_schedule() -> Weight { Weight::from_parts(123, 456) } - fn request_revenue_info_at() -> Weight { Weight::from_parts(123, 456) } + /// Storage: `Broker::Configuration` (r:0 w:1) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`) + fn configure() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_157_000 picoseconds. + Weight::from_parts(3_478_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Reservations` (r:1 w:1) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + fn reserve() -> Weight { + // Proof Size summary in bytes: + // Measured: `5016` + // Estimated: `7496` + // Minimum execution time: 22_427_000 picoseconds. + Weight::from_parts(23_442_000, 7496) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Reservations` (r:1 w:1) + /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 4]`. + fn unreserve(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6218` + // Estimated: `7496` + // Minimum execution time: 20_863_000 picoseconds. + Weight::from_parts(22_435_696, 7496) + // Standard Error: 11_196 + .saturating_add(Weight::from_parts(344, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Leases` (r:1 w:1) + /// Proof: `Broker::Leases` (`max_values`: Some(1), `max_size`: Some(41), added: 536, mode: `MaxEncodedLen`) + fn set_lease() -> Weight { + // Proof Size summary in bytes: + // Measured: `239` + // Estimated: `1526` + // Minimum execution time: 12_827_000 picoseconds. + Weight::from_parts(13_470_000, 1526) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Configuration` (r:1 w:0) + /// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, 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::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::Status` (r:0 w:1) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, 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 start_sales(_n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `6330` + // Estimated: `8499` + // Minimum execution time: 64_179_000 picoseconds. + Weight::from_parts(67_646_772, 8499) + .saturating_add(RocksDbWeight::get().reads(6_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`) + /// Storage: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, 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::Regions` (r:0 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn purchase() -> Weight { + // Proof Size summary in bytes: + // Measured: `568` + // Estimated: `2053` + // Minimum execution time: 49_065_000 picoseconds. + Weight::from_parts(50_220_000, 2053) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// 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: `Broker::SaleInfo` (r:1 w:1) + /// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`) + /// Storage: `Broker::AllowedRenewals` (r:1 w:2) + /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, 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::Workplan` (r:0 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn renew() -> Weight { + // Proof Size summary in bytes: + // Measured: `686` + // Estimated: `4698` + // Minimum execution time: 75_326_000 picoseconds. + Weight::from_parts(76_193_000, 4698) + .saturating_add(RocksDbWeight::get().reads(6_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 17_564_000 picoseconds. + Weight::from_parts(18_212_000, 3550) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:2) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn partition() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 19_548_000 picoseconds. + Weight::from_parts(20_585_000, 3550) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Broker::Regions` (r:1 w:2) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn interlace() -> Weight { + // Proof Size summary in bytes: + // Measured: `495` + // Estimated: `3550` + // Minimum execution time: 19_603_000 picoseconds. + Weight::from_parts(20_075_000, 3550) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// 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: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + fn assign() -> Weight { + // Proof Size summary in bytes: + // Measured: `740` + // Estimated: `4681` + // Minimum execution time: 32_255_000 picoseconds. + Weight::from_parts(33_243_000, 4681) + .saturating_add(RocksDbWeight::get().reads(4_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolIo` (r:2 w:2) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolContribution` (r:0 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + fn pool() -> Weight { + // Proof Size summary in bytes: + // Measured: `775` + // Estimated: `5996` + // Minimum execution time: 37_211_000 picoseconds. + Weight::from_parts(38_985_000, 5996) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(5_u64)) + } + /// Storage: `Broker::InstaPoolContribution` (r:1 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolHistory` (r:3 w:0) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `m` is `[0, 3]`. + fn claim_revenue(m: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `478 + m * (45 ±0)` + // Estimated: `6196 + m * (2520 ±0)` + // Minimum execution time: 43_370_000 picoseconds. + Weight::from_parts(46_106_878, 6196) + // Standard Error: 76_802 + .saturating_add(Weight::from_parts(3_803_718, 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(2_u64)) + .saturating_add(Weight::from_parts(0, 2520).saturating_mul(m.into())) + } + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn purchase_credit() -> Weight { + // Proof Size summary in bytes: + // Measured: `103` + // Estimated: `3593` + // Minimum execution time: 44_947_000 picoseconds. + Weight::from_parts(45_909_000, 3593) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::Regions` (r:1 w:1) + /// Proof: `Broker::Regions` (`max_values`: None, `max_size`: Some(85), added: 2560, mode: `MaxEncodedLen`) + fn drop_region() -> Weight { + // Proof Size summary in bytes: + // Measured: `603` + // Estimated: `3550` + // Minimum execution time: 31_169_000 picoseconds. + Weight::from_parts(32_139_000, 3550) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// 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: `Broker::InstaPoolContribution` (r:1 w:1) + /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) + fn drop_contribution() -> Weight { + // Proof Size summary in bytes: + // Measured: `601` + // Estimated: `3533` + // Minimum execution time: 34_722_000 picoseconds. + Weight::from_parts(36_341_000, 3533) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Status` (r:1 w:0) + /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) + /// Storage: `Broker::AllowedRenewals` (r:1 w:1) + /// Proof: `Broker::AllowedRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`) + fn drop_renewal() -> Weight { + // Proof Size summary in bytes: + // Measured: `525` + // Estimated: `4698` + // Minimum execution time: 26_324_000 picoseconds. + Weight::from_parts(27_763_000, 4698) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) + /// The range of component `n` is `[0, 1000]`. + fn request_core_count(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_928_000 picoseconds. + Weight::from_parts(7_661_845, 0) + // Standard Error: 23 + .saturating_add(Weight::from_parts(37, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) + /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) + /// The range of component `n` is `[0, 1000]`. + fn process_core_count(_n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `97` + // Estimated: `3562` + // Minimum execution time: 7_279_000 picoseconds. + Weight::from_parts(7_867_446, 3562) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + fn process_revenue() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 6_005_000 picoseconds. + Weight::from_parts(6_416_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_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: 47_284_000 picoseconds. + Weight::from_parts(49_700_704, 8499) + // Standard Error: 121 + .saturating_add(Weight::from_parts(35, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(15_u64)) + } + /// Storage: `Broker::InstaPoolIo` (r:1 w:0) + /// Proof: `Broker::InstaPoolIo` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) + /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) + /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) + fn process_pool() -> Weight { + // Proof Size summary in bytes: + // Measured: `180` + // Estimated: `3493` + // Minimum execution time: 9_651_000 picoseconds. + Weight::from_parts(10_076_000, 3493) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: `Broker::Workplan` (r:1 w:1) + /// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`) + /// Storage: `Broker::Workload` (r:1 w:1) + /// Proof: `Broker::Workload` (`max_values`: None, `max_size`: Some(1212), added: 3687, mode: `MaxEncodedLen`) + fn process_core_schedule() -> Weight { + // Proof Size summary in bytes: + // Measured: `1423` + // Estimated: `4681` + // Minimum execution time: 20_975_000 picoseconds. + Weight::from_parts(21_846_000, 4681) + .saturating_add(RocksDbWeight::get().reads(2_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } + fn request_revenue_info_at() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 170_000 picoseconds. + Weight::from_parts(208_000, 0) + } } From 6b6e7aa2e9a5224357d92b3ec036bde3196029e5 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:09:10 +0530 Subject: [PATCH 104/131] Adds benchmark for drop_history and fixes worst case for claim_revenue --- frame/broker/src/benchmarking.rs | 52 ++++++++++++++++++++++++++++---- frame/broker/src/lib.rs | 2 ++ frame/broker/src/tick_impls.rs | 4 +-- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 1625c8a8c6f43..2a046d085d960 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -142,9 +142,7 @@ mod benches { } #[benchmark] - fn unreserve( - n: Linear<0, { T::MaxReservedCores::get().saturating_sub(1) }>, - ) -> Result<(), BenchmarkError> { + fn unreserve() -> Result<(), BenchmarkError> { // Assume Reservations to be filled for worst case setup_reservations::(T::MaxReservedCores::get()); @@ -152,7 +150,7 @@ mod benches { T::AdminOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; #[extrinsic_call] - _(origin as T::RuntimeOrigin, n); + _(origin as T::RuntimeOrigin, 0); assert_eq!( Reservations::::get().len(), @@ -451,7 +449,7 @@ mod benches { #[benchmark] fn claim_revenue( - m: Linear<0, { new_config_record::().region_length }>, + m: Linear<1, { new_config_record::().region_length }>, ) -> Result<(), BenchmarkError> { let core = setup_and_start_sale::()?; @@ -462,6 +460,10 @@ mod benches { &caller.clone(), T::Currency::minimum_balance().saturating_add(10u32.into()), ); + T::Currency::set_balance( + &Broker::::account_id(), + T::Currency::minimum_balance().saturating_add(200u32.into()), + ); let region = Broker::::do_purchase(caller.clone(), 10u32.into()) .map_err(|_| BenchmarkError::Weightless)?; @@ -471,13 +473,24 @@ mod benches { Broker::::do_pool(region, None, recipient.clone(), Final) .map_err(|_| BenchmarkError::Weightless)?; + let revenue = 10u32.into(); + InstaPoolHistory::::insert( + region.begin, + InstaPoolHistoryRecord { + private_contributions: 4u32.into(), + system_contributions: 3u32.into(), + maybe_payout: Some(revenue), + }, + ); + #[extrinsic_call] _(RawOrigin::Signed(caller), region, m); + assert!(InstaPoolHistory::::get(region.begin).is_none()); assert_last_event::( Event::RevenueClaimPaid { who: recipient, - amount: 0u32.into(), // Todo: fix the conditions for this benchmark + amount: 200u32.into(), next: if m < new_config_record::().region_length { Some(RegionId { begin: 4.saturating_add(m), core, mask: CoreMask::complete() }) } else { @@ -589,6 +602,33 @@ mod benches { Ok(()) } + #[benchmark] + fn drop_history() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + let when = 5u32.into(); + let revenue = 10u32.into(); + + advance_to::(25); + + let caller: T::AccountId = whitelisted_caller(); + InstaPoolHistory::::insert( + when, + InstaPoolHistoryRecord { + private_contributions: 4u32.into(), + system_contributions: 3u32.into(), + maybe_payout: Some(revenue), + }, + ); + + #[extrinsic_call] + _(RawOrigin::Signed(caller), when); + + assert!(InstaPoolHistory::::get(when).is_none()); + assert_last_event::(Event::HistoryDropped { when, revenue }.into()); + + Ok(()) + } + #[benchmark] fn drop_renewal() -> Result<(), BenchmarkError> { let core = setup_and_start_sale::()?; diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index e89bf3c417ce5..c262f40a330e7 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -544,6 +544,7 @@ pub mod pallet { /// - `initial_price`: The price of Bulk Coretime in the first sale. /// - `core_count`: The number of cores which can be allocated. #[pallet::call_index(4)] + #[pallet::weight(T::WeightInfo::start_sales((*core_count).into()))] pub fn start_sales( origin: OriginFor, initial_price: BalanceOf, @@ -769,6 +770,7 @@ pub mod pallet { /// - `origin`: Must be Root or pass `AdminOrigin`. /// - `core_count`: The desired number of cores to be made available. #[pallet::call_index(18)] + #[pallet::weight(T::WeightInfo::request_core_count((*core_count).into()))] pub fn request_core_count(origin: OriginFor, core_count: CoreIndex) -> DispatchResult { T::AdminOrigin::ensure_origin_or_root(origin)?; Self::do_request_core_count(core_count)?; diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 364107a30f15b..8b2c1624b5e9d 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -27,7 +27,7 @@ impl Pallet { let mut meter = WeightMeter::max_limit(); if Self::process_core_count(&mut status) { - meter.consume(T::WeightInfo::process_core_count()); + meter.consume(T::WeightInfo::process_core_count(status.core_count.into())); } if Self::process_revenue() { @@ -40,7 +40,7 @@ impl Pallet { if commit_timeslice >= sale.region_begin { // Sale can be rotated. Self::rotate_sale(sale, &config, &status); - meter.consume(T::WeightInfo::rotate_sale()); + meter.consume(T::WeightInfo::rotate_sale(status.core_count.into())); } } From 87bba2c0b807674b0ea78d886f6b61609f42f5f4 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 29 Jul 2023 11:24:38 +0530 Subject: [PATCH 105/131] Adds drop_history in WeightInfo --- frame/broker/src/weights.rs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index 944fc9b1e8604..e23f05922f1a5 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -51,7 +51,7 @@ use core::marker::PhantomData; pub trait WeightInfo { fn configure() -> Weight; fn reserve() -> Weight; - fn unreserve(n: u32, ) -> Weight; + fn unreserve() -> Weight; fn set_lease() -> Weight; fn start_sales(n: u32, ) -> Weight; fn purchase() -> Weight; @@ -65,6 +65,7 @@ pub trait WeightInfo { fn purchase_credit() -> Weight; fn drop_region() -> Weight; fn drop_contribution() -> Weight; + fn drop_history() -> Weight; fn drop_renewal() -> Weight; fn request_core_count(n: u32, ) -> Weight; fn process_core_count(n: u32, ) -> Weight; @@ -101,15 +102,14 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `Broker::Reservations` (r:1 w:1) /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 4]`. - fn unreserve(n: u32, ) -> Weight { + fn unreserve() -> Weight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` // Minimum execution time: 20_863_000 picoseconds. Weight::from_parts(22_435_696, 7496) // Standard Error: 11_196 - .saturating_add(Weight::from_parts(344, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(344, 0)) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -331,6 +331,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + + fn drop_history() -> Weight { + Weight::from_parts(27_763_000, 4698) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// The range of component `n` is `[0, 1000]`. @@ -447,15 +453,14 @@ impl WeightInfo for () { } /// Storage: `Broker::Reservations` (r:1 w:1) /// Proof: `Broker::Reservations` (`max_values`: Some(1), `max_size`: Some(6011), added: 6506, mode: `MaxEncodedLen`) - /// The range of component `n` is `[0, 4]`. - fn unreserve(n: u32, ) -> Weight { + fn unreserve() -> Weight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` // Minimum execution time: 20_863_000 picoseconds. Weight::from_parts(22_435_696, 7496) // Standard Error: 11_196 - .saturating_add(Weight::from_parts(344, 0).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(344, 0)) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -664,6 +669,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + + fn drop_history() -> Weight { + Weight::from_parts(36_341_000, 3533) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::AllowedRenewals` (r:1 w:1) From 56a92b43bd8bd559f1ddf07d37acf692becf05b4 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Sat, 29 Jul 2023 06:24:48 +0000 Subject: [PATCH 106/131] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_broker --- frame/broker/src/weights.rs | 282 +++++++++++++++++++----------------- 1 file changed, 148 insertions(+), 134 deletions(-) diff --git a/frame/broker/src/weights.rs b/frame/broker/src/weights.rs index e23f05922f1a5..93b568bf2a035 100644 --- a/frame/broker/src/weights.rs +++ b/frame/broker/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for `pallet_broker` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-07-25, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-07-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` //! HOSTNAME: `runner-ynta1nyy-project-145-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` @@ -85,8 +85,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_157_000 picoseconds. - Weight::from_parts(3_478_000, 0) + // Minimum execution time: 3_448_000 picoseconds. + Weight::from_parts(3_729_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -95,8 +95,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 22_427_000 picoseconds. - Weight::from_parts(23_442_000, 7496) + // Minimum execution time: 22_537_000 picoseconds. + Weight::from_parts(23_335_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -106,10 +106,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 20_863_000 picoseconds. - Weight::from_parts(22_435_696, 7496) - // Standard Error: 11_196 - .saturating_add(Weight::from_parts(344, 0)) + // Minimum execution time: 21_668_000 picoseconds. + Weight::from_parts(22_442_000, 7496) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -119,8 +117,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 12_827_000 picoseconds. - Weight::from_parts(13_470_000, 1526) + // Minimum execution time: 13_606_000 picoseconds. + Weight::from_parts(14_104_000, 1526) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -143,8 +141,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 64_179_000 picoseconds. - Weight::from_parts(67_646_772, 8499) + // Minimum execution time: 64_012_000 picoseconds. + Weight::from_parts(67_819_922, 8499) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(16_u64)) } @@ -162,8 +160,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `568` // Estimated: `2053` - // Minimum execution time: 49_065_000 picoseconds. - Weight::from_parts(50_220_000, 2053) + // Minimum execution time: 48_110_000 picoseconds. + Weight::from_parts(49_234_000, 2053) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -185,8 +183,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `686` // Estimated: `4698` - // Minimum execution time: 75_326_000 picoseconds. - Weight::from_parts(76_193_000, 4698) + // Minimum execution time: 69_580_000 picoseconds. + Weight::from_parts(70_914_000, 4698) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -196,8 +194,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 17_564_000 picoseconds. - Weight::from_parts(18_212_000, 3550) + // Minimum execution time: 17_687_000 picoseconds. + Weight::from_parts(18_573_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -207,8 +205,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_548_000 picoseconds. - Weight::from_parts(20_585_000, 3550) + // Minimum execution time: 19_675_000 picoseconds. + Weight::from_parts(20_234_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -218,8 +216,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_603_000 picoseconds. - Weight::from_parts(20_075_000, 3550) + // Minimum execution time: 19_426_000 picoseconds. + Weight::from_parts(20_414_000, 3550) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -235,8 +233,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 32_255_000 picoseconds. - Weight::from_parts(33_243_000, 4681) + // Minimum execution time: 31_751_000 picoseconds. + Weight::from_parts(32_966_000, 4681) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -254,29 +252,29 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 37_211_000 picoseconds. - Weight::from_parts(38_985_000, 5996) + // Minimum execution time: 36_709_000 picoseconds. + Weight::from_parts(38_930_000, 5996) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } /// Storage: `Broker::InstaPoolContribution` (r:1 w:1) /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) - /// Storage: `Broker::InstaPoolHistory` (r:3 w:0) + /// Storage: `Broker::InstaPoolHistory` (r:3 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:1) + /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `m` is `[0, 3]`. + /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `478 + m * (45 ±0)` + // Measured: `720` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 43_370_000 picoseconds. - Weight::from_parts(46_106_878, 6196) - // Standard Error: 76_802 - .saturating_add(Weight::from_parts(3_803_718, 0).saturating_mul(m.into())) + // Minimum execution time: 55_510_000 picoseconds. + Weight::from_parts(56_665_061, 6196) + // Standard Error: 61_729 + .saturating_add(Weight::from_parts(1_724_824, 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(2_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(m.into())) } /// Storage: `System::Account` (r:1 w:1) @@ -285,8 +283,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 44_947_000 picoseconds. - Weight::from_parts(45_909_000, 3593) + // Minimum execution time: 44_992_000 picoseconds. + Weight::from_parts(46_225_000, 3593) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -298,8 +296,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 31_169_000 picoseconds. - Weight::from_parts(32_139_000, 3550) + // Minimum execution time: 28_207_000 picoseconds. + Weight::from_parts(28_707_000, 3550) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -313,11 +311,28 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 34_722_000 picoseconds. - Weight::from_parts(36_341_000, 3533) + // Minimum execution time: 31_813_000 picoseconds. + Weight::from_parts(32_612_000, 3533) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// 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: `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:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn drop_history() -> Weight { + // Proof Size summary in bytes: + // Measured: `829` + // Estimated: `3593` + // Minimum execution time: 38_571_000 picoseconds. + Weight::from_parts(39_493_000, 3593) + .saturating_add(T::DbWeight::get().reads(4_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } /// Storage: `Broker::Status` (r:1 w:0) /// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`) /// Storage: `Broker::AllowedRenewals` (r:1 w:1) @@ -326,28 +341,20 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `525` // Estimated: `4698` - // Minimum execution time: 26_324_000 picoseconds. - Weight::from_parts(27_763_000, 4698) - .saturating_add(T::DbWeight::get().reads(2_u64)) - .saturating_add(T::DbWeight::get().writes(1_u64)) - } - - fn drop_history() -> Weight { - Weight::from_parts(27_763_000, 4698) + // Minimum execution time: 24_714_000 picoseconds. + Weight::from_parts(25_288_000, 4698) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// 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: 6_928_000 picoseconds. - Weight::from_parts(7_661_845, 0) - // Standard Error: 23 - .saturating_add(Weight::from_parts(37, 0).saturating_mul(n.into())) + // Minimum execution time: 7_258_000 picoseconds. + Weight::from_parts(7_925_570, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) @@ -357,8 +364,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `97` // Estimated: `3562` - // Minimum execution time: 7_279_000 picoseconds. - Weight::from_parts(7_867_446, 3562) + // Minimum execution time: 7_136_000 picoseconds. + Weight::from_parts(7_788_194, 3562) .saturating_add(T::DbWeight::get().reads(1_u64)) } /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) @@ -367,8 +374,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_005_000 picoseconds. - Weight::from_parts(6_416_000, 0) + // Minimum execution time: 6_049_000 picoseconds. + Weight::from_parts(6_311_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Broker::InstaPoolIo` (r:3 w:3) @@ -386,10 +393,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 47_284_000 picoseconds. - Weight::from_parts(49_700_704, 8499) - // Standard Error: 121 - .saturating_add(Weight::from_parts(35, 0).saturating_mul(n.into())) + // Minimum execution time: 47_504_000 picoseconds. + Weight::from_parts(49_778_098, 8499) + // Standard Error: 109 + .saturating_add(Weight::from_parts(427, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(15_u64)) } @@ -401,8 +408,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 9_651_000 picoseconds. - Weight::from_parts(10_076_000, 3493) + // Minimum execution time: 9_573_000 picoseconds. + Weight::from_parts(10_034_000, 3493) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -414,8 +421,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 20_975_000 picoseconds. - Weight::from_parts(21_846_000, 4681) + // Minimum execution time: 21_331_000 picoseconds. + Weight::from_parts(22_235_000, 4681) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -423,8 +430,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 170_000 picoseconds. - Weight::from_parts(208_000, 0) + // Minimum execution time: 191_000 picoseconds. + Weight::from_parts(234_000, 0) } } @@ -436,8 +443,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_157_000 picoseconds. - Weight::from_parts(3_478_000, 0) + // Minimum execution time: 3_448_000 picoseconds. + Weight::from_parts(3_729_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Reservations` (r:1 w:1) @@ -446,8 +453,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `5016` // Estimated: `7496` - // Minimum execution time: 22_427_000 picoseconds. - Weight::from_parts(23_442_000, 7496) + // Minimum execution time: 22_537_000 picoseconds. + Weight::from_parts(23_335_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -457,10 +464,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6218` // Estimated: `7496` - // Minimum execution time: 20_863_000 picoseconds. - Weight::from_parts(22_435_696, 7496) - // Standard Error: 11_196 - .saturating_add(Weight::from_parts(344, 0)) + // Minimum execution time: 21_668_000 picoseconds. + Weight::from_parts(22_442_000, 7496) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -470,8 +475,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `239` // Estimated: `1526` - // Minimum execution time: 12_827_000 picoseconds. - Weight::from_parts(13_470_000, 1526) + // Minimum execution time: 13_606_000 picoseconds. + Weight::from_parts(14_104_000, 1526) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -494,8 +499,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6330` // Estimated: `8499` - // Minimum execution time: 64_179_000 picoseconds. - Weight::from_parts(67_646_772, 8499) + // Minimum execution time: 64_012_000 picoseconds. + Weight::from_parts(67_819_922, 8499) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(16_u64)) } @@ -513,8 +518,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `568` // Estimated: `2053` - // Minimum execution time: 49_065_000 picoseconds. - Weight::from_parts(50_220_000, 2053) + // Minimum execution time: 48_110_000 picoseconds. + Weight::from_parts(49_234_000, 2053) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -536,8 +541,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `686` // Estimated: `4698` - // Minimum execution time: 75_326_000 picoseconds. - Weight::from_parts(76_193_000, 4698) + // Minimum execution time: 69_580_000 picoseconds. + Weight::from_parts(70_914_000, 4698) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -547,8 +552,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 17_564_000 picoseconds. - Weight::from_parts(18_212_000, 3550) + // Minimum execution time: 17_687_000 picoseconds. + Weight::from_parts(18_573_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -558,8 +563,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_548_000 picoseconds. - Weight::from_parts(20_585_000, 3550) + // Minimum execution time: 19_675_000 picoseconds. + Weight::from_parts(20_234_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -569,8 +574,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `495` // Estimated: `3550` - // Minimum execution time: 19_603_000 picoseconds. - Weight::from_parts(20_075_000, 3550) + // Minimum execution time: 19_426_000 picoseconds. + Weight::from_parts(20_414_000, 3550) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -586,8 +591,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `740` // Estimated: `4681` - // Minimum execution time: 32_255_000 picoseconds. - Weight::from_parts(33_243_000, 4681) + // Minimum execution time: 31_751_000 picoseconds. + Weight::from_parts(32_966_000, 4681) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -605,29 +610,29 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `775` // Estimated: `5996` - // Minimum execution time: 37_211_000 picoseconds. - Weight::from_parts(38_985_000, 5996) + // Minimum execution time: 36_709_000 picoseconds. + Weight::from_parts(38_930_000, 5996) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } /// Storage: `Broker::InstaPoolContribution` (r:1 w:1) /// Proof: `Broker::InstaPoolContribution` (`max_values`: None, `max_size`: Some(68), added: 2543, mode: `MaxEncodedLen`) - /// Storage: `Broker::InstaPoolHistory` (r:3 w:0) + /// Storage: `Broker::InstaPoolHistory` (r:3 w:1) /// Proof: `Broker::InstaPoolHistory` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:2 w:1) + /// Storage: `System::Account` (r:2 w:0) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// The range of component `m` is `[0, 3]`. + /// The range of component `m` is `[1, 3]`. fn claim_revenue(m: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `478 + m * (45 ±0)` + // Measured: `720` // Estimated: `6196 + m * (2520 ±0)` - // Minimum execution time: 43_370_000 picoseconds. - Weight::from_parts(46_106_878, 6196) - // Standard Error: 76_802 - .saturating_add(Weight::from_parts(3_803_718, 0).saturating_mul(m.into())) + // Minimum execution time: 55_510_000 picoseconds. + Weight::from_parts(56_665_061, 6196) + // Standard Error: 61_729 + .saturating_add(Weight::from_parts(1_724_824, 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(2_u64)) + .saturating_add(RocksDbWeight::get().writes(3_u64)) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(m.into())) } /// Storage: `System::Account` (r:1 w:1) @@ -636,8 +641,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `103` // Estimated: `3593` - // Minimum execution time: 44_947_000 picoseconds. - Weight::from_parts(45_909_000, 3593) + // Minimum execution time: 44_992_000 picoseconds. + Weight::from_parts(46_225_000, 3593) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -649,8 +654,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `603` // Estimated: `3550` - // Minimum execution time: 31_169_000 picoseconds. - Weight::from_parts(32_139_000, 3550) + // Minimum execution time: 28_207_000 picoseconds. + Weight::from_parts(28_707_000, 3550) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -664,15 +669,26 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `601` // Estimated: `3533` - // Minimum execution time: 34_722_000 picoseconds. - Weight::from_parts(36_341_000, 3533) + // Minimum execution time: 31_813_000 picoseconds. + Weight::from_parts(32_612_000, 3533) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - + /// 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: `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:0) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) fn drop_history() -> Weight { - Weight::from_parts(36_341_000, 3533) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Proof Size summary in bytes: + // Measured: `829` + // Estimated: `3593` + // Minimum execution time: 38_571_000 picoseconds. + Weight::from_parts(39_493_000, 3593) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::Status` (r:1 w:0) @@ -683,22 +699,20 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `525` // Estimated: `4698` - // Minimum execution time: 26_324_000 picoseconds. - Weight::from_parts(27_763_000, 4698) + // Minimum execution time: 24_714_000 picoseconds. + Weight::from_parts(25_288_000, 4698) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// Proof: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:0 w:1) /// 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: 6_928_000 picoseconds. - Weight::from_parts(7_661_845, 0) - // Standard Error: 23 - .saturating_add(Weight::from_parts(37, 0).saturating_mul(n.into())) + // Minimum execution time: 7_258_000 picoseconds. + Weight::from_parts(7_925_570, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: UNKNOWN KEY `0x18194fcb5c1fcace44d2d0a004272614` (r:1 w:0) @@ -708,8 +722,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `97` // Estimated: `3562` - // Minimum execution time: 7_279_000 picoseconds. - Weight::from_parts(7_867_446, 3562) + // Minimum execution time: 7_136_000 picoseconds. + Weight::from_parts(7_788_194, 3562) .saturating_add(RocksDbWeight::get().reads(1_u64)) } /// Storage: `Broker::InstaPoolHistory` (r:0 w:1) @@ -718,8 +732,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_005_000 picoseconds. - Weight::from_parts(6_416_000, 0) + // Minimum execution time: 6_049_000 picoseconds. + Weight::from_parts(6_311_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Broker::InstaPoolIo` (r:3 w:3) @@ -737,10 +751,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6281` // Estimated: `8499` - // Minimum execution time: 47_284_000 picoseconds. - Weight::from_parts(49_700_704, 8499) - // Standard Error: 121 - .saturating_add(Weight::from_parts(35, 0).saturating_mul(n.into())) + // Minimum execution time: 47_504_000 picoseconds. + Weight::from_parts(49_778_098, 8499) + // Standard Error: 109 + .saturating_add(Weight::from_parts(427, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(15_u64)) } @@ -752,8 +766,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `180` // Estimated: `3493` - // Minimum execution time: 9_651_000 picoseconds. - Weight::from_parts(10_076_000, 3493) + // Minimum execution time: 9_573_000 picoseconds. + Weight::from_parts(10_034_000, 3493) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -765,8 +779,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `1423` // Estimated: `4681` - // Minimum execution time: 20_975_000 picoseconds. - Weight::from_parts(21_846_000, 4681) + // Minimum execution time: 21_331_000 picoseconds. + Weight::from_parts(22_235_000, 4681) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -774,7 +788,7 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 170_000 picoseconds. - Weight::from_parts(208_000, 0) + // Minimum execution time: 191_000 picoseconds. + Weight::from_parts(234_000, 0) } } From 343b695dc011bf30339897b56ca29ace896046cf Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Sat, 29 Jul 2023 14:18:07 +0530 Subject: [PATCH 107/131] Minor fix for Quick Benchmark CI --- frame/broker/src/benchmarking.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 2a046d085d960..fb4b72c4a11f8 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -469,6 +469,7 @@ mod benches { .map_err(|_| BenchmarkError::Weightless)?; let recipient: T::AccountId = account("recipient", 0, SEED); + T::Currency::set_balance(&recipient.clone(), T::Currency::minimum_balance()); Broker::::do_pool(region, None, recipient.clone(), Final) .map_err(|_| BenchmarkError::Weightless)?; From c588f3c756d3945614f5f90fd37ec66daaeb4d67 Mon Sep 17 00:00:00 2001 From: Gav Date: Sat, 29 Jul 2023 11:03:39 +0100 Subject: [PATCH 108/131] Fixes --- frame/broker/src/dispatchable_impls.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 9a935c486aefa..2cf933cbec389 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -39,6 +39,7 @@ impl Pallet { pub(crate) fn do_set_lease(task: TaskId, until: Timeslice) -> DispatchResult { let mut r = Leases::::get(); + ensure!(until > Self::current_timeslice(), Error::::AlreadyExpired); r.try_push(LeaseRecordItem { until, task }) .map_err(|_| Error::::TooManyLeases)?; Leases::::put(r); @@ -327,7 +328,7 @@ impl Pallet { payout.saturating_accrue(p); pool_record.private_contributions.saturating_reduce(contributed_parts); - let remaining_payout = total_payout.saturating_sub(payout); + let remaining_payout = total_payout.saturating_sub(p); if !remaining_payout.is_zero() && pool_record.private_contributions > 0 { pool_record.maybe_payout = Some(remaining_payout); InstaPoolHistory::::insert(r, &pool_record); From def03b9661a3da39e5d225dcbc9afe3c923b25e3 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 31 Jul 2023 15:35:06 +0100 Subject: [PATCH 109/131] Docs --- client/consensus/grandpa/src/communication/gossip.rs | 4 +--- frame/asset-conversion/src/lib.rs | 4 +++- frame/asset-conversion/src/tests.rs | 6 +++++- frame/broker/README.md | 12 ------------ 4 files changed, 9 insertions(+), 17 deletions(-) diff --git a/client/consensus/grandpa/src/communication/gossip.rs b/client/consensus/grandpa/src/communication/gossip.rs index 5688aff3ea717..3a78b157d5b1b 100644 --- a/client/consensus/grandpa/src/communication/gossip.rs +++ b/client/consensus/grandpa/src/communication/gossip.rs @@ -546,9 +546,7 @@ impl Peers { who: &PeerId, update: NeighborPacket, ) -> Result>, Misbehavior> { - let Some(peer) = self.inner.get_mut(who) else { - return Ok(None) - }; + let Some(peer) = self.inner.get_mut(who) else { return Ok(None) }; let invalid_change = peer.view.set_id > update.set_id || peer.view.round > update.round && peer.view.set_id == update.set_id || diff --git a/frame/asset-conversion/src/lib.rs b/frame/asset-conversion/src/lib.rs index f9aeeace11fe7..8d266a20492a2 100644 --- a/frame/asset-conversion/src/lib.rs +++ b/frame/asset-conversion/src/lib.rs @@ -1194,7 +1194,9 @@ pub mod pallet { () ); } else { - let MultiAssetIdConversionResult::Converted(asset_id) = T::MultiAssetIdConverter::try_convert(asset) else { + let MultiAssetIdConversionResult::Converted(asset_id) = + T::MultiAssetIdConverter::try_convert(asset) + else { return Err(()) }; let minimal = T::Assets::minimum_balance(asset_id); diff --git a/frame/asset-conversion/src/tests.rs b/frame/asset-conversion/src/tests.rs index 80faf5363b011..450a074ec3675 100644 --- a/frame/asset-conversion/src/tests.rs +++ b/frame/asset-conversion/src/tests.rs @@ -66,7 +66,11 @@ fn pool_assets() -> Vec { fn create_tokens(owner: u128, tokens: Vec>) { for token_id in tokens { - let MultiAssetIdConversionResult::Converted(asset_id) = NativeOrAssetIdConverter::try_convert(&token_id) else { unreachable!("invalid token") }; + let MultiAssetIdConversionResult::Converted(asset_id) = + NativeOrAssetIdConverter::try_convert(&token_id) + else { + unreachable!("invalid token") + }; assert_ok!(Assets::force_create(RuntimeOrigin::root(), asset_id, owner, false, 1)); } } diff --git a/frame/broker/README.md b/frame/broker/README.md index b62eebbed177e..65b6179863e3d 100644 --- a/frame/broker/README.md +++ b/frame/broker/README.md @@ -24,15 +24,3 @@ indicates usage of a single core one time over a timeslice. | <-------\ price fixed, unsold assigned to instapool, system cores reserved -/ ``` - -## TODO - -- More Events - -- Benchmarks -- Weights -- Final docs -- Tests - - Tests for dropping out of date storage - - Tests for core count changes - - Tests for every error From 0560151250d17846e143209ea40147ddd4890d58 Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 31 Jul 2023 15:36:50 +0100 Subject: [PATCH 110/131] Headers --- frame/broker/src/adapt_price.rs | 17 +++++++++++++++++ frame/broker/src/core_mask.rs | 17 +++++++++++++++++ frame/broker/src/coretime_interface.rs | 17 +++++++++++++++++ frame/broker/src/dispatchable_impls.rs | 17 +++++++++++++++++ frame/broker/src/nonfungible_impl.rs | 17 +++++++++++++++++ frame/broker/src/tick_impls.rs | 17 +++++++++++++++++ frame/broker/src/types.rs | 17 +++++++++++++++++ frame/broker/src/utility_impls.rs | 17 +++++++++++++++++ 8 files changed, 136 insertions(+) diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs index 0e7d4a534f3de..d89154f640005 100644 --- a/frame/broker/src/adapt_price.rs +++ b/frame/broker/src/adapt_price.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::CoreIndex; use sp_arithmetic::{traits::One, FixedU64}; diff --git a/frame/broker/src/core_mask.rs b/frame/broker/src/core_mask.rs index fea8e40f0c323..f83ed42b455c8 100644 --- a/frame/broker/src/core_mask.rs +++ b/frame/broker/src/core_mask.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use codec::{Decode, Encode, MaxEncodedLen}; use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not}; use scale_info::TypeInfo; diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 3ba181bd806e5..5197bc49c63f1 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::Parameter; use scale_info::TypeInfo; diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 2cf933cbec389..181395b734b2f 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use super::*; use frame_support::{ pallet_prelude::{DispatchResult, *}, diff --git a/frame/broker/src/nonfungible_impl.rs b/frame/broker/src/nonfungible_impl.rs index 4a6d404e39986..fe95438cb1afa 100644 --- a/frame/broker/src/nonfungible_impl.rs +++ b/frame/broker/src/nonfungible_impl.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use super::*; use frame_support::{ pallet_prelude::{DispatchResult, *}, diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index 8b2c1624b5e9d..abf356f6b83a5 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use super::*; use frame_support::{pallet_prelude::*, weights::WeightMeter}; use sp_arithmetic::{ diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index 7405b860cc911..e8210b380b1bc 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use crate::{ Config, CoreAssignment, CoreIndex, CoreMask, CoretimeInterface, TaskId, CORE_MASK_BITS, }; diff --git a/frame/broker/src/utility_impls.rs b/frame/broker/src/utility_impls.rs index c2b9bfc876479..99c4de32f7767 100644 --- a/frame/broker/src/utility_impls.rs +++ b/frame/broker/src/utility_impls.rs @@ -1,3 +1,20 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + use super::*; use frame_support::{ pallet_prelude::{DispatchResult, *}, From 3ccb6104afa591e6eec2821cc0aba89834035fef Mon Sep 17 00:00:00 2001 From: gupnik <17176722+gupnik@users.noreply.github.com> Date: Mon, 31 Jul 2023 20:32:24 +0530 Subject: [PATCH 111/131] Expose a couple of APIs for benchmarking (#14688) * Expose a couple of APIs for benchmarking * Adds doc * Minor fix in CoretimeInterface impl for kitchensik * Minor --- bin/node/runtime/src/lib.rs | 23 +++++++++++----- frame/broker/src/benchmarking.rs | 36 +++++++++++++++++++++++--- frame/broker/src/coretime_interface.rs | 18 ++++++++++++- frame/broker/src/mock.rs | 9 +++++++ 4 files changed, 75 insertions(+), 11 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 6bb18fb74666d..7c411f12a79e0 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1888,7 +1888,8 @@ impl OnUnbalanced> for IntoAuthor { } parameter_types! { - pub storage CoreCount: CoreIndex = 20; + pub storage CoreCount: Option = None; + pub storage CoretimeRevenue: Option<(BlockNumber, Balance)> = None; } pub struct CoretimeProvider; @@ -1899,9 +1900,7 @@ impl CoretimeInterface for CoretimeProvider { fn latest() -> Self::BlockNumber { System::block_number() } - fn request_core_count(count: CoreIndex) { - CoreCount::set(&count); - } + fn request_core_count(_count: CoreIndex) {} fn request_revenue_info_at(_when: Self::BlockNumber) {} fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {} fn assign_core( @@ -1912,10 +1911,22 @@ impl CoretimeInterface for CoretimeProvider { ) { } fn check_notify_core_count() -> Option { - Some(CoreCount::get()) + let count = CoreCount::get(); + CoreCount::set(&None); + count } fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { - Some((10u32.into(), 0u32.into())) + let revenue = CoretimeRevenue::get(); + CoretimeRevenue::set(&None); + revenue + } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_core_count(count: u16) { + CoreCount::set(&Some(count)); + } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_revenue_info(when: Self::BlockNumber, revenue: Self::Balance) { + CoretimeRevenue::set(&Some((when, revenue))); } } diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index fb4b72c4a11f8..17b21f596af68 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -676,7 +676,7 @@ mod benches { let core_count = n.try_into().unwrap(); - Broker::::do_request_core_count(core_count).map_err(|_| BenchmarkError::Weightless)?; + ::ensure_notify_core_count(core_count); let mut status = Status::::get().ok_or(BenchmarkError::Weightless)?; @@ -690,17 +690,45 @@ mod benches { Ok(()) } - // Todo: Fix conditions for worst case #[benchmark] - fn process_revenue() { + fn process_revenue() -> Result<(), BenchmarkError> { + setup_and_start_sale::()?; + + advance_to::(2); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::set_balance( + &caller.clone(), + T::Currency::minimum_balance().saturating_add(30u32.into()), + ); + T::Currency::set_balance(&Broker::::account_id(), T::Currency::minimum_balance()); + + ::ensure_notify_revenue_info(10u32.into(), 10u32.into()); + + InstaPoolHistory::::insert( + 4u32, + InstaPoolHistoryRecord { + private_contributions: 1u32.into(), + system_contributions: 9u32.into(), + maybe_payout: None, + }, + ); + #[block] { Broker::::process_revenue(); } assert_last_event::( - Event::HistoryDropped { when: 4u32.into(), revenue: 0u32.into() }.into(), + Event::ClaimsReady { + when: 4u32.into(), + system_payout: 9u32.into(), + private_payout: 1u32.into(), + } + .into(), ); + + Ok(()) } #[benchmark] diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 5197bc49c63f1..6e69ca66c6f2f 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -53,7 +53,7 @@ pub trait CoretimeInterface { type AccountId: Parameter; /// A (Relay-chain-side) balance. - type Balance; + type Balance: AtLeast32BitUnsigned; /// A (Relay-chain-side) block number. type BlockNumber: AtLeast32BitUnsigned @@ -122,6 +122,18 @@ pub trait CoretimeInterface { /// notified of revenue information. The Relay-chain must be configured to ensure that only a /// single revenue information destination exists. fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)>; + + /// Ensure that core count is updated to the provided value. + /// + /// This is only used for benchmarking. + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_core_count(count: u16); + + /// Ensure that revenue information is updated to the provided value. + /// + /// This is only used for benchmarking. + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_revenue_info(when: Self::BlockNumber, revenue: Self::Balance); } impl CoretimeInterface for () { @@ -147,4 +159,8 @@ impl CoretimeInterface for () { fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { None } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_core_count(_count: u16) {} + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_revenue_info(_when: Self::BlockNumber, _revenue: Self::Balance) {} } diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 3366678741eb6..6ec37e0e7de80 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -110,6 +110,7 @@ impl CoretimeInterface for TestCoretimeProvider { if when > Self::latest() { panic!("Asking for revenue info in the future {:?} {:?}", when, Self::latest()); } + let mut total = 0; CoretimeSpending::mutate(|s| { s.retain(|(n, a)| { @@ -142,6 +143,14 @@ impl CoretimeInterface for TestCoretimeProvider { fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> { NotifyRevenueInfo::mutate(|s| s.pop()) } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_core_count(count: u16) { + NotifyCoreCount::mutate(|s| s.insert(0, count)); + } + #[cfg(feature = "runtime-benchmarks")] + fn ensure_notify_revenue_info(when: Self::BlockNumber, revenue: Self::Balance) { + NotifyRevenueInfo::mutate(|s| s.push((when, revenue))); + } } impl TestCoretimeProvider { pub fn spend_instantaneous(who: u64, price: u64) -> Result<(), ()> { From e1c772021d581711f18f2d8546959836d7fd0ded Mon Sep 17 00:00:00 2001 From: Gav Date: Mon, 31 Jul 2023 16:40:54 +0100 Subject: [PATCH 112/131] Cap renewal price --- frame/broker/src/dispatchable_impls.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 181395b734b2f..319d29c6cd00a 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -151,7 +151,9 @@ impl Pallet { Workplan::::insert((sale.region_begin, core), &workload); let begin = sale.region_end; - let price = record.price + config.renewal_bump * record.price; + let price_cap = record.price + config.renewal_bump * record.price; + let now = frame_system::Pallet::::block_number(); + let price = Self::sale_price(&sale, now).min(price_cap); let new_record = AllowedRenewalRecord { price, completion: Complete(workload) }; AllowedRenewals::::remove(renewal_id); AllowedRenewals::::insert(AllowedRenewalId { core, when: begin }, &new_record); From 841b9d256eb75a5a770696750890b01af0f1c2c6 Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Tue, 1 Aug 2023 18:10:51 +0530 Subject: [PATCH 113/131] Adds a few tests --- frame/broker/src/tests.rs | 98 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 28e8caae0d6db..3fc0789aefcc4 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -21,7 +21,9 @@ use crate::{core_mask::*, mock::*, *}; use frame_support::{ assert_noop, assert_ok, traits::nonfungible::{Inspect as NftInspect, Transfer}, + BoundedVec, }; +use sp_runtime::traits::Get; use CoreAssignment::*; use CoretimeTraceItem::*; use Finality::*; @@ -650,3 +652,99 @@ fn partition_then_interlace_works() { ); }); } + +#[test] +fn reservations_are_limited() { + TestExt::new().execute_with(|| { + let schedule = Schedule::truncate_from(vec![ScheduleItem { + assignment: Pool, + mask: CoreMask::complete(), + }]); + let max_cores: u32 = ::MaxReservedCores::get(); + Reservations::::put( + BoundedVec::try_from(vec![schedule.clone(); max_cores as usize]).unwrap(), + ); + assert_noop!(Broker::do_reserve(schedule), Error::::TooManyReservations); + }); +} + +#[test] +fn cannot_unreserve_unknown() { + TestExt::new().execute_with(|| { + let schedule = Schedule::truncate_from(vec![ScheduleItem { + assignment: Pool, + mask: CoreMask::complete(), + }]); + Reservations::::put(BoundedVec::try_from(vec![schedule.clone(); 1usize]).unwrap()); + assert_noop!(Broker::do_unreserve(2), Error::::UnknownReservation); + }); +} + +#[test] +fn cannot_set_expired_lease() { + TestExt::new().execute_with(|| { + advance_to(2); + let current_timeslice = Broker::current_timeslice(); + assert_noop!( + Broker::do_set_lease(1000, current_timeslice.saturating_sub(1)), + Error::::AlreadyExpired + ); + }); +} + +#[test] +fn leases_are_limited() { + TestExt::new().execute_with(|| { + let max_leases: u32 = ::MaxLeasedCores::get(); + Leases::::put( + BoundedVec::try_from(vec![ + LeaseRecordItem { task: 1u32, until: 10u32 }; + max_leases as usize + ]) + .unwrap(), + ); + assert_noop!(Broker::do_set_lease(1000, 10), Error::::TooManyLeases); + }); +} + +#[test] +fn purchase_requires_valid_status_and_sale_info() { + TestExt::new().execute_with(|| { + assert_noop!(Broker::do_purchase(1, 100), Error::::Uninitialized); + + let status = StatusRecord { + core_count: 2, + private_pool_size: 0, + system_pool_size: 0, + last_committed_timeslice: 0, + last_timeslice: 1, + }; + Status::::put(&status); + assert_noop!(Broker::do_purchase(1, 100), Error::::NoSales); + + let mut dummy_sale = SaleInfoRecord { + sale_start: 0, + leadin_length: 0, + price: 200, + sellout_price: None, + region_begin: 0, + region_end: 3, + first_core: 3, + ideal_cores_sold: 0, + cores_offered: 1, + cores_sold: 2, + }; + SaleInfo::::put(&dummy_sale); + assert_noop!(Broker::do_purchase(1, 100), Error::::Unavailable); + + dummy_sale.first_core = 1; + SaleInfo::::put(&dummy_sale); + assert_noop!(Broker::do_purchase(1, 100), Error::::SoldOut); + + assert_ok!(Broker::do_start_sales(200, 1)); + assert_noop!(Broker::do_purchase(1, 100), Error::::TooEarly); + + advance_to(2); + assert_noop!(Broker::do_purchase(1, 100), Error::::Overpriced); + }); +} From f8fed4afe42c3e9b50b25e770fea5fe2c19cd6aa Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:57:29 +0530 Subject: [PATCH 114/131] Adds more tests --- frame/broker/src/tests.rs | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 3fc0789aefcc4..d0c3ea5499191 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -748,3 +748,108 @@ fn purchase_requires_valid_status_and_sale_info() { assert_noop!(Broker::do_purchase(1, 100), Error::::Overpriced); }); } + +#[test] +fn renewal_requires_valid_status_and_sale_info() { + TestExt::new().execute_with(|| { + assert_noop!(Broker::do_renew(1, 1), Error::::Uninitialized); + + let status = StatusRecord { + core_count: 2, + private_pool_size: 0, + system_pool_size: 0, + last_committed_timeslice: 0, + last_timeslice: 1, + }; + Status::::put(&status); + assert_noop!(Broker::do_renew(1, 1), Error::::NoSales); + + let mut dummy_sale = SaleInfoRecord { + sale_start: 0, + leadin_length: 0, + price: 200, + sellout_price: None, + region_begin: 0, + region_end: 3, + first_core: 3, + ideal_cores_sold: 0, + cores_offered: 1, + cores_sold: 2, + }; + SaleInfo::::put(&dummy_sale); + assert_noop!(Broker::do_renew(1, 1), Error::::Unavailable); + + dummy_sale.first_core = 1; + SaleInfo::::put(&dummy_sale); + assert_noop!(Broker::do_renew(1, 1), Error::::SoldOut); + + assert_ok!(Broker::do_start_sales(200, 1)); + assert_noop!(Broker::do_renew(1, 1), Error::::NotAllowed); + + let record = AllowedRenewalRecord { + price: 100, + completion: CompletionStatus::Partial(CoreMask::from_chunk(0, 20)), + }; + AllowedRenewals::::insert(AllowedRenewalId { core: 1, when: 4 }, &record); + assert_noop!(Broker::do_renew(1, 1), Error::::IncompleteAssignment); + }); +} + +#[test] +fn cannot_transfer_or_partition_or_interlace_unknown() { + TestExt::new().execute_with(|| { + let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() }; + assert_noop!(Broker::do_transfer(region_id, None, 2), Error::::UnknownRegion); + assert_noop!(Broker::do_partition(region_id, None, 2), Error::::UnknownRegion); + assert_noop!( + Broker::do_interlace(region_id, None, CoreMask::from_chunk(0, 20)), + Error::::UnknownRegion + ); + }); +} + +#[test] +fn check_ownership_for_transfer_or_partition_or_interlace() { + TestExt::new().execute_with(|| { + let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() }; + let record = RegionRecord { end: 4, owner: 1, paid: None }; + Regions::::insert(region_id, &record); + assert_noop!(Broker::do_transfer(region_id, Some(2), 2), Error::::NotOwner); + assert_noop!(Broker::do_partition(region_id, Some(2), 2), Error::::NotOwner); + assert_noop!( + Broker::do_interlace(region_id, Some(2), CoreMask::from_chunk(0, 20)), + Error::::NotOwner + ); + }); +} + +#[test] +fn cannot_partition_invalid_offset() { + TestExt::new().execute_with(|| { + let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() }; + let record = RegionRecord { end: 4, owner: 1, paid: None }; + Regions::::insert(region_id, &record); + assert_noop!(Broker::do_partition(region_id, None, 5), Error::::PivotTooLate); + }); +} + +#[test] +fn cannot_interlace_invalid_pivot() { + TestExt::new().execute_with(|| { + let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::from_chunk(0, 20) }; + let record = RegionRecord { end: 4, owner: 1, paid: None }; + Regions::::insert(region_id, &record); + assert_noop!( + Broker::do_interlace(region_id, None, CoreMask::from_chunk(20, 40)), + Error::::ExteriorPivot + ); + assert_noop!( + Broker::do_interlace(region_id, None, CoreMask::void()), + Error::::VoidPivot + ); + assert_noop!( + Broker::do_interlace(region_id, None, CoreMask::from_chunk(0, 20)), + Error::::CompletePivot + ); + }); +} From 913bc91d46201111bb6812a80949f6b88965b7ce Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Wed, 2 Aug 2023 16:39:43 +0530 Subject: [PATCH 115/131] Minor updates --- frame/broker/src/tests.rs | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index d0c3ea5499191..c21e7d55f2a89 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -810,14 +810,14 @@ fn cannot_transfer_or_partition_or_interlace_unknown() { #[test] fn check_ownership_for_transfer_or_partition_or_interlace() { - TestExt::new().execute_with(|| { - let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() }; - let record = RegionRecord { end: 4, owner: 1, paid: None }; - Regions::::insert(region_id, &record); - assert_noop!(Broker::do_transfer(region_id, Some(2), 2), Error::::NotOwner); - assert_noop!(Broker::do_partition(region_id, Some(2), 2), Error::::NotOwner); + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_noop!(Broker::do_transfer(region, Some(2), 2), Error::::NotOwner); + assert_noop!(Broker::do_partition(region, Some(2), 2), Error::::NotOwner); assert_noop!( - Broker::do_interlace(region_id, Some(2), CoreMask::from_chunk(0, 20)), + Broker::do_interlace(region, Some(2), CoreMask::from_chunk(0, 20)), Error::::NotOwner ); }); @@ -825,30 +825,31 @@ fn check_ownership_for_transfer_or_partition_or_interlace() { #[test] fn cannot_partition_invalid_offset() { - TestExt::new().execute_with(|| { - let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::complete() }; - let record = RegionRecord { end: 4, owner: 1, paid: None }; - Regions::::insert(region_id, &record); - assert_noop!(Broker::do_partition(region_id, None, 5), Error::::PivotTooLate); + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_noop!(Broker::do_partition(region, None, 5), Error::::PivotTooLate); }); } #[test] fn cannot_interlace_invalid_pivot() { - TestExt::new().execute_with(|| { - let region_id = RegionId { begin: 0, core: 0, mask: CoreMask::from_chunk(0, 20) }; - let record = RegionRecord { end: 4, owner: 1, paid: None }; - Regions::::insert(region_id, &record); + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + let (region1, _) = Broker::do_interlace(region, None, CoreMask::from_chunk(0, 20)).unwrap(); assert_noop!( - Broker::do_interlace(region_id, None, CoreMask::from_chunk(20, 40)), + Broker::do_interlace(region1, None, CoreMask::from_chunk(20, 40)), Error::::ExteriorPivot ); assert_noop!( - Broker::do_interlace(region_id, None, CoreMask::void()), + Broker::do_interlace(region1, None, CoreMask::void()), Error::::VoidPivot ); assert_noop!( - Broker::do_interlace(region_id, None, CoreMask::from_chunk(0, 20)), + Broker::do_interlace(region1, None, CoreMask::from_chunk(0, 20)), Error::::CompletePivot ); }); From 3b0bd20ac79a7be6decc3b5fd4c16323e50f7a5d Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:25:54 +0530 Subject: [PATCH 116/131] Adds a test for an edge case --- frame/broker/src/tests.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index c21e7d55f2a89..16932906e0d64 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -854,3 +854,29 @@ fn cannot_interlace_invalid_pivot() { ); }); } + +#[test] +fn assign_should_drop_invalid_region() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let mut region = Broker::do_purchase(1, u64::max_value()).unwrap(); + advance_to(10); + assert_ok!(Broker::do_assign(region, Some(1), 1001, Provisional)); + region.begin = 7; + System::assert_last_event(Event::RegionDropped { region_id: region, duration: 0 }.into()); + }); +} + +#[test] +fn pool_should_drop_invalid_region() { + TestExt::new().endow(1, 1000).execute_with(|| { + assert_ok!(Broker::do_start_sales(100, 1)); + advance_to(2); + let mut region = Broker::do_purchase(1, u64::max_value()).unwrap(); + advance_to(10); + assert_ok!(Broker::do_pool(region, Some(1), 1001, Provisional)); + region.begin = 7; + System::assert_last_event(Event::RegionDropped { region_id: region, duration: 0 }.into()); + }); +} From 8e6072cbb03f8083a5077b14822a4add669304dc Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:43:49 +0530 Subject: [PATCH 117/131] Fixes feature propagation --- frame/broker/Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index 17f73cce52e99..4dc32d4046a7c 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -49,5 +49,7 @@ runtime-benchmarks = [ ] try-runtime = [ - "frame-support/try-runtime" + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime" ] From 8eb3187cfdbbaa4cc7b6bbd607f133083b9cb9dc Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:46:45 +0530 Subject: [PATCH 118/131] Fixes feature propagation --- frame/broker/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index 4dc32d4046a7c..f9e0c4d40206a 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -38,6 +38,7 @@ std = [ "sp-runtime/std", "sp-arithmetic/std", "sp-core/std", + "sp-io/std", "sp-std/std", ] From b863d5d1a473482452865b6ad3662f9fbc3c6edd Mon Sep 17 00:00:00 2001 From: Nikhil Gupta <17176722+gupnik@users.noreply.github.com> Date: Thu, 3 Aug 2023 17:59:15 +0530 Subject: [PATCH 119/131] Adds doc fix --- frame/broker/src/coretime_interface.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 6e69ca66c6f2f..1a9877ef9f0f0 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -47,7 +47,7 @@ pub enum CoreAssignment { /// Type able to accept Coretime scheduling instructions and provide certain usage information. /// Generally implemented by the Relay-chain or some means of communicating with it. /// -/// The trait representation of RFC#5 https://github.com/polkadot-fellows/RFCs/pull/5. +/// The trait representation of RFC#5 ``. pub trait CoretimeInterface { /// A (Relay-chain-side) account ID. type AccountId: Parameter; From fbb570fdd34bea490ec340779baf61ed6c1491fc Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:06:28 +0200 Subject: [PATCH 120/131] Syntax nits Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 10 ++++------ frame/broker/src/tick_impls.rs | 10 ++++------ 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 319d29c6cd00a..49ed0c0cec573 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -331,13 +331,11 @@ impl Pallet { region.begin = r + 1; contribution.length.saturating_dec(); - let mut pool_record = match InstaPoolHistory::::get(r) { - Some(x) => x, - None => continue, + let Some(mut pool_record) = InstaPoolHistory::::get(r) else { + continue; }; - let total_payout = match pool_record.maybe_payout { - Some(x) => x, - None => break, + let Some(total_payout) = pool_record.maybe_payout else { + break; }; let p = total_payout .saturating_mul(contributed_parts.into()) diff --git a/frame/broker/src/tick_impls.rs b/frame/broker/src/tick_impls.rs index abf356f6b83a5..0677d2793e21a 100644 --- a/frame/broker/src/tick_impls.rs +++ b/frame/broker/src/tick_impls.rs @@ -95,9 +95,8 @@ impl Pallet { } pub(crate) fn process_revenue() -> bool { - let (until, amount) = match T::Coretime::check_notify_revenue_info() { - Some(x) => x, - None => return false, + let Some((until, amount)) = T::Coretime::check_notify_revenue_info() else { + return false; }; let when: Timeslice = (until / T::TimeslicePeriod::get()).saturating_sub(One::one()).saturated_into(); @@ -290,9 +289,8 @@ impl Pallet { rc_begin: RelayBlockNumberOf, core: CoreIndex, ) { - let workplan = match Workplan::::take((timeslice, core)) { - Some(w) => w, - None => return, + let Some(workplan) = Workplan::::take((timeslice, core)) else { + return; }; let workload = Workload::::get(core); let parts_used = workplan.iter().map(|i| i.mask).fold(CoreMask::void(), |a, i| a | i); From 0478e09bdd6fcde43e204231ab694d62c938f2d5 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:09:35 +0200 Subject: [PATCH 121/131] Reuse Bit assign functions Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/core_mask.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/frame/broker/src/core_mask.rs b/frame/broker/src/core_mask.rs index f83ed42b455c8..bbd7f6d24b59c 100644 --- a/frame/broker/src/core_mask.rs +++ b/frame/broker/src/core_mask.rs @@ -84,12 +84,9 @@ impl From for u128 { } impl BitAnd for CoreMask { type Output = Self; - fn bitand(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitand(rhs.0[i]); - } - Self(result) + fn bitand(mut self, rhs: Self) -> Self { + self.bitand_assign(rhs); + self } } impl BitAndAssign for CoreMask { @@ -101,12 +98,9 @@ impl BitAndAssign for CoreMask { } impl BitOr for CoreMask { type Output = Self; - fn bitor(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitor(rhs.0[i]); - } - Self(result) + fn bitor(mut self, rhs: Self) -> Self { + self.bitor_assign(rhs); + self } } impl BitOrAssign for CoreMask { @@ -118,12 +112,9 @@ impl BitOrAssign for CoreMask { } impl BitXor for CoreMask { type Output = Self; - fn bitxor(self, rhs: Self) -> Self { - let mut result = [0u8; 10]; - for i in 0..10 { - result[i] = self.0[i].bitxor(rhs.0[i]); - } - Self(result) + fn bitxor(mut self, rhs: Self) -> Self { + self.bitxor_assign(rhs); + self } } impl BitXorAssign for CoreMask { From 7cc753fe7bc5a822c69f5d8b593b3022388bc806 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:19:35 +0200 Subject: [PATCH 122/131] Bitwise tests Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/core_mask.rs | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/frame/broker/src/core_mask.rs b/frame/broker/src/core_mask.rs index bbd7f6d24b59c..b8d045077d828 100644 --- a/frame/broker/src/core_mask.rs +++ b/frame/broker/src/core_mask.rs @@ -179,4 +179,49 @@ mod tests { fn chunk_works() { assert_eq!(CoreMask::from_chunk(40, 60), CoreMask::from(0x00000_00000_fffff_00000),); } + + #[test] + fn bit_or_works() { + assert_eq!( + CoreMask::from(0x02040_a0c0e_d0a0b_0ffff) | CoreMask::from(0x10305_0b0d0_0e0d0_e0000), + CoreMask::from(0x12345_abcde_deadb_effff), + ); + } + + #[test] + fn bit_or_assign_works() { + let mut a = CoreMask::from(0x02040_a0c0e_d0a0b_0ffff); + a |= CoreMask::from(0x10305_0b0d0_0e0d0_e0000); + assert_eq!(a, CoreMask::from(0x12345_abcde_deadb_effff)); + } + + #[test] + fn bit_and_works() { + assert_eq!( + CoreMask::from(0x00000_abcde_deadb_efff0) & CoreMask::from(0x02040_00000_d0a0b_0ff0f), + CoreMask::from(0x00000_00000_d0a0b_0ff00), + ); + } + + #[test] + fn bit_and_assign_works() { + let mut a = CoreMask::from(0x00000_abcde_deadb_efff0); + a &= CoreMask::from(0x02040_00000_d0a0b_0ff0f); + assert_eq!(a, CoreMask::from(0x00000_00000_d0a0b_0ff00)); + } + + #[test] + fn bit_xor_works() { + assert_eq!( + CoreMask::from(0x10010_10010_10010_10010) ^ CoreMask::from(0x01110_01110_01110_01110), + CoreMask::from(0x11100_11100_11100_11100), + ); + } + + #[test] + fn bit_xor_assign_works() { + let mut a = CoreMask::from(0x10010_10010_10010_10010); + a ^= CoreMask::from(0x01110_01110_01110_01110); + assert_eq!(a, CoreMask::from(0x11100_11100_11100_11100)); + } } From 6e2dd79a73519547b952845d13e3519702f2101d Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:31:07 +0200 Subject: [PATCH 123/131] adapt_price: Edge case for sold == target Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/adapt_price.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs index d89154f640005..d1596b7d60cb5 100644 --- a/frame/broker/src/adapt_price.rs +++ b/frame/broker/src/adapt_price.rs @@ -28,7 +28,7 @@ pub trait AdaptPrice { /// performance. /// /// - `sold`: The number of cores sold. - /// - `target`: The target number of cores to be sold. + /// - `target`: The target number of cores to be sold (must be larger than zero). /// - `limit`: The maximum number of cores to be sold. fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64; } @@ -50,7 +50,7 @@ impl AdaptPrice for Linear { FixedU64::from(2) - when } fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64 { - if sold < target { + if sold <= target { FixedU64::from_rational(sold.into(), target.into()) } else { FixedU64::one() + @@ -58,3 +58,25 @@ impl AdaptPrice for Linear { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn linear_no_panic() { + for limit in 0..10 { + for target in 1..10 { + for sold in 0..=limit { + let price = Linear::adapt_price(sold, target, limit); + + if sold > target { + assert!(price > FixedU64::one()); + } else { + assert!(price <= FixedU64::one()); + } + } + } + } + } +} From 94105d30eb890dbc44b83e94b2bed951e4670321 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:42:21 +0200 Subject: [PATCH 124/131] Add sanity checking to ConfigRecord Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 1 + frame/broker/src/lib.rs | 2 ++ frame/broker/src/mock.rs | 24 ++++++++++++++---------- frame/broker/src/tests.rs | 13 +++++++++++++ frame/broker/src/types.rs | 14 ++++++++++++++ 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 49ed0c0cec573..f7664763a4f99 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -26,6 +26,7 @@ use CompletionStatus::{Complete, Partial}; impl Pallet { pub(crate) fn do_configure(config: ConfigRecordOf) -> DispatchResult { + config.validate().map_err(|()| Error::::InvalidConfig)?; Configuration::::put(config); Ok(()) } diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index c262f40a330e7..80a9a061976fe 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -468,6 +468,8 @@ pub mod pallet { UnknownRenewal, /// The lease expiry time has already passed. AlreadyExpired, + /// The configuration could not be applied because it is invalid. + InvalidConfig, } #[pallet::hooks] diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index 6ec37e0e7de80..cab6b7389c064 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -243,20 +243,24 @@ pub fn attribute(nft: RegionId, attribute: impl codec::Encode) >::typed_attribute::<_, T>(&nft.into(), &attribute).unwrap() } +pub fn new_config() -> ConfigRecordOf { + ConfigRecord { + advance_notice: 2, + interlude_length: 1, + leadin_length: 1, + ideal_bulk_proportion: Default::default(), + limit_cores_offered: None, + region_length: 3, + renewal_bump: Perbill::from_percent(10), + contribution_timeout: 5, + } +} + pub struct TestExt(ConfigRecordOf); #[allow(dead_code)] impl TestExt { pub fn new() -> Self { - Self(ConfigRecord { - advance_notice: 2, - interlude_length: 1, - leadin_length: 1, - ideal_bulk_proportion: Default::default(), - limit_cores_offered: None, - region_length: 3, - renewal_bump: Perbill::from_percent(10), - contribution_timeout: 5, - }) + Self(new_config()) } pub fn advance_notice(mut self, advance_notice: Timeslice) -> Self { diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 16932906e0d64..6d575d4bc8c0e 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -23,6 +23,7 @@ use frame_support::{ traits::nonfungible::{Inspect as NftInspect, Transfer}, BoundedVec, }; +use frame_system::RawOrigin::Root; use sp_runtime::traits::Get; use CoreAssignment::*; use CoretimeTraceItem::*; @@ -880,3 +881,15 @@ fn pool_should_drop_invalid_region() { System::assert_last_event(Event::RegionDropped { region_id: region, duration: 0 }.into()); }); } + +#[test] +fn config_works() { + TestExt::new().execute_with(|| { + let mut cfg = new_config(); + // Good config works: + assert_ok!(Broker::configure(Root.into(), cfg.clone())); + // Bad config is a noop: + cfg.leadin_length = 0; + assert_noop!(Broker::configure(Root.into(), cfg), Error::::InvalidConfig); + }); +} diff --git a/frame/broker/src/types.rs b/frame/broker/src/types.rs index e8210b380b1bc..89222ca8e9527 100644 --- a/frame/broker/src/types.rs +++ b/frame/broker/src/types.rs @@ -274,3 +274,17 @@ pub struct ConfigRecord { pub contribution_timeout: Timeslice, } pub type ConfigRecordOf = ConfigRecord, RelayBlockNumberOf>; + +impl ConfigRecord +where + BlockNumber: sp_arithmetic::traits::Zero, +{ + /// Check the config for basic validity constraints. + pub(crate) fn validate(&self) -> Result<(), ()> { + if self.leadin_length.is_zero() { + return Err(()) + } + + Ok(()) + } +} From 6103d1d2d33774fba7dc8d1231e306ac0c1d835d Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:47:42 +0200 Subject: [PATCH 125/131] Add deny(missing_docs) where possible Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/adapt_price.rs | 2 ++ frame/broker/src/coretime_interface.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/frame/broker/src/adapt_price.rs b/frame/broker/src/adapt_price.rs index d1596b7d60cb5..8266625687a23 100644 --- a/frame/broker/src/adapt_price.rs +++ b/frame/broker/src/adapt_price.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![deny(missing_docs)] + use crate::CoreIndex; use sp_arithmetic::{traits::One, FixedU64}; diff --git a/frame/broker/src/coretime_interface.rs b/frame/broker/src/coretime_interface.rs index 1a9877ef9f0f0..fec40b9fdd7b3 100644 --- a/frame/broker/src/coretime_interface.rs +++ b/frame/broker/src/coretime_interface.rs @@ -15,6 +15,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#![deny(missing_docs)] + use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::Parameter; use scale_info::TypeInfo; From a71813d6501c9491f28e4baa47f32cbdee42ecd8 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:54:34 +0200 Subject: [PATCH 126/131] partition: forbid pivot_offset == 0 Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 1 + frame/broker/src/lib.rs | 2 ++ frame/broker/src/tests.rs | 1 + 3 files changed, 4 insertions(+) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index f7664763a4f99..5b3b010ac51b6 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -202,6 +202,7 @@ impl Pallet { } let pivot = region_id.begin.saturating_add(pivot_offset); ensure!(pivot < region.end, Error::::PivotTooLate); + ensure!(pivot > region_id.begin, Error::::PivotTooEarly); region.paid = None; let new_region_ids = (region_id, RegionId { begin: pivot, ..region_id.clone() }); diff --git a/frame/broker/src/lib.rs b/frame/broker/src/lib.rs index 80a9a061976fe..4abd041f5f397 100644 --- a/frame/broker/src/lib.rs +++ b/frame/broker/src/lib.rs @@ -419,6 +419,8 @@ pub mod pallet { NotOwner, /// The pivot point of the partition at or after the end of the region. PivotTooLate, + /// The pivot point of the partition at the beginning of the region. + PivotTooEarly, /// The pivot mask for the interlacing is not contained within the region's interlace mask. ExteriorPivot, /// The pivot mask for the interlacing is void (and therefore unschedulable). diff --git a/frame/broker/src/tests.rs b/frame/broker/src/tests.rs index 6d575d4bc8c0e..3c326010dddfc 100644 --- a/frame/broker/src/tests.rs +++ b/frame/broker/src/tests.rs @@ -830,6 +830,7 @@ fn cannot_partition_invalid_offset() { assert_ok!(Broker::do_start_sales(100, 1)); advance_to(2); let region = Broker::do_purchase(1, u64::max_value()).unwrap(); + assert_noop!(Broker::do_partition(region, None, 0), Error::::PivotTooEarly); assert_noop!(Broker::do_partition(region, None, 5), Error::::PivotTooLate); }); } From 0e4b434623454bb4026d54064aba0180f22d8c0a Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 19:56:36 +0200 Subject: [PATCH 127/131] Sort features zepter format features Signed-off-by: Oliver Tale-Yazdi --- frame/broker/Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frame/broker/Cargo.toml b/frame/broker/Cargo.toml index f9e0c4d40206a..daa2426b2c34a 100644 --- a/frame/broker/Cargo.toml +++ b/frame/broker/Cargo.toml @@ -27,7 +27,7 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys sp-io = { version = "23.0.0", path = "../../primitives/io" } [features] -default = ["std"] +default = [ "std" ] std = [ "codec/std", @@ -35,10 +35,10 @@ std = [ "frame-support/std", "frame-system/std", "scale-info/std", - "sp-runtime/std", "sp-arithmetic/std", "sp-core/std", "sp-io/std", + "sp-runtime/std", "sp-std/std", ] @@ -52,5 +52,5 @@ runtime-benchmarks = [ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", - "sp-runtime/try-runtime" + "sp-runtime/try-runtime", ] From 3df25802296d617c7e6ac7541bc301434d530637 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 20:04:40 +0200 Subject: [PATCH 128/131] Import Zero from new location Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 17b21f596af68..66b2b727014a2 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -29,7 +29,7 @@ use frame_support::{ }, }; use frame_system::{Pallet as System, RawOrigin}; -use sp_arithmetic::Perbill; +use sp_arithmetic::{traits::Zero, Perbill}; use sp_core::Get; use sp_runtime::Saturating; From b6bdc4fa1a773e401a3a539ca4aee6f1b90a2b2e Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 20:23:06 +0200 Subject: [PATCH 129/131] Clippy: remove redundant clone Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/dispatchable_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/dispatchable_impls.rs b/frame/broker/src/dispatchable_impls.rs index 5b3b010ac51b6..7c1d5a786b7cf 100644 --- a/frame/broker/src/dispatchable_impls.rs +++ b/frame/broker/src/dispatchable_impls.rs @@ -205,7 +205,7 @@ impl Pallet { ensure!(pivot > region_id.begin, Error::::PivotTooEarly); region.paid = None; - let new_region_ids = (region_id, RegionId { begin: pivot, ..region_id.clone() }); + let new_region_ids = (region_id, RegionId { begin: pivot, ..region_id }); Regions::::insert(&new_region_ids.0, &RegionRecord { end: pivot, ..region.clone() }); Regions::::insert(&new_region_ids.1, ®ion); From 08bb271946262be6e7c63ed7b096d473cf7676d1 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 20:44:36 +0200 Subject: [PATCH 130/131] try to fix build Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index cab6b7389c064..ac27b5d421d03 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -34,7 +34,7 @@ use sp_runtime::{ traits::{BlakeTwo256, Identity, IdentityLookup}, BuildStorage, Saturating, }; -use sp_std::collections::btree_map::BTreeMap; +use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; type Block = frame_system::mocking::MockBlock; From 7bced00756f420d42afb77dce223170c0b778701 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Thu, 24 Aug 2023 21:02:27 +0200 Subject: [PATCH 131/131] Fix CI Signed-off-by: Oliver Tale-Yazdi --- frame/broker/src/benchmarking.rs | 1 + frame/broker/src/mock.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/broker/src/benchmarking.rs b/frame/broker/src/benchmarking.rs index 66b2b727014a2..663bf2f466cf3 100644 --- a/frame/broker/src/benchmarking.rs +++ b/frame/broker/src/benchmarking.rs @@ -32,6 +32,7 @@ use frame_system::{Pallet as System, RawOrigin}; use sp_arithmetic::{traits::Zero, Perbill}; use sp_core::Get; use sp_runtime::Saturating; +use sp_std::{vec, vec::Vec}; const SEED: u32 = 0; const MAX_CORE_COUNT: u16 = 1_000; diff --git a/frame/broker/src/mock.rs b/frame/broker/src/mock.rs index ac27b5d421d03..cab6b7389c064 100644 --- a/frame/broker/src/mock.rs +++ b/frame/broker/src/mock.rs @@ -34,7 +34,7 @@ use sp_runtime::{ traits::{BlakeTwo256, Identity, IdentityLookup}, BuildStorage, Saturating, }; -use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; +use sp_std::collections::btree_map::BTreeMap; type Block = frame_system::mocking::MockBlock;