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::dispatch::DispatchResult;
17use frame_support::pallet_prelude::Weight;
18use frame_support::traits::tokens;
19use frame_support::weights::WeightToFee;
20use frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND;
21use frame_support::{Deserialize, Serialize};
22use frame_system::limits::BlockLength;
23use frame_system::offchain::CreateTransactionBase;
24use frame_system::pallet_prelude::BlockNumberFor;
25use pallet_transaction_payment::{
26 Multiplier, NextFeeMultiplier, OnChargeTransaction, TargetedFeeAdjustment,
27};
28use parity_scale_codec::{Codec, Decode, Encode, MaxEncodedLen};
29use scale_info::TypeInfo;
30use sp_core::parameter_types;
31use sp_runtime::traits::{Block as BlockT, Bounded, Header as HeaderT, IdentifyAccount, Verify};
32use sp_runtime::{FixedPointNumber, MultiSignature, Perbill, Perquintill};
33pub use subspace_core_primitives::BlockNumber;
34
35pub const MIN_REPLICATION_FACTOR: u16 = 25;
38
39pub const SHANNON: Balance = 1;
41pub const DECIMAL_PLACES: u8 = 18;
43pub const AI3: Balance = (10 * SHANNON).pow(DECIMAL_PLACES as u32);
45pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
47pub const SLOT_PROBABILITY: (u64, u64) = (1, 6);
50pub const BLOCK_WEIGHT_FOR_2_SEC: Weight =
52 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
53
54pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024;
56
57pub const DOMAINS_PRUNING_DEPTH_MULTIPLIER: u32 = 2;
59
60pub fn maximum_normal_block_length() -> BlockLength {
62 BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO)
63}
64
65pub const MAX_CALL_RECURSION_DEPTH: u32 = 10;
71
72pub type Signature = MultiSignature;
74
75pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
81
82pub type Balance = u128;
84
85pub type Nonce = u32;
87
88pub type Hash = sp_core::H256;
90
91pub type Moment = u64;
93
94pub type ExtrinsicFor<Block> = <Block as BlockT>::Extrinsic;
96
97pub type BlockHashFor<Block> = <Block as BlockT>::Hash;
99
100pub type HeaderFor<Block> = <Block as BlockT>::Header;
102
103pub type BlockHashingFor<Block> = <HeaderFor<Block> as HeaderT>::Hashing;
105
106parameter_types! {
107 pub const ConsensusEventSegmentSize: u32 = 0;
109 pub const DomainEventSegmentSize: u32 = 100;
111}
112
113pub mod opaque {
120 use super::BlockNumber;
121 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
122 use sp_runtime::generic;
123 use sp_runtime::traits::BlakeTwo256;
124
125 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
127 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
129}
130
131pub mod time {
132 pub const MILLISECS_PER_BLOCK: u64 = 6000;
149 pub const BLOCKS_IN_AN_MINUTE: u32 = (60 * 1000) / MILLISECS_PER_BLOCK as u32;
151 pub const BLOCKS_IN_AN_HOUR: u32 = 60 * BLOCKS_IN_AN_MINUTE;
153 pub const BLOCKS_IN_A_DAY: u32 = 24 * BLOCKS_IN_AN_HOUR;
155}
156
157#[derive(Copy, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, MaxEncodedLen, Debug)]
158pub struct CouncilDemocracyConfigParams<BlockNumber> {
159 pub council_motion_duration: BlockNumber,
161 pub democracy_cooloff_period: BlockNumber,
163 pub democracy_enactment_period: BlockNumber,
165 pub democracy_fast_track_voting_period: BlockNumber,
167 pub democracy_launch_period: BlockNumber,
169 pub democracy_vote_locking_period: BlockNumber,
171 pub democracy_voting_period: BlockNumber,
173}
174
175impl<BlockNumber: From<u32>> Default for CouncilDemocracyConfigParams<BlockNumber> {
176 fn default() -> Self {
177 Self {
178 council_motion_duration: BLOCKS_IN_A_DAY.into(),
179 democracy_cooloff_period: BLOCKS_IN_A_DAY.into(),
180 democracy_enactment_period: BLOCKS_IN_A_DAY.into(),
181 democracy_fast_track_voting_period: (2 * BLOCKS_IN_A_DAY).into(),
182 democracy_launch_period: (2 * BLOCKS_IN_A_DAY).into(),
183 democracy_vote_locking_period: BLOCKS_IN_A_DAY.into(),
184 democracy_voting_period: BLOCKS_IN_A_DAY.into(),
185 }
186 }
187}
188
189impl<BlockNumber: From<u32>> CouncilDemocracyConfigParams<BlockNumber> {
190 pub fn production_params() -> Self {
192 Self::default()
193 }
194
195 pub fn fast_params() -> Self {
197 Self {
198 council_motion_duration: (15 * BLOCKS_IN_AN_MINUTE).into(),
199 democracy_cooloff_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
200 democracy_enactment_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
201 democracy_fast_track_voting_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
202 democracy_launch_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
203 democracy_vote_locking_period: BLOCKS_IN_AN_MINUTE.into(),
204 democracy_voting_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
205 }
206 }
207}
208pub struct GenesisConfigParams {
210 pub confirmation_depth_k: BlockNumber,
212 pub domain_block_pruning_depth: BlockNumber,
214 pub staking_withdrawal_period: BlockNumber,
216}
217
218impl GenesisConfigParams {
219 pub const fn production_params() -> Self {
221 Self {
222 confirmation_depth_k: 100u32,
223 domain_block_pruning_depth: 14_400u32,
224 staking_withdrawal_period: 14_400u32,
225 }
226 }
227
228 pub const fn dev_params() -> Self {
230 Self {
231 confirmation_depth_k: 5u32,
232 domain_block_pruning_depth: 5u32,
233 staking_withdrawal_period: 5u32,
234 }
235 }
236}
237
238pub trait RewardsEnabled {
240 fn rewards_enabled() -> bool;
242}
243
244pub trait FindBlockRewardAddress<RewardAddress> {
246 fn find_block_reward_address() -> Option<RewardAddress>;
248}
249
250pub trait FindVotingRewardAddresses<RewardAddress> {
252 fn find_voting_reward_addresses() -> Vec<RewardAddress>;
254}
255
256pub trait StorageFee<Balance> {
257 fn transaction_byte_fee() -> Balance;
259
260 fn note_storage_fees(fee: Balance);
262}
263
264parameter_types! {
265 pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(50);
268 pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1_000_000);
271 pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
275 pub MaximumMultiplier: Multiplier = Bounded::max_value();
277}
278
279pub type SlowAdjustingFeeUpdate<R, TargetBlockFullness> = TargetedFeeAdjustment<
282 R,
283 TargetBlockFullness,
284 AdjustmentVariable,
285 MinimumMultiplier,
286 MaximumMultiplier,
287>;
288
289#[derive(Encode, Decode, TypeInfo)]
290pub struct BlockTransactionByteFee<Balance: Codec> {
291 pub current: Balance,
293 pub next: Balance,
295}
296
297impl<Balance: Codec + tokens::Balance> Default for BlockTransactionByteFee<Balance> {
298 fn default() -> Self {
299 BlockTransactionByteFee {
300 current: Balance::max_value(),
301 next: Balance::max_value(),
302 }
303 }
304}
305
306parameter_types! {
307 pub const XdmFeeMultipler: u32 = 5;
308}
309
310pub type OnChargeTransactionBalance<T> = <<T as pallet_transaction_payment::Config>::OnChargeTransaction as OnChargeTransaction<
312 T,
313>>::Balance;
314
315pub struct XdmAdjustedWeightToFee<T>(PhantomData<T>);
317impl<T: pallet_transaction_payment::Config> WeightToFee for XdmAdjustedWeightToFee<T> {
318 type Balance = OnChargeTransactionBalance<T>;
319
320 fn weight_to_fee(weight: &Weight) -> Self::Balance {
321 let unadjusted_weight_fee = pallet_transaction_payment::Pallet::<T>::weight_to_fee(*weight);
323 let multiplier = NextFeeMultiplier::<T>::get();
324 multiplier.saturating_mul_int(unadjusted_weight_fee)
326 }
327}
328
329#[derive(
330 PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug,
331)]
332pub enum HoldIdentifier {
333 DomainStaking,
334 DomainInstantiation,
335 DomainStorageFund,
336 MessengerChannel,
337 Preimage,
338}
339
340pub trait CreateUnsigned<LocalCall>: CreateTransactionBase<LocalCall> {
342 fn create_unsigned(call: Self::RuntimeCall) -> Self::Extrinsic;
344}
345
346pub trait OnSetCode<Number> {
348 fn set_code(block_number: Number) -> DispatchResult;
350}
351
352pub struct SetCode<Runtime, OSC>(PhantomData<(Runtime, OSC)>);
354impl<Runtime, OSC> frame_system::SetCode<Runtime> for SetCode<Runtime, OSC>
355where
356 Runtime: frame_system::Config,
357 OSC: OnSetCode<BlockNumberFor<Runtime>>,
358{
359 fn set_code(code: Vec<u8>) -> DispatchResult {
360 let current_block_number = frame_system::Pallet::<Runtime>::block_number();
361 OSC::set_code(current_block_number)?;
362 frame_system::Pallet::<Runtime>::update_code_in_storage(&code);
363 Ok(())
364 }
365}
366
367#[cfg(feature = "testing")]
368pub mod tests_utils {
369 use frame_support::dispatch::DispatchClass;
370 use frame_support::weights::Weight;
371 use frame_system::limits::BlockWeights;
372 use pallet_transaction_payment::{Multiplier, MultiplierUpdate};
373 use sp_runtime::BuildStorage;
374 use sp_runtime::traits::{Convert, Get};
375 use std::marker::PhantomData;
376
377 pub struct FeeMultiplierUtils<Runtime, BlockWeightsGetter>(
378 PhantomData<(Runtime, BlockWeightsGetter)>,
379 );
380
381 impl<Runtime, BlockWeightsGetter> FeeMultiplierUtils<Runtime, BlockWeightsGetter>
382 where
383 Runtime: frame_system::Config + pallet_transaction_payment::Config,
384 BlockWeightsGetter: Get<BlockWeights>,
385 {
386 fn max_normal() -> Weight {
387 let block_weights = BlockWeightsGetter::get();
388 block_weights
389 .get(DispatchClass::Normal)
390 .max_total
391 .unwrap_or(block_weights.max_block)
392 }
393
394 fn min_multiplier() -> Multiplier {
395 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::min()
396 }
397
398 fn target() -> Weight {
399 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::target()
400 * Self::max_normal()
401 }
402
403 fn runtime_multiplier_update(fm: Multiplier) -> Multiplier {
405 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::convert(fm)
406 }
407
408 fn run_with_system_weight<F>(w: Weight, assertions: F)
409 where
410 F: Fn(),
411 {
412 let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
413 .build_storage()
414 .unwrap()
415 .into();
416 t.execute_with(|| {
417 frame_system::Pallet::<Runtime>::set_block_consumed_resources(w, 0);
418 assertions()
419 });
420 }
421
422 pub fn multiplier_can_grow_from_zero()
426 where
427 Runtime: pallet_transaction_payment::Config,
428 BlockWeightsGetter: Get<BlockWeights>,
429 {
430 Self::run_with_system_weight(
433 Self::target().set_ref_time((Self::target().ref_time() / 100) * 101),
434 || {
435 let next = Self::runtime_multiplier_update(Self::min_multiplier());
436 assert!(
437 next > Self::min_multiplier(),
438 "{:?} !> {:?}",
439 next,
440 Self::min_multiplier()
441 );
442 },
443 );
444
445 Self::run_with_system_weight(
447 Self::target().set_proof_size((Self::target().proof_size() / 100) * 101),
448 || {
449 let next = Self::runtime_multiplier_update(Self::min_multiplier());
450 assert!(
451 next > Self::min_multiplier(),
452 "{:?} !> {:?}",
453 next,
454 Self::min_multiplier()
455 );
456 },
457 )
458 }
459 }
460}