// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// This file is part of Pezkuwi.
// Pezkuwi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Pezkuwi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Pezkuwi. If not, see .
//! Runtime modules for teyrchains code.
//!
//! It is crucial to include all the modules from this crate in the runtime, in
//! particular the `Initializer` module, as it is responsible for initializing the state
//! of the other modules.
#![cfg_attr(feature = "runtime-benchmarks", recursion_limit = "256")]
#![cfg_attr(not(feature = "std"), no_std)]
pub mod assigner_coretime;
pub mod configuration;
pub mod coretime;
pub mod disputes;
pub mod dmp;
pub mod hrmp;
pub mod inclusion;
pub mod initializer;
pub mod metrics;
pub mod on_demand;
pub mod origin;
pub mod paras;
pub mod paras_inherent;
pub mod reward_points;
pub mod scheduler;
pub mod session_info;
pub mod shared;
pub mod runtime_api_impl;
mod util;
#[cfg(any(feature = "runtime-benchmarks", test))]
mod builder;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod ump_tests;
extern crate alloc;
pub use origin::{ensure_teyrchain, Origin};
pub use paras::{ParaLifecycle, UpgradeStrategy};
use pezkuwi_primitives::{HeadData, Id as ParaId, ValidationCode};
use pezsp_arithmetic::traits::Saturating;
use pezsp_runtime::{traits::Get, DispatchResult, FixedU128};
/// Trait for tracking message delivery fees on a transport protocol.
pub trait FeeTracker {
/// Type used for assigning different fee factors to different destinations
type Id: Copy;
/// Minimal delivery fee factor.
const MIN_FEE_FACTOR: FixedU128 = FixedU128::from_u32(1);
/// The factor that is used to increase the current message fee factor when the transport
/// protocol is experiencing some lags.
const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05
/// The factor that is used to increase the current message fee factor for every sent kilobyte.
const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001
/// Returns the current message fee factor.
fn get_fee_factor(id: Self::Id) -> FixedU128;
/// Sets the current message fee factor.
fn set_fee_factor(id: Self::Id, val: FixedU128);
fn do_increase_fee_factor(fee_factor: &mut FixedU128, message_size: u128) {
let message_size_factor = FixedU128::from(message_size.saturating_div(1024))
.saturating_mul(Self::MESSAGE_SIZE_FEE_BASE);
*fee_factor = fee_factor
.saturating_mul(Self::EXPONENTIAL_FEE_BASE.saturating_add(message_size_factor));
}
/// Increases the delivery fee factor by a factor based on message size and records the result.
fn increase_fee_factor(id: Self::Id, message_size: u128) {
let mut fee_factor = Self::get_fee_factor(id);
Self::do_increase_fee_factor(&mut fee_factor, message_size);
Self::set_fee_factor(id, fee_factor);
}
fn do_decrease_fee_factor(fee_factor: &mut FixedU128) -> bool {
const { assert!(Self::EXPONENTIAL_FEE_BASE.into_inner() >= FixedU128::from_u32(1).into_inner()) }
if *fee_factor == Self::MIN_FEE_FACTOR {
return false;
}
// This should never lead to a panic because of the static assert above.
*fee_factor = Self::MIN_FEE_FACTOR.max(*fee_factor / Self::EXPONENTIAL_FEE_BASE);
true
}
/// Decreases the delivery fee factor by a constant factor and records the result.
///
/// Does not reduce the fee factor below the initial value, which is currently set as 1.
///
/// Returns `true` if the fee factor was actually decreased, `false` otherwise.
fn decrease_fee_factor(id: Self::Id) -> bool {
let mut fee_factor = Self::get_fee_factor(id);
let res = Self::do_decrease_fee_factor(&mut fee_factor);
Self::set_fee_factor(id, fee_factor);
res
}
}
/// Helper struct used for accessing `FeeTracker::MIN_FEE_FACTOR`
pub struct GetMinFeeFactor(core::marker::PhantomData);
impl Get for GetMinFeeFactor {
fn get() -> FixedU128 {
T::MIN_FEE_FACTOR
}
}
/// Schedule a para to be initialized at the start of the next session with the given genesis data.
pub fn schedule_para_initialize(
id: ParaId,
genesis: paras::ParaGenesisArgs,
) -> Result<(), ()> {
paras::Pezpallet::::schedule_para_initialize(id, genesis).map_err(|_| ())
}
/// Schedule a para to be cleaned up at the start of the next session.
pub fn schedule_para_cleanup(id: pezkuwi_primitives::Id) -> Result<(), ()> {
paras::Pezpallet::::schedule_para_cleanup(id).map_err(|_| ())
}
/// Schedule a parathread (on-demand teyrchain) to be upgraded to a lease holding teyrchain.
pub fn schedule_parathread_upgrade(id: ParaId) -> Result<(), ()> {
paras::Pezpallet::::schedule_parathread_upgrade(id).map_err(|_| ())
}
/// Schedule a lease holding teyrchain to be downgraded to an on-demand teyrchain.
pub fn schedule_teyrchain_downgrade(id: ParaId) -> Result<(), ()> {
paras::Pezpallet::::schedule_teyrchain_downgrade(id).map_err(|_| ())
}
/// Schedules a validation code upgrade to a teyrchain with the given id.
pub fn schedule_code_upgrade(
id: ParaId,
new_code: ValidationCode,
set_go_ahead: UpgradeStrategy,
) -> DispatchResult {
paras::Pezpallet::::schedule_code_upgrade_external(id, new_code, set_go_ahead)
}
/// Sets the current teyrchain head with the given id.
pub fn set_current_head(id: ParaId, new_head: HeadData) {
paras::Pezpallet::::set_current_head(id, new_head)
}
/// Ensure more initialization for `ParaId` when benchmarking. (e.g. open HRMP channels, ...)
#[cfg(feature = "runtime-benchmarks")]
pub trait EnsureForTeyrchain {
fn ensure(para_id: ParaId);
}
#[cfg(feature = "runtime-benchmarks")]
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl EnsureForTeyrchain for Tuple {
fn ensure(para: ParaId) {
for_tuples!( #(
Tuple::ensure(para);
)* );
}
}