Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 46c78d5

Browse files
gavofyorkgupnikggwpez
authored
Frame: Agile Coretime Broker pallet (RFC-1) (#14568)
* Add Broker pallet * Flesh out CorePart * Repotting and fleshing out * more drafting * process timeslice * Test Fungibles completed * Auctions * Price morphing * First tests * Tidying up config/status * Docs * Timeslice todying * More Timeslice tidying * Tests] * Repotting. * Tests * Tests * System InstaPool cores and payout * Better Relay Test framework * Tests and instapool fixes * Support NFT interface * Proper renewals * Better events, results * Test transfer * Renewal test * Repot some impls and make dispatchables. * Better weight * Test migration * Document events * Introduce durations * Core count * Allow reassignment * Better naming * Error docs * Docs * Formatting * Advance notice period is in RC blocks, not timeslices * Docs * Formatting * Docs * Missing file * Added some events * Events for all dispatchables * Remove benchmark * Fix * Adds benchmark for configure and some basic setup * Adds benchmark for reserve and unreserve * Adds a couple of more benchmarks * Docs * Event * Fix * Adds benchmark for purchase * Dedup * Add some weight breakdowns * Repotting * Adds more benchmarks * Renaming and one more event * Sale event * Better price API and docs * Avoid possibility of clobbering renewal record * Avoid possibility of clobbering renewal record * Fixes a few benchmarks * Another test * More tests * Drop history test * Rename and CORE_MASK_BITS constant * Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/broker/src/utility_impls.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/broker/src/dispatchable_impls.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Update frame/broker/src/mock.rs Co-authored-by: Oliver Tale-Yazdi <[email protected]> * Addresses few review comments * Addresses few review comments * Addresses few review comments * Merge * Merge * ".git/.scripts/commands/fmt/fmt.sh" * Integrates broker in kitchensink * Minor update * Fixes typo * Moves balance back to u64 * Fixes kitchensink build * Fixes worst case for assign * Adds benchmark for process_core_count * Adds a couple of more benchmarks * Adds an assert for partition * Uses max_timeslices as input in claim_revenue benchmark * Adds benchmark for drop_renewal * Adds benchmark for process_core_schedule * Adds benchmark for process_pool * Adds assertion for transfer * Fixes benchmark for broker in kitchensink * Adds todo for process_revenue benchmark * Minor update * Fix for pool revenue history * remove TODOs * Fix tests * Document CoretimeInterface * rename part to mask * Fixes * Grumble * ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_broker * Adds benchmark for drop_history and fixes worst case for claim_revenue * Adds drop_history in WeightInfo * ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_broker * Minor fix for Quick Benchmark CI * Fixes * Docs * Headers * 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 * Cap renewal price * Adds a few tests * Adds more tests * Minor updates * Adds a test for an edge case * Fixes feature propagation * Fixes feature propagation * Adds doc fix * Syntax nits Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Reuse Bit assign functions Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Bitwise tests Signed-off-by: Oliver Tale-Yazdi <[email protected]> * adapt_price: Edge case for sold == target Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Add sanity checking to ConfigRecord Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Add deny(missing_docs) where possible Signed-off-by: Oliver Tale-Yazdi <[email protected]> * partition: forbid pivot_offset == 0 Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Sort features zepter format features Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Import Zero from new location Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Clippy: remove redundant clone Signed-off-by: Oliver Tale-Yazdi <[email protected]> * try to fix build Signed-off-by: Oliver Tale-Yazdi <[email protected]> * Fix CI Signed-off-by: Oliver Tale-Yazdi <[email protected]> --------- Signed-off-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: Nikhil Gupta <[email protected]> Co-authored-by: Oliver Tale-Yazdi <[email protected]> Co-authored-by: command-bot <>
1 parent 2fe6bc9 commit 46c78d5

File tree

29 files changed

+5884
-18
lines changed

29 files changed

+5884
-18
lines changed

Diff for: Cargo.lock

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ members = [
131131
"frame/benchmarking",
132132
"frame/benchmarking/pov",
133133
"frame/bounties",
134+
"frame/broker",
134135
"frame/child-bounties",
135136
"frame/collective",
136137
"frame/contracts",

Diff for: bin/node/runtime/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pallet-babe = { version = "4.0.0-dev", default-features = false, path = "../../.
6767
pallet-bags-list = { version = "4.0.0-dev", default-features = false, path = "../../../frame/bags-list" }
6868
pallet-balances = { version = "4.0.0-dev", default-features = false, path = "../../../frame/balances" }
6969
pallet-bounties = { version = "4.0.0-dev", default-features = false, path = "../../../frame/bounties" }
70+
pallet-broker = { version = "0.1.0", default-features = false, path = "../../../frame/broker" }
7071
pallet-child-bounties = { version = "4.0.0-dev", default-features = false, path = "../../../frame/child-bounties" }
7172
pallet-collective = { version = "4.0.0-dev", default-features = false, path = "../../../frame/collective" }
7273
pallet-contracts = { version = "4.0.0-dev", default-features = false, path = "../../../frame/contracts" }
@@ -160,6 +161,7 @@ std = [
160161
"pallet-bags-list/std",
161162
"pallet-balances/std",
162163
"pallet-bounties/std",
164+
"pallet-broker/std",
163165
"pallet-child-bounties/std",
164166
"pallet-collective/std",
165167
"pallet-contracts-primitives/std",
@@ -254,6 +256,7 @@ runtime-benchmarks = [
254256
"pallet-bags-list/runtime-benchmarks",
255257
"pallet-balances/runtime-benchmarks",
256258
"pallet-bounties/runtime-benchmarks",
259+
"pallet-broker/runtime-benchmarks",
257260
"pallet-child-bounties/runtime-benchmarks",
258261
"pallet-collective/runtime-benchmarks",
259262
"pallet-contracts/runtime-benchmarks",
@@ -324,6 +327,7 @@ try-runtime = [
324327
"pallet-bags-list/try-runtime",
325328
"pallet-balances/try-runtime",
326329
"pallet-bounties/try-runtime",
330+
"pallet-broker/try-runtime",
327331
"pallet-child-bounties/try-runtime",
328332
"pallet-collective/try-runtime",
329333
"pallet-contracts/try-runtime",

Diff for: bin/node/runtime/src/lib.rs

+75-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use frame_support::{
3535
pallet_prelude::Get,
3636
parameter_types,
3737
traits::{
38-
fungible::ItemOf,
38+
fungible::{Balanced, Credit, ItemOf},
3939
tokens::{nonfungibles_v2::Inspect, GetSalary, PayFromAccount},
4040
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse,
4141
EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem,
@@ -56,6 +56,7 @@ use frame_system::{
5656
pub use node_primitives::{AccountId, Signature};
5757
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Moment, Nonce};
5858
use pallet_asset_conversion::{NativeOrAssetId, NativeOrAssetIdConverter};
59+
use pallet_broker::{CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600};
5960
use pallet_election_provider_multi_phase::SolutionAccuracyOf;
6061
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
6162
use pallet_nfts::PalletFeatures;
@@ -1877,6 +1878,77 @@ impl pallet_statement::Config for Runtime {
18771878
type MaxAllowedBytes = MaxAllowedBytes;
18781879
}
18791880

1881+
parameter_types! {
1882+
pub const BrokerPalletId: PalletId = PalletId(*b"py/broke");
1883+
}
1884+
1885+
pub struct IntoAuthor;
1886+
impl OnUnbalanced<Credit<AccountId, Balances>> for IntoAuthor {
1887+
fn on_nonzero_unbalanced(credit: Credit<AccountId, Balances>) {
1888+
if let Some(author) = Authorship::author() {
1889+
let _ = <Balances as Balanced<_>>::resolve(&author, credit);
1890+
}
1891+
}
1892+
}
1893+
1894+
parameter_types! {
1895+
pub storage CoreCount: Option<CoreIndex> = None;
1896+
pub storage CoretimeRevenue: Option<(BlockNumber, Balance)> = None;
1897+
}
1898+
1899+
pub struct CoretimeProvider;
1900+
impl CoretimeInterface for CoretimeProvider {
1901+
type AccountId = AccountId;
1902+
type Balance = Balance;
1903+
type BlockNumber = BlockNumber;
1904+
fn latest() -> Self::BlockNumber {
1905+
System::block_number()
1906+
}
1907+
fn request_core_count(_count: CoreIndex) {}
1908+
fn request_revenue_info_at(_when: Self::BlockNumber) {}
1909+
fn credit_account(_who: Self::AccountId, _amount: Self::Balance) {}
1910+
fn assign_core(
1911+
_core: CoreIndex,
1912+
_begin: Self::BlockNumber,
1913+
_assignment: Vec<(CoreAssignment, PartsOf57600)>,
1914+
_end_hint: Option<Self::BlockNumber>,
1915+
) {
1916+
}
1917+
fn check_notify_core_count() -> Option<u16> {
1918+
let count = CoreCount::get();
1919+
CoreCount::set(&None);
1920+
count
1921+
}
1922+
fn check_notify_revenue_info() -> Option<(Self::BlockNumber, Self::Balance)> {
1923+
let revenue = CoretimeRevenue::get();
1924+
CoretimeRevenue::set(&None);
1925+
revenue
1926+
}
1927+
#[cfg(feature = "runtime-benchmarks")]
1928+
fn ensure_notify_core_count(count: u16) {
1929+
CoreCount::set(&Some(count));
1930+
}
1931+
#[cfg(feature = "runtime-benchmarks")]
1932+
fn ensure_notify_revenue_info(when: Self::BlockNumber, revenue: Self::Balance) {
1933+
CoretimeRevenue::set(&Some((when, revenue)));
1934+
}
1935+
}
1936+
1937+
impl pallet_broker::Config for Runtime {
1938+
type RuntimeEvent = RuntimeEvent;
1939+
type Currency = Balances;
1940+
type OnRevenue = IntoAuthor;
1941+
type TimeslicePeriod = ConstU32<2>;
1942+
type MaxLeasedCores = ConstU32<5>;
1943+
type MaxReservedCores = ConstU32<5>;
1944+
type Coretime = CoretimeProvider;
1945+
type ConvertBalance = traits::Identity;
1946+
type WeightInfo = ();
1947+
type PalletId = BrokerPalletId;
1948+
type AdminOrigin = EnsureRoot<AccountId>;
1949+
type PriceAdapter = pallet_broker::Linear;
1950+
}
1951+
18801952
construct_runtime!(
18811953
pub struct Runtime
18821954
{
@@ -1950,6 +2022,7 @@ construct_runtime!(
19502022
MessageQueue: pallet_message_queue,
19512023
Pov: frame_benchmarking_pallet_pov,
19522024
Statement: pallet_statement,
2025+
Broker: pallet_broker,
19532026
}
19542027
);
19552028

@@ -2030,6 +2103,7 @@ mod benches {
20302103
[pallet_bags_list, VoterList]
20312104
[pallet_balances, Balances]
20322105
[pallet_bounties, Bounties]
2106+
[pallet_broker, Broker]
20332107
[pallet_child_bounties, ChildBounties]
20342108
[pallet_collective, Council]
20352109
[pallet_conviction_voting, ConvictionVoting]

Diff for: client/consensus/grandpa/src/communication/gossip.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,7 @@ impl<N: Ord> Peers<N> {
546546
who: &PeerId,
547547
update: NeighborPacket<N>,
548548
) -> Result<Option<&View<N>>, Misbehavior> {
549-
let Some(peer) = self.inner.get_mut(who) else {
550-
return Ok(None)
551-
};
549+
let Some(peer) = self.inner.get_mut(who) else { return Ok(None) };
552550

553551
let invalid_change = peer.view.set_id > update.set_id ||
554552
peer.view.round > update.round && peer.view.set_id == update.set_id ||

Diff for: frame/broker/Cargo.toml

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[package]
2+
name = "pallet-broker"
3+
version = "0.1.0"
4+
description = "Brokerage tool for managing Polkadot Core scheduling"
5+
authors = ["Parity Technologies <[email protected]>"]
6+
homepage = "https://substrate.io"
7+
edition = "2021"
8+
license = "Apache-2.0"
9+
repository = "https://github.com/paritytech/substrate"
10+
11+
[package.metadata.docs.rs]
12+
targets = ["x86_64-unknown-linux-gnu"]
13+
14+
[dependencies]
15+
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ "derive"] }
16+
scale-info = { version = "2.0.0", default-features = false, features = ["derive"] }
17+
bitvec = "1"
18+
sp-std = { version = "8.0.0", default-features = false, path = "../../primitives/std" }
19+
sp-arithmetic = { version = "16.0.0", default-features = false, path = "../../primitives/arithmetic" }
20+
sp-core = { version = "21.0.0", default-features = false, path = "../../primitives/core" }
21+
sp-runtime = { version = "24.0.0", default-features = false, path = "../../primitives/runtime" }
22+
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" }
23+
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
24+
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
25+
26+
[dev-dependencies]
27+
sp-io = { version = "23.0.0", path = "../../primitives/io" }
28+
29+
[features]
30+
default = [ "std" ]
31+
32+
std = [
33+
"codec/std",
34+
"frame-benchmarking?/std",
35+
"frame-support/std",
36+
"frame-system/std",
37+
"scale-info/std",
38+
"sp-arithmetic/std",
39+
"sp-core/std",
40+
"sp-io/std",
41+
"sp-runtime/std",
42+
"sp-std/std",
43+
]
44+
45+
runtime-benchmarks = [
46+
"frame-benchmarking/runtime-benchmarks",
47+
"frame-support/runtime-benchmarks",
48+
"frame-system/runtime-benchmarks",
49+
"sp-runtime/runtime-benchmarks",
50+
]
51+
52+
try-runtime = [
53+
"frame-support/try-runtime",
54+
"frame-system/try-runtime",
55+
"sp-runtime/try-runtime",
56+
]

Diff for: frame/broker/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Pallet Broker
2+
3+
Brokerage tool for managing Polkadot Core scheduling.
4+
5+
Properly described in RFC-0001 Agile Coretime.
6+
7+
## Implemnentation Specifics
8+
9+
### Core Mask Bits
10+
11+
This is 1/80th of a Polkadot Core per timeslice. Assuming timeslices are 80 blocks, then this
12+
indicates usage of a single core one time over a timeslice.
13+
14+
### The Sale
15+
16+
```nocompile
17+
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2
18+
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
19+
--------------------------------------------------------
20+
< interlude >
21+
< sale >
22+
... of which ...
23+
< descending-price >< fixed-price >
24+
| <-------\
25+
price fixed, unsold assigned to instapool, system cores reserved -/
26+
```

Diff for: frame/broker/src/adapt_price.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
#![deny(missing_docs)]
19+
20+
use crate::CoreIndex;
21+
use sp_arithmetic::{traits::One, FixedU64};
22+
23+
/// Type for determining how to set price.
24+
pub trait AdaptPrice {
25+
/// Return the factor by which the regular price must be multiplied during the leadin period.
26+
///
27+
/// - `when`: The amount through the leadin period; between zero and one.
28+
fn leadin_factor_at(when: FixedU64) -> FixedU64;
29+
/// Return the correction factor by which the regular price must be multiplied based on market
30+
/// performance.
31+
///
32+
/// - `sold`: The number of cores sold.
33+
/// - `target`: The target number of cores to be sold (must be larger than zero).
34+
/// - `limit`: The maximum number of cores to be sold.
35+
fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64;
36+
}
37+
38+
impl AdaptPrice for () {
39+
fn leadin_factor_at(_: FixedU64) -> FixedU64 {
40+
FixedU64::one()
41+
}
42+
fn adapt_price(_: CoreIndex, _: CoreIndex, _: CoreIndex) -> FixedU64 {
43+
FixedU64::one()
44+
}
45+
}
46+
47+
/// Simple implementation of `AdaptPrice` giving a monotonic leadin and a linear price change based
48+
/// on cores sold.
49+
pub struct Linear;
50+
impl AdaptPrice for Linear {
51+
fn leadin_factor_at(when: FixedU64) -> FixedU64 {
52+
FixedU64::from(2) - when
53+
}
54+
fn adapt_price(sold: CoreIndex, target: CoreIndex, limit: CoreIndex) -> FixedU64 {
55+
if sold <= target {
56+
FixedU64::from_rational(sold.into(), target.into())
57+
} else {
58+
FixedU64::one() +
59+
FixedU64::from_rational((sold - target).into(), (limit - target).into())
60+
}
61+
}
62+
}
63+
64+
#[cfg(test)]
65+
mod tests {
66+
use super::*;
67+
68+
#[test]
69+
fn linear_no_panic() {
70+
for limit in 0..10 {
71+
for target in 1..10 {
72+
for sold in 0..=limit {
73+
let price = Linear::adapt_price(sold, target, limit);
74+
75+
if sold > target {
76+
assert!(price > FixedU64::one());
77+
} else {
78+
assert!(price <= FixedU64::one());
79+
}
80+
}
81+
}
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)