subspace_runtime_primitives/
lib.rs1#![cfg_attr(not(feature = "std"), no_std)]
3
4pub mod extension;
5pub mod utility;
6pub mod weights;
7
8#[cfg(not(feature = "std"))]
9extern crate alloc;
10
11use crate::time::{BLOCKS_IN_A_DAY, BLOCKS_IN_AN_MINUTE};
12#[cfg(not(feature = "std"))]
13use alloc::vec::Vec;
14use core::marker::PhantomData;
15use frame_support::dispatch::DispatchResult;
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 frame_system::pallet_prelude::BlockNumberFor;
24use pallet_transaction_payment::{
25 Multiplier, NextFeeMultiplier, OnChargeTransaction, TargetedFeeAdjustment,
26};
27use parity_scale_codec::{Codec, Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
28use scale_info::TypeInfo;
29use sp_core::parameter_types;
30use sp_runtime::traits::{Block as BlockT, Bounded, Header as HeaderT, IdentifyAccount, Verify};
31use sp_runtime::{FixedPointNumber, MultiSignature, Perbill, Perquintill};
32pub use subspace_core_primitives::BlockNumber;
33
34pub const MIN_REPLICATION_FACTOR: u16 = 25;
37
38pub const SHANNON: Balance = 1;
40pub const DECIMAL_PLACES: u8 = 18;
42pub const AI3: Balance = (10 * SHANNON).pow(DECIMAL_PLACES as u32);
44pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
46pub const SLOT_PROBABILITY: (u64, u64) = (1, 6);
49pub const BLOCK_WEIGHT_FOR_2_SEC: Weight =
51 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
52
53pub const MAX_BLOCK_LENGTH: u32 = 5 * 1024 * 1024;
55
56pub const DOMAINS_PRUNING_DEPTH_MULTIPLIER: u32 = 2;
58
59pub fn maximum_normal_block_length() -> BlockLength {
61 BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO)
62}
63
64pub const MAX_CALL_RECURSION_DEPTH: u32 = 10;
70
71pub type Signature = MultiSignature;
73
74pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
80
81pub type Balance = u128;
83
84pub type Nonce = u32;
86
87pub type Hash = sp_core::H256;
89
90pub type Moment = u64;
92
93pub type ExtrinsicFor<Block> = <Block as BlockT>::Extrinsic;
95
96pub type BlockHashFor<Block> = <Block as BlockT>::Hash;
98
99pub type HeaderFor<Block> = <Block as BlockT>::Header;
101
102pub type BlockHashingFor<Block> = <HeaderFor<Block> as HeaderT>::Hashing;
104
105parameter_types! {
106 pub const ConsensusEventSegmentSize: u32 = 0;
108 pub const DomainEventSegmentSize: u32 = 100;
110}
111
112pub mod opaque {
119 use super::BlockNumber;
120 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
121 use sp_runtime::generic;
122 use sp_runtime::traits::BlakeTwo256;
123
124 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
126 pub type Block = generic::Block<Header, UncheckedExtrinsic>;
128}
129
130pub mod time {
131 pub const MILLISECS_PER_BLOCK: u64 = 6000;
148 pub const BLOCKS_IN_AN_MINUTE: u32 = (60 * 1000) / MILLISECS_PER_BLOCK as u32;
150 pub const BLOCKS_IN_AN_HOUR: u32 = 60 * BLOCKS_IN_AN_MINUTE;
152 pub const BLOCKS_IN_A_DAY: u32 = 24 * BLOCKS_IN_AN_HOUR;
154}
155
156#[derive(Copy, Clone, Encode, Decode, TypeInfo, Serialize, Deserialize, MaxEncodedLen, Debug)]
157pub struct CouncilDemocracyConfigParams<BlockNumber> {
158 pub council_motion_duration: BlockNumber,
160 pub democracy_cooloff_period: BlockNumber,
162 pub democracy_enactment_period: BlockNumber,
164 pub democracy_fast_track_voting_period: BlockNumber,
166 pub democracy_launch_period: BlockNumber,
168 pub democracy_vote_locking_period: BlockNumber,
170 pub democracy_voting_period: BlockNumber,
172}
173
174impl<BlockNumber: From<u32>> Default for CouncilDemocracyConfigParams<BlockNumber> {
175 fn default() -> Self {
176 Self {
177 council_motion_duration: BLOCKS_IN_A_DAY.into(),
178 democracy_cooloff_period: BLOCKS_IN_A_DAY.into(),
179 democracy_enactment_period: BLOCKS_IN_A_DAY.into(),
180 democracy_fast_track_voting_period: (2 * BLOCKS_IN_A_DAY).into(),
181 democracy_launch_period: (2 * BLOCKS_IN_A_DAY).into(),
182 democracy_vote_locking_period: BLOCKS_IN_A_DAY.into(),
183 democracy_voting_period: BLOCKS_IN_A_DAY.into(),
184 }
185 }
186}
187
188impl<BlockNumber: From<u32>> CouncilDemocracyConfigParams<BlockNumber> {
189 pub fn production_params() -> Self {
191 Self::default()
192 }
193
194 pub fn fast_params() -> Self {
196 Self {
197 council_motion_duration: (15 * BLOCKS_IN_AN_MINUTE).into(),
198 democracy_cooloff_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
199 democracy_enactment_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
200 democracy_fast_track_voting_period: (5 * BLOCKS_IN_AN_MINUTE).into(),
201 democracy_launch_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
202 democracy_vote_locking_period: BLOCKS_IN_AN_MINUTE.into(),
203 democracy_voting_period: (15 * BLOCKS_IN_AN_MINUTE).into(),
204 }
205 }
206}
207pub struct GenesisConfigParams {
209 pub confirmation_depth_k: BlockNumber,
211 pub domain_block_pruning_depth: BlockNumber,
213 pub staking_withdrawal_period: BlockNumber,
215}
216
217impl GenesisConfigParams {
218 pub const fn production_params() -> Self {
220 Self {
221 confirmation_depth_k: 100u32,
222 domain_block_pruning_depth: 14_400u32,
223 staking_withdrawal_period: 14_400u32,
224 }
225 }
226
227 pub const fn dev_params() -> Self {
229 Self {
230 confirmation_depth_k: 5u32,
231 domain_block_pruning_depth: 5u32,
232 staking_withdrawal_period: 5u32,
233 }
234 }
235}
236
237pub trait RewardsEnabled {
239 fn rewards_enabled() -> bool;
241}
242
243pub trait FindBlockRewardAddress<RewardAddress> {
245 fn find_block_reward_address() -> Option<RewardAddress>;
247}
248
249pub trait FindVotingRewardAddresses<RewardAddress> {
251 fn find_voting_reward_addresses() -> Vec<RewardAddress>;
253}
254
255pub trait StorageFee<Balance> {
256 fn transaction_byte_fee() -> Balance;
258
259 fn note_storage_fees(fee: Balance);
261}
262
263parameter_types! {
264 pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(50);
267 pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(75, 1_000_000);
270 pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 10u128);
274 pub MaximumMultiplier: Multiplier = Bounded::max_value();
276}
277
278pub type SlowAdjustingFeeUpdate<R, TargetBlockFullness> = TargetedFeeAdjustment<
281 R,
282 TargetBlockFullness,
283 AdjustmentVariable,
284 MinimumMultiplier,
285 MaximumMultiplier,
286>;
287
288#[derive(Encode, Decode, TypeInfo)]
289pub struct BlockTransactionByteFee<Balance: Codec> {
290 pub current: Balance,
292 pub next: Balance,
294}
295
296impl<Balance: Codec + tokens::Balance> Default for BlockTransactionByteFee<Balance> {
297 fn default() -> Self {
298 BlockTransactionByteFee {
299 current: Balance::max_value(),
300 next: Balance::max_value(),
301 }
302 }
303}
304
305parameter_types! {
306 pub const XdmFeeMultipler: u32 = 5;
307}
308
309pub type OnChargeTransactionBalance<T> = <<T as pallet_transaction_payment::Config>::OnChargeTransaction as OnChargeTransaction<
311 T,
312>>::Balance;
313
314pub struct XdmAdjustedWeightToFee<T>(PhantomData<T>);
316impl<T: pallet_transaction_payment::Config> WeightToFee for XdmAdjustedWeightToFee<T> {
317 type Balance = OnChargeTransactionBalance<T>;
318
319 fn weight_to_fee(weight: &Weight) -> Self::Balance {
320 let unadjusted_weight_fee = pallet_transaction_payment::Pallet::<T>::weight_to_fee(*weight);
322 let multiplier = NextFeeMultiplier::<T>::get();
323 multiplier.saturating_mul_int(unadjusted_weight_fee)
325 }
326}
327
328#[derive(
329 PartialEq,
330 Eq,
331 Clone,
332 Encode,
333 Decode,
334 TypeInfo,
335 MaxEncodedLen,
336 Ord,
337 PartialOrd,
338 Copy,
339 Debug,
340 DecodeWithMemTracking,
341)]
342pub enum HoldIdentifier {
343 DomainStaking,
344 DomainInstantiation,
345 DomainStorageFund,
346 MessengerChannel,
347 Preimage,
348}
349
350pub trait CreateUnsigned<LocalCall>: CreateTransactionBase<LocalCall> {
352 fn create_unsigned(call: Self::RuntimeCall) -> Self::Extrinsic;
354}
355
356pub trait OnSetCode<Number> {
358 fn set_code(block_number: Number) -> DispatchResult;
360}
361
362pub struct SetCode<Runtime, OSC>(PhantomData<(Runtime, OSC)>);
364impl<Runtime, OSC> frame_system::SetCode<Runtime> for SetCode<Runtime, OSC>
365where
366 Runtime: frame_system::Config,
367 OSC: OnSetCode<BlockNumberFor<Runtime>>,
368{
369 fn set_code(code: Vec<u8>) -> DispatchResult {
370 let current_block_number = frame_system::Pallet::<Runtime>::block_number();
371 OSC::set_code(current_block_number)?;
372 frame_system::Pallet::<Runtime>::update_code_in_storage(&code);
373 Ok(())
374 }
375}
376
377#[cfg(feature = "testing")]
378pub mod tests_utils {
379 use frame_support::dispatch::DispatchClass;
380 use frame_support::weights::Weight;
381 use frame_system::limits::BlockWeights;
382 use pallet_transaction_payment::{Multiplier, MultiplierUpdate};
383 use sp_runtime::BuildStorage;
384 use sp_runtime::traits::{Convert, Get};
385 use std::marker::PhantomData;
386
387 pub struct FeeMultiplierUtils<Runtime, BlockWeightsGetter>(
388 PhantomData<(Runtime, BlockWeightsGetter)>,
389 );
390
391 impl<Runtime, BlockWeightsGetter> FeeMultiplierUtils<Runtime, BlockWeightsGetter>
392 where
393 Runtime: frame_system::Config + pallet_transaction_payment::Config,
394 BlockWeightsGetter: Get<BlockWeights>,
395 {
396 fn max_normal() -> Weight {
397 let block_weights = BlockWeightsGetter::get();
398 block_weights
399 .get(DispatchClass::Normal)
400 .max_total
401 .unwrap_or(block_weights.max_block)
402 }
403
404 fn min_multiplier() -> Multiplier {
405 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::min()
406 }
407
408 fn target() -> Weight {
409 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::target()
410 * Self::max_normal()
411 }
412
413 fn runtime_multiplier_update(fm: Multiplier) -> Multiplier {
415 <Runtime as pallet_transaction_payment::Config>::FeeMultiplierUpdate::convert(fm)
416 }
417
418 fn run_with_system_weight<F>(w: Weight, assertions: F)
419 where
420 F: Fn(),
421 {
422 let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::<Runtime>::default()
423 .build_storage()
424 .unwrap()
425 .into();
426 t.execute_with(|| {
427 frame_system::Pallet::<Runtime>::set_block_consumed_resources(w, 0);
428 assertions()
429 });
430 }
431
432 pub fn multiplier_can_grow_from_zero()
436 where
437 Runtime: pallet_transaction_payment::Config,
438 BlockWeightsGetter: Get<BlockWeights>,
439 {
440 Self::run_with_system_weight(
443 Self::target().set_ref_time((Self::target().ref_time() / 100) * 101),
444 || {
445 let next = Self::runtime_multiplier_update(Self::min_multiplier());
446 assert!(
447 next > Self::min_multiplier(),
448 "{:?} !> {:?}",
449 next,
450 Self::min_multiplier()
451 );
452 },
453 );
454
455 Self::run_with_system_weight(
457 Self::target().set_proof_size((Self::target().proof_size() / 100) * 101),
458 || {
459 let next = Self::runtime_multiplier_update(Self::min_multiplier());
460 assert!(
461 next > Self::min_multiplier(),
462 "{:?} !> {:?}",
463 next,
464 Self::min_multiplier()
465 );
466 },
467 )
468 }
469 }
470}