subspace_runtime_primitives/
lib.rs1#![feature(let_chains)]
3#![cfg_attr(not(feature = "std"), no_std)]
4
5pub mod extension;
6pub mod utility;
7pub mod weights;
8
9#[cfg(not(feature = "std"))]
10extern crate alloc;
11
12use crate::time::{BLOCKS_IN_A_DAY, BLOCKS_IN_AN_MINUTE};
13#[cfg(not(feature = "std"))]
14use alloc::vec::Vec;
15use core::marker::PhantomData;
16use frame_support::pallet_prelude::Weight;
17use frame_support::traits::tokens;
18use frame_support::weights::WeightToFee;
19use frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND;
20use frame_support::{Deserialize, Serialize};
21use frame_system::limits::BlockLength;
22use frame_system::offchain::CreateTransactionBase;
23use pallet_transaction_payment::{
24 Multiplier, NextFeeMultiplier, OnChargeTransaction, TargetedFeeAdjustment,
25};
26use parity_scale_codec::{Codec, Decode, Encode, MaxEncodedLen};
27use scale_info::TypeInfo;
28use sp_core::parameter_types;
29use sp_runtime::traits::{Block as BlockT, Bounded, Header as HeaderT, IdentifyAccount, Verify};
30use sp_runtime::{FixedPointNumber, MultiSignature, Perbill, Perquintill};
31pub use subspace_core_primitives::BlockNumber;
32
33pub const MIN_REPLICATION_FACTOR: u16 = 25;
36
37pub const SHANNON: Balance = 1;
39pub const DECIMAL_PLACES: u8 = 18;
41pub const AI3: Balance = (10 * SHANNON).pow(DECIMAL_PLACES as u32);
43pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
45pub const SLOT_PROBABILITY: (u64, u64) = (1, 6);
48pub const BLOCK_WEIGHT_FOR_2_SEC: Weight =
50 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
51
52pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024;
54
55pub const DOMAINS_PRUNING_DEPTH_MULTIPLIER: u32 = 2;
57
58pub const DOMAINS_BLOCK_PRUNING_DEPTH: u32 = 14_400;
60
61pub fn maximum_normal_block_length() -> BlockLength {
63 BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO)
64}
65
66pub const MAX_CALL_RECURSION_DEPTH: u32 = 10;
72
73pub type Signature = MultiSignature;
75
76pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
82
83pub type Balance = u128;
85
86pub type Nonce = u32;
88
89pub type Hash = sp_core::H256;
91
92pub type Moment = u64;
94
95pub type ExtrinsicFor<Block> = <Block as BlockT>::Extrinsic;
97
98pub type BlockHashFor<Block> = <Block as BlockT>::Hash;
100
101pub type HeaderFor<Block> = <Block as BlockT>::Header;
103
104pub type BlockHashingFor<Block> = <HeaderFor<Block> as HeaderT>::Hashing;
106
107parameter_types! {
108 pub const ConsensusEventSegmentSize: u32 = 0;
110 pub const DomainEventSegmentSize: u32 = 100;
112}
113
114pub mod opaque {
121 use super::BlockNumber;
122 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
123 use sp_runtime::generic;
124 use sp_runtime::traits::BlakeTwo256;
125
126 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
128 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
130}
131
132pub mod time {
133 pub const MILLISECS_PER_BLOCK: u64 = 6000;
150 pub const BLOCKS_IN_AN_MINUTE: u32 = (60 * 1000) / MILLISECS_PER_BLOCK as u32;
152 pub const BLOCKS_IN_AN_HOUR: u32 = 60 * BLOCKS_IN_AN_MINUTE;
154 pub const BLOCKS_IN_A_DAY: u32 = 24 * BLOCKS_IN_AN_HOUR;
156}
157
158#[derive(Copy, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, MaxEncodedLen, Debug)]
159pub struct CouncilDemocracyConfigParams<BlockNumber> {
160 pub council_motion_duration: BlockNumber,
162 pub democracy_cooloff_period: BlockNumber,
164 pub democracy_enactment_period: BlockNumber,
166 pub democracy_fast_track_voting_period: BlockNumber,
168 pub democracy_launch_period: BlockNumber,
170 pub democracy_vote_locking_period: BlockNumber,
172 pub democracy_voting_period: BlockNumber,
174}
175
176impl<BlockNumber: From<u32>> Default for CouncilDemocracyConfigParams<BlockNumber> {
177 fn default() -> Self {
178 Self {
179 council_motion_duration: BLOCKS_IN_A_DAY.into(),
180 democracy_cooloff_period: BLOCKS_IN_A_DAY.into(),
181 democracy_enactment_period: BLOCKS_IN_A_DAY.into(),
182 democracy_fast_track_voting_period: (2 * BLOCKS_IN_A_DAY).into(),
183 democracy_launch_period: (2 * BLOCKS_IN_A_DAY).into(),
184 democracy_vote_locking_period: BLOCKS_IN_A_DAY.into(),
185 democracy_voting_period: BLOCKS_IN_A_DAY.into(),
186 }
187 }
188}
189
190impl<BlockNumber: From<u32>> CouncilDemocracyConfigParams<BlockNumber> {
191 pub fn production_params() -> Self {
193 Self::default()
194 }
195
196 pub fn fast_params() -> Self {
198 Self {
199 council_motion_duration: (15 * BLOCKS_IN_AN_MINUTE).into(),
200 democracy_cooloff_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
201 democracy_enactment_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
202 democracy_fast_track_voting_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
203 democracy_launch_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
204 democracy_vote_locking_period: BLOCKS_IN_AN_MINUTE.into(),
205 democracy_voting_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
206 }
207 }
208}
209
210pub trait RewardsEnabled {
212 fn rewards_enabled() -> bool;
214}
215
216pub trait FindBlockRewardAddress<RewardAddress> {
218 fn find_block_reward_address() -> Option<RewardAddress>;
220}
221
222pub trait FindVotingRewardAddresses<RewardAddress> {
224 fn find_voting_reward_addresses() -> Vec<RewardAddress>;
226}
227
228pub trait StorageFee<Balance> {
229 fn transaction_byte_fee() -> Balance;
231
232 fn note_storage_fees(fee: Balance);
234}
235
236parameter_types! {
237 pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(50);
240 pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1_000_000);
243 pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
247 pub MaximumMultiplier: Multiplier = Bounded::max_value();
249}
250
251pub type SlowAdjustingFeeUpdate<R, TargetBlockFullness> = TargetedFeeAdjustment<
254 R,
255 TargetBlockFullness,
256 AdjustmentVariable,
257 MinimumMultiplier,
258 MaximumMultiplier,
259>;
260
261#[derive(Encode, Decode, TypeInfo)]
262pub struct BlockTransactionByteFee<Balance: Codec> {
263 pub current: Balance,
265 pub next: Balance,
267}
268
269impl<Balance: Codec + tokens::Balance> Default for BlockTransactionByteFee<Balance> {
270 fn default() -> Self {
271 BlockTransactionByteFee {
272 current: Balance::max_value(),
273 next: Balance::max_value(),
274 }
275 }
276}
277
278parameter_types! {
279 pub const XdmFeeMultipler: u32 = 5;
280}
281
282pub type OnChargeTransactionBalance<T> = <<T as pallet_transaction_payment::Config>::OnChargeTransaction as OnChargeTransaction<
284 T,
285>>::Balance;
286
287pub struct XdmAdjustedWeightToFee<T>(PhantomData<T>);
289impl<T: pallet_transaction_payment::Config> WeightToFee for XdmAdjustedWeightToFee<T> {
290 type Balance = OnChargeTransactionBalance<T>;
291
292 fn weight_to_fee(weight: &Weight) -> Self::Balance {
293 let unadjusted_weight_fee = pallet_transaction_payment::Pallet::<T>::weight_to_fee(*weight);
295 let multiplier = NextFeeMultiplier::<T>::get();
296 multiplier.saturating_mul_int(unadjusted_weight_fee)
298 }
299}
300
301#[derive(
302 PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug,
303)]
304pub enum HoldIdentifier {
305 DomainStaking,
306 DomainInstantiation,
307 DomainStorageFund,
308 MessengerChannel,
309 Preimage,
310}
311
312pub trait CreateUnsigned<LocalCall>: CreateTransactionBase<LocalCall> {
314 fn create_unsigned(call: Self::RuntimeCall) -> Self::Extrinsic;
316}
317
318#[cfg(feature = "testing")]
319pub mod tests_utils {
320 use frame_support::dispatch::DispatchClass;
321 use frame_support::weights::Weight;
322 use frame_system::limits::BlockWeights;
323 use pallet_transaction_payment::{Multiplier, MultiplierUpdate};
324 use sp_runtime::BuildStorage;
325 use sp_runtime::traits::{Convert, Get};
326 use std::marker::PhantomData;
327
328 pub struct FeeMultiplierUtils<Runtime, BlockWeightsGetter>(
329 PhantomData<(Runtime, BlockWeightsGetter)>,
330 );
331
332 impl<Runtime, BlockWeightsGetter> FeeMultiplierUtils<Runtime, BlockWeightsGetter>
333 where
334 Runtime: frame_system::Config + pallet_transaction_payment::Config,
335 BlockWeightsGetter: Get<BlockWeights>,
336 {
337 fn max_normal() -> Weight {
338 let block_weights = BlockWeightsGetter::get();
339 block_weights
340 .get(DispatchClass::Normal)
341 .max_total
342 .unwrap_or(block_weights.max_block)
343 }
344
345 fn min_multiplier() -> Multiplier {
346 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::min()
347 }
348
349 fn target() -> Weight {
350 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::target()
351 * Self::max_normal()
352 }
353
354 fn runtime_multiplier_update(fm: Multiplier) -> Multiplier {
356 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::convert(fm)
357 }
358
359 fn run_with_system_weight<F>(w: Weight, assertions: F)
360 where
361 F: Fn(),
362 {
363 let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
364 .build_storage()
365 .unwrap()
366 .into();
367 t.execute_with(|| {
368 frame_system::Pallet::<Runtime>::set_block_consumed_resources(w, 0);
369 assertions()
370 });
371 }
372
373 pub fn multiplier_can_grow_from_zero()
377 where
378 Runtime: pallet_transaction_payment::Config,
379 BlockWeightsGetter: Get<BlockWeights>,
380 {
381 Self::run_with_system_weight(
384 Self::target().set_ref_time((Self::target().ref_time() / 100) * 101),
385 || {
386 let next = Self::runtime_multiplier_update(Self::min_multiplier());
387 assert!(
388 next > Self::min_multiplier(),
389 "{:?} !> {:?}",
390 next,
391 Self::min_multiplier()
392 );
393 },
394 );
395
396 Self::run_with_system_weight(
398 Self::target().set_proof_size((Self::target().proof_size() / 100) * 101),
399 || {
400 let next = Self::runtime_multiplier_update(Self::min_multiplier());
401 assert!(
402 next > Self::min_multiplier(),
403 "{:?} !> {:?}",
404 next,
405 Self::min_multiplier()
406 );
407 },
408 )
409 }
410 }
411}