referrerpolicy=no-referrer-when-downgrade

pallet_on_demand_para/
types.rs

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//! Types used by this pallet.
19
20use crate::{
21	Config, Error, RelayBlockNumberOf, DEFAULT_BASE_FEE, DEFAULT_DRAIN_RATE_PER_BLOCK,
22	DEFAULT_ORDER_CAP, DEFAULT_PRICE_STEP,
23};
24use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
25use fp_coretime::TaskId;
26use frame_support::{
27	pallet_prelude::*,
28	traits::{fungible::Inspect, tokens::Balance},
29};
30use frame_system::Config as SConfig;
31use scale_info::TypeInfo;
32use sp_arithmetic::{
33	traits::{ensure_pow, One, Saturating},
34	FixedPointNumber, FixedU128, Perbill,
35};
36use sp_runtime::DispatchError;
37
38pub type BalanceOf<T> = <<T as Config>::Currency as Inspect<<T as SConfig>::AccountId>>::Balance;
39
40/// The parameters used for pricing on-demand orders.
41#[derive(
42	Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen,
43)]
44pub struct PriceParameters<Balance> {
45	/// The maximum number of outstanding orders beyond which we reject new orders.
46	pub order_cap: u32,
47	/// The number of outstanding orders assumed to be drained per Relay-chain block, per pool
48	/// core.
49	pub drain_rate_per_block: u32,
50	/// The spot price increase per outstanding order in the queue.
51	pub price_step: Perbill,
52	/// The base spot price when the queue is empty.
53	pub base_fee: Balance,
54}
55
56impl<T> Default for PriceParameters<T>
57where
58	T: From<u32>,
59{
60	fn default() -> Self {
61		Self {
62			order_cap: DEFAULT_ORDER_CAP,
63			drain_rate_per_block: DEFAULT_DRAIN_RATE_PER_BLOCK,
64			price_step: Perbill::from_percent(DEFAULT_PRICE_STEP),
65			base_fee: T::from(DEFAULT_BASE_FEE),
66		}
67	}
68}
69
70impl<Balance> PriceParameters<Balance> {
71	pub(crate) fn validate<T>(&self) -> Result<(), Error<T>>
72	where
73		T: Config,
74		T::Currency: Inspect<<T as SConfig>::AccountId, Balance = Balance>,
75		Balance: frame_support::traits::tokens::Balance,
76	{
77		ensure!(
78			T::PricingProvider::spot_price(self, self.order_cap).is_ok(),
79			Error::<T>::OrderPriceCanOverflow
80		);
81		Ok(())
82	}
83}
84
85pub type PriceParametersOf<T> = PriceParameters<BalanceOf<T>>;
86
87/// Data about a placed on-demand order.
88#[derive(
89	Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen,
90)]
91pub struct EnqueuedOrder<RelayBlockNumber> {
92	/// The parachain the order was placed for.
93	pub para_id: TaskId,
94	/// The Relay-chain block number the order came in at.
95	pub ordered_at: RelayBlockNumber,
96}
97
98/// The locally tracked, estimated state of the Relay chain's on-demand order queue.
99#[derive(
100	Encode, Decode, DecodeWithMemTracking, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen,
101)]
102pub struct QueueTracker<RelayBlockNumber> {
103	/// The current estimated number of outstanding orders.
104	pub outstanding_orders: u32,
105	/// When the queue state was last updated.
106	pub last_updated: RelayBlockNumber,
107}
108
109pub type QueueTrackerOf<T> = QueueTracker<RelayBlockNumberOf<T>>;
110
111/// Type for getting information about the on-demand pool capacity.
112pub trait PoolCapacityProvider {
113	/// Returns how many cores are dedicated to the on-demand pool.
114	fn pool_cores() -> u32;
115}
116
117/// Type for determining the prices of on-demand orders
118pub trait PricingProvider<T: Balance> {
119	/// Returns the current spot price of an on-demand order.
120	fn spot_price(price_config: &PriceParameters<T>, queue_depth: u32) -> Result<T, DispatchError>;
121}
122
123/// A type implementing the default algorithm for determining the order price.
124pub struct DefaultPricingProvider;
125
126impl<T: Balance> PricingProvider<T> for DefaultPricingProvider {
127	fn spot_price(price_config: &PriceParameters<T>, queue_depth: u32) -> Result<T, DispatchError> {
128		// Every order already outstanding raises the price by `price_step`.
129		let price_adjustment = ensure_pow(
130			FixedU128::one().saturating_add(FixedU128::from_perbill(price_config.price_step)),
131			queue_depth as usize,
132		)?;
133		Ok(price_adjustment.saturating_mul_int(price_config.base_fee))
134	}
135}