Skip to content

Commit

Permalink
Coretime auto-renew (paritytech#4424)
Browse files Browse the repository at this point in the history
This PR adds functionality that allows tasks to enable auto-renewal.
Each task eligible for renewal can enable auto-renewal.

A new storage value is added to track all the cores with auto-renewal
enabled and the associated task running on the core. The `BoundedVec` is
sorted by `CoreIndex` to make disabling auto-renewal more efficient.

Cores are renewed at the start of a new bulk sale. If auto-renewal
fails(e.g. due to the sovereign account of the task not holding
sufficient balance), an event will be emitted, and the renewal will
continue for the other cores.

The two added extrinsics are:
- `enable_auto_renew`: Extrinsic for enabling auto renewal.
- `disable_auto_renew`: Extrinsic for disabling auto renewal.

TODOs:
- [x] Write benchmarks for the newly added extrinsics.

Closes: paritytech#4351

---------

Co-authored-by: Dónal Murray <donalm@seadanda.dev>
  • Loading branch information
2 people authored and dharjeezy committed Aug 27, 2024
1 parent 0625c53 commit 50dce5b
Show file tree
Hide file tree
Showing 15 changed files with 1,078 additions and 207 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

use crate::*;
use crate::{xcm_config::LocationToAccountId, *};
use codec::{Decode, Encode};
use cumulus_pallet_parachain_system::RelaychainDataProvider;
use cumulus_primitives_core::relay_chain;
Expand All @@ -27,12 +27,14 @@ use frame_support::{
},
};
use frame_system::Pallet as System;
use pallet_broker::{CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf};
use pallet_broker::{
CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, TaskId,
};
use parachains_common::{AccountId, Balance};
use rococo_runtime_constants::system_parachain::coretime;
use sp_runtime::traits::AccountIdConversion;
use sp_runtime::traits::{AccountIdConversion, MaybeConvert};
use xcm::latest::prelude::*;
use xcm_executor::traits::TransactAsset;
use xcm_executor::traits::{ConvertLocation, TransactAsset};

pub struct BurnCoretimeRevenue;
impl OnUnbalanced<Credit<AccountId, Balances>> for BurnCoretimeRevenue {
Expand Down Expand Up @@ -263,6 +265,15 @@ impl CoretimeInterface for CoretimeAllocator {
}
}

pub struct SovereignAccountOf;
impl MaybeConvert<TaskId, AccountId> for SovereignAccountOf {
fn maybe_convert(id: TaskId) -> Option<AccountId> {
// Currently all tasks are parachains.
let location = Location::new(1, [Parachain(id)]);
LocationToAccountId::convert_location(&location)
}
}

impl pallet_broker::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
Expand All @@ -275,5 +286,7 @@ impl pallet_broker::Config for Runtime {
type WeightInfo = weights::pallet_broker::WeightInfo<Runtime>;
type PalletId = BrokerPalletId;
type AdminOrigin = EnsureRoot<AccountId>;
type SovereignAccountOf = SovereignAccountOf;
type MaxAutoRenewals = ConstU32<100>;
type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,44 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Broker::SaleInfo` (r:1 w:1)
/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
/// Storage: `Broker::Configuration` (r:1 w:0)
/// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
/// Storage: `Broker::Status` (r:1 w:0)
/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Authorship::Author` (r:1 w:0)
/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `System::Digest` (r:1 w:0)
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Broker::AutoRenewals` (r:1 w:1)
/// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
/// Storage: `Broker::Workplan` (r:0 w:1)
/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
fn enable_auto_renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `914`
// Estimated: `4698`
// Minimum execution time: 51_938_000 picoseconds.
Weight::from_parts(55_025_000, 4698)
.saturating_add(T::DbWeight::get().reads(8_u64))
.saturating_add(T::DbWeight::get().writes(6_u64))
}
/// Storage: `Broker::AutoRenewals` (r:1 w:1)
/// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
fn disable_auto_renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `480`
// Estimated: `1516`
// Minimum execution time: 9_628_000 picoseconds.
Weight::from_parts(10_400_000, 1516)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `PolkadotXcm::SupportedVersion` (r:1 w:0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Cumulus. If not, see <http://www.gnu.org/licenses/>.

use crate::*;
use crate::{xcm_config::LocationToAccountId, *};
use codec::{Decode, Encode};
use cumulus_pallet_parachain_system::RelaychainDataProvider;
use cumulus_primitives_core::relay_chain;
Expand All @@ -28,13 +28,13 @@ use frame_support::{
};
use frame_system::Pallet as System;
use pallet_broker::{
CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, Timeslice,
CoreAssignment, CoreIndex, CoretimeInterface, PartsOf57600, RCBlockNumberOf, TaskId, Timeslice,
};
use parachains_common::{AccountId, Balance};
use sp_runtime::traits::AccountIdConversion;
use sp_runtime::traits::{AccountIdConversion, MaybeConvert};
use westend_runtime_constants::system_parachain::coretime;
use xcm::latest::prelude::*;
use xcm_executor::traits::TransactAsset;
use xcm_executor::traits::{ConvertLocation, TransactAsset};

pub struct BurnCoretimeRevenue;
impl OnUnbalanced<Credit<AccountId, Balances>> for BurnCoretimeRevenue {
Expand Down Expand Up @@ -277,6 +277,15 @@ impl CoretimeInterface for CoretimeAllocator {
}
}

pub struct SovereignAccountOf;
impl MaybeConvert<TaskId, AccountId> for SovereignAccountOf {
fn maybe_convert(id: TaskId) -> Option<AccountId> {
// Currently all tasks are parachains.
let location = Location::new(1, [Parachain(id)]);
LocationToAccountId::convert_location(&location)
}
}

impl pallet_broker::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
Expand All @@ -290,5 +299,7 @@ impl pallet_broker::Config for Runtime {
type WeightInfo = weights::pallet_broker::WeightInfo<Runtime>;
type PalletId = BrokerPalletId;
type AdminOrigin = EnsureRoot<AccountId>;
type SovereignAccountOf = SovereignAccountOf;
type MaxAutoRenewals = ConstU32<20>;
type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,44 @@ impl<T: frame_system::Config> pallet_broker::WeightInfo for WeightInfo<T> {
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Broker::SaleInfo` (r:1 w:1)
/// Proof: `Broker::SaleInfo` (`max_values`: Some(1), `max_size`: Some(57), added: 552, mode: `MaxEncodedLen`)
/// Storage: `Broker::PotentialRenewals` (r:1 w:2)
/// Proof: `Broker::PotentialRenewals` (`max_values`: None, `max_size`: Some(1233), added: 3708, mode: `MaxEncodedLen`)
/// Storage: `Broker::Configuration` (r:1 w:0)
/// Proof: `Broker::Configuration` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
/// Storage: `Broker::Status` (r:1 w:0)
/// Proof: `Broker::Status` (`max_values`: Some(1), `max_size`: Some(18), added: 513, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Authorship::Author` (r:1 w:0)
/// Proof: `Authorship::Author` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `System::Digest` (r:1 w:0)
/// Proof: `System::Digest` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Broker::AutoRenewals` (r:1 w:1)
/// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
/// Storage: `Broker::Workplan` (r:0 w:1)
/// Proof: `Broker::Workplan` (`max_values`: None, `max_size`: Some(1216), added: 3691, mode: `MaxEncodedLen`)
fn enable_auto_renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `914`
// Estimated: `4698`
// Minimum execution time: 51_938_000 picoseconds.
Weight::from_parts(55_025_000, 4698)
.saturating_add(T::DbWeight::get().reads(8_u64))
.saturating_add(T::DbWeight::get().writes(6_u64))
}
/// Storage: `Broker::AutoRenewals` (r:1 w:1)
/// Proof: `Broker::AutoRenewals` (`max_values`: Some(1), `max_size`: Some(31), added: 526, mode: `MaxEncodedLen`)
fn disable_auto_renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `480`
// Estimated: `1516`
// Minimum execution time: 9_628_000 picoseconds.
Weight::from_parts(10_400_000, 1516)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
/// Storage: `System::Account` (r:1 w:0)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn on_new_timeslice() -> Weight {
Expand Down
20 changes: 20 additions & 0 deletions prdoc/pr_4424.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: Coretime auto renewal

doc:
- audience: Runtime User
description: |
With the additions in this PR, any task that utilizes a core that can be auto-renewed
can enable auto-renewal. The renewal is paid from the task's sovereign account.
The two new extrinsics for controlling auto-renewal are `enable_auto_renew` and
`disable_auto_renew`.

crates:
- name: pallet-broker
bump: major
- name: coretime-rococo-runtime
bump: minor
- name: coretime-westend-runtime
bump: minor
16 changes: 14 additions & 2 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ use pallet_nis::WithMaximumOf;
use pallet_session::historical as pallet_session_historical;
// Can't use `FungibleAdapter` here until Treasury pallet migrates to fungibles
// <https://github.com/paritytech/polkadot-sdk/issues/226>
use pallet_broker::TaskId;
#[allow(deprecated)]
pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
Expand All @@ -97,8 +98,8 @@ use sp_runtime::{
curve::PiecewiseLinear,
generic, impl_opaque_keys,
traits::{
self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, NumberFor,
OpaqueKeys, SaturatedConversion, StaticLookup,
self, AccountIdConversion, BlakeTwo256, Block as BlockT, Bounded, ConvertInto,
MaybeConvert, NumberFor, OpaqueKeys, SaturatedConversion, StaticLookup,
},
transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedPointNumber, FixedU128, Perbill, Percent, Permill, Perquintill,
Expand Down Expand Up @@ -2115,6 +2116,15 @@ impl CoretimeInterface for CoretimeProvider {
}
}

pub struct SovereignAccountOf;
// Dummy implementation which converts `TaskId` to `AccountId`.
impl MaybeConvert<TaskId, AccountId> for SovereignAccountOf {
fn maybe_convert(task: TaskId) -> Option<AccountId> {
let mut account: [u8; 32] = [0; 32];
account[..4].copy_from_slice(&task.to_le_bytes());
Some(account.into())
}
}
impl pallet_broker::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
Expand All @@ -2127,6 +2137,8 @@ impl pallet_broker::Config for Runtime {
type WeightInfo = ();
type PalletId = BrokerPalletId;
type AdminOrigin = EnsureRoot<AccountId>;
type SovereignAccountOf = SovereignAccountOf;
type MaxAutoRenewals = ConstU32<10>;
type PriceAdapter = pallet_broker::CenterTargetPrice<Balance>;
}

Expand Down
Loading

0 comments on commit 50dce5b

Please sign in to comment.