referrerpolicy=no-referrer-when-downgrade

polkadot_runtime_parachains/
lib.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Runtime modules for parachains code.
18//!
19//! It is crucial to include all the modules from this crate in the runtime, in
20//! particular the `Initializer` module, as it is responsible for initializing the state
21//! of the other modules.
22
23#![cfg_attr(feature = "runtime-benchmarks", recursion_limit = "256")]
24#![cfg_attr(not(feature = "std"), no_std)]
25
26pub mod assigner_coretime;
27pub mod configuration;
28pub mod coretime;
29pub mod disputes;
30pub mod dmp;
31pub mod hrmp;
32pub mod inclusion;
33pub mod initializer;
34pub mod metrics;
35pub mod on_demand;
36pub mod origin;
37pub mod paras;
38pub mod paras_inherent;
39pub mod reward_points;
40pub mod scheduler;
41pub mod session_info;
42pub mod shared;
43
44pub mod runtime_api_impl;
45
46mod util;
47
48#[cfg(any(feature = "runtime-benchmarks", test))]
49mod builder;
50#[cfg(test)]
51mod mock;
52#[cfg(test)]
53mod ump_tests;
54
55extern crate alloc;
56
57pub use origin::{ensure_parachain, Origin};
58pub use paras::{ParaLifecycle, UpgradeStrategy};
59use polkadot_primitives::{HeadData, Id as ParaId, ValidationCode};
60use sp_arithmetic::traits::Saturating;
61use sp_runtime::{traits::Get, DispatchResult, FixedU128};
62
63/// Trait for tracking message delivery fees on a transport protocol.
64pub trait FeeTracker {
65	/// Type used for assigning different fee factors to different destinations
66	type Id: Copy;
67
68	/// Minimal delivery fee factor.
69	const MIN_FEE_FACTOR: FixedU128 = FixedU128::from_u32(1);
70	/// The factor that is used to increase the current message fee factor when the transport
71	/// protocol is experiencing some lags.
72	const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05
73	/// The factor that is used to increase the current message fee factor for every sent kilobyte.
74	const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001
75
76	/// Returns the current message fee factor.
77	fn get_fee_factor(id: Self::Id) -> FixedU128;
78
79	/// Sets the current message fee factor.
80	fn set_fee_factor(id: Self::Id, val: FixedU128);
81
82	fn do_increase_fee_factor(fee_factor: &mut FixedU128, message_size: u128) {
83		let message_size_factor = FixedU128::from(message_size.saturating_div(1024))
84			.saturating_mul(Self::MESSAGE_SIZE_FEE_BASE);
85		*fee_factor = fee_factor
86			.saturating_mul(Self::EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor));
87	}
88
89	/// Increases the delivery fee factor by a factor based on message size and records the result.
90	fn increase_fee_factor(id: Self::Id, message_size: u128) {
91		let mut fee_factor = Self::get_fee_factor(id);
92		Self::do_increase_fee_factor(&mut fee_factor, message_size);
93		Self::set_fee_factor(id, fee_factor);
94	}
95
96	fn do_decrease_fee_factor(fee_factor: &mut FixedU128) -> bool {
97		const { assert!(Self::EXPONENTIAL_FEE_BASE.into_inner() >= FixedU128::from_u32(1).into_inner()) }
98
99		if *fee_factor == Self::MIN_FEE_FACTOR {
100			return false;
101		}
102
103		// This should never lead to a panic because of the static assert above.
104		*fee_factor = Self::MIN_FEE_FACTOR.max(*fee_factor / Self::EXPONENTIAL_FEE_BASE);
105		true
106	}
107
108	/// Decreases the delivery fee factor by a constant factor and records the result.
109	///
110	/// Does not reduce the fee factor below the initial value, which is currently set as 1.
111	///
112	/// Returns `true` if the fee factor was actually decreased, `false` otherwise.
113	fn decrease_fee_factor(id: Self::Id) -> bool {
114		let mut fee_factor = Self::get_fee_factor(id);
115		let res = Self::do_decrease_fee_factor(&mut fee_factor);
116		Self::set_fee_factor(id, fee_factor);
117		res
118	}
119}
120
121/// Helper struct used for accessing `FeeTracker::MIN_FEE_FACTOR`
122pub struct GetMinFeeFactor<T>(core::marker::PhantomData<T>);
123
124impl<T: FeeTracker> Get<FixedU128> for GetMinFeeFactor<T> {
125	fn get() -> FixedU128 {
126		T::MIN_FEE_FACTOR
127	}
128}
129
130/// Schedule a para to be initialized at the start of the next session with the given genesis data.
131pub fn schedule_para_initialize<T: paras::Config>(
132	id: ParaId,
133	genesis: paras::ParaGenesisArgs,
134) -> Result<(), ()> {
135	paras::Pallet::<T>::schedule_para_initialize(id, genesis).map_err(|_| ())
136}
137
138/// Schedule a para to be cleaned up at the start of the next session.
139pub fn schedule_para_cleanup<T: paras::Config>(id: polkadot_primitives::Id) -> Result<(), ()> {
140	paras::Pallet::<T>::schedule_para_cleanup(id).map_err(|_| ())
141}
142
143/// Schedule a parathread (on-demand parachain) to be upgraded to a lease holding parachain.
144pub fn schedule_parathread_upgrade<T: paras::Config>(id: ParaId) -> Result<(), ()> {
145	paras::Pallet::<T>::schedule_parathread_upgrade(id).map_err(|_| ())
146}
147
148/// Schedule a lease holding parachain to be downgraded to an on-demand parachain.
149pub fn schedule_parachain_downgrade<T: paras::Config>(id: ParaId) -> Result<(), ()> {
150	paras::Pallet::<T>::schedule_parachain_downgrade(id).map_err(|_| ())
151}
152
153/// Schedules a validation code upgrade to a parachain with the given id.
154pub fn schedule_code_upgrade<T: paras::Config>(
155	id: ParaId,
156	new_code: ValidationCode,
157	set_go_ahead: UpgradeStrategy,
158) -> DispatchResult {
159	paras::Pallet::<T>::schedule_code_upgrade_external(id, new_code, set_go_ahead)
160}
161
162/// Sets the current parachain head with the given id.
163pub fn set_current_head<T: paras::Config>(id: ParaId, new_head: HeadData) {
164	paras::Pallet::<T>::set_current_head(id, new_head)
165}
166
167/// Ensure more initialization for `ParaId` when benchmarking. (e.g. open HRMP channels, ...)
168#[cfg(feature = "runtime-benchmarks")]
169pub trait EnsureForParachain {
170	fn ensure(para_id: ParaId);
171}
172
173#[cfg(feature = "runtime-benchmarks")]
174#[impl_trait_for_tuples::impl_for_tuples(30)]
175impl EnsureForParachain for Tuple {
176	fn ensure(para: ParaId) {
177		for_tuples!( #(
178			Tuple::ensure(para);
179		)* );
180	}
181}