1#![cfg_attr(not(feature = "std"), no_std)]
2#![feature(const_trait_impl, variant_count)]
3#![allow(incomplete_features)]
5#![feature(generic_const_exprs)]
8#![recursion_limit = "256"]
10#![allow(
12 non_camel_case_types,
13 reason = "https://github.com/rust-lang/rust-analyzer/issues/16514"
14)]
15
16mod domains;
17mod fees;
18mod object_mapping;
19mod signed_extensions;
20
21extern crate alloc;
22
23#[cfg(feature = "std")]
25include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
26
27use crate::fees::{OnChargeTransaction, TransactionByteFee};
28use crate::object_mapping::extract_block_object_mapping;
29pub use crate::signed_extensions::DisablePallets;
30use alloc::borrow::Cow;
31use core::mem;
32use core::num::NonZeroU64;
33use domain_runtime_primitives::opaque::Header as DomainHeader;
34use domain_runtime_primitives::{
35 AccountIdConverter, BlockNumber as DomainNumber, EthereumAccountId, Hash as DomainHash,
36 MAX_OUTGOING_MESSAGES, maximum_domain_block_weight,
37};
38use frame_support::genesis_builder_helper::{build_state, get_preset};
39use frame_support::inherent::ProvideInherent;
40use frame_support::traits::fungible::HoldConsideration;
41use frame_support::traits::{
42 ConstU8, ConstU16, ConstU32, ConstU64, Currency, EitherOfDiverse, EqualPrivilegeOnly,
43 Everything, Get, LinearStoragePrice, OnUnbalanced, Time, VariantCount,
44};
45use frame_support::weights::constants::ParityDbWeight;
46use frame_support::weights::{ConstantMultiplier, Weight};
47use frame_support::{PalletId, construct_runtime, parameter_types};
48use frame_system::EnsureRoot;
49use frame_system::limits::{BlockLength, BlockWeights};
50use frame_system::pallet_prelude::RuntimeCallFor;
51use pallet_collective::{EnsureMember, EnsureProportionAtLeast};
52pub use pallet_rewards::RewardPoint;
53pub use pallet_subspace::{AllowAuthoringBy, EnableRewardsAt};
54use pallet_transporter::EndpointHandler;
55use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
56use scale_info::TypeInfo;
57use sp_api::impl_runtime_apis;
58use sp_consensus_slots::{Slot, SlotDuration};
59use sp_consensus_subspace::{ChainConstants, PotParameters, SignedVote, SolutionRanges, Vote};
60use sp_core::crypto::KeyTypeId;
61use sp_core::{ConstBool, H256, OpaqueMetadata};
62use sp_domains::bundle_producer_election::BundleProducerElectionParams;
63use sp_domains::{
64 ChannelId, DOMAIN_STORAGE_FEE_MULTIPLIER, DomainAllowlistUpdates, DomainId, DomainInstanceData,
65 ExecutionReceiptFor, INITIAL_DOMAIN_TX_RANGE, OperatorId, OperatorPublicKey,
66 OperatorRewardSource, PermissionedActionAllowedBy,
67};
68use sp_domains_fraud_proof::fraud_proof::FraudProof;
69use sp_domains_fraud_proof::storage_proof::{
70 FraudProofStorageKeyProvider, FraudProofStorageKeyRequest,
71};
72use sp_messenger::endpoint::{Endpoint, EndpointHandler as EndpointHandlerT, EndpointId};
73use sp_messenger::messages::{
74 BlockMessagesQuery, BlockMessagesWithStorageKey, ChainId, ChannelStateWithNonce,
75 CrossDomainMessage, MessageId, MessageKey, MessagesWithStorageKey, Nonce as XdmNonce,
76};
77use sp_messenger::{ChannelNonce, XdmId};
78use sp_messenger_host_functions::{StorageKeyRequest, get_storage_key};
79use sp_mmr_primitives::EncodableOpaqueLeaf;
80use sp_runtime::traits::{
81 AccountIdConversion, AccountIdLookup, BlakeTwo256, ConstU128, Keccak256, NumberFor,
82};
83use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity};
84use sp_runtime::type_with_default::TypeWithDefault;
85use sp_runtime::{AccountId32, ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill, generic};
86use sp_std::collections::btree_map::BTreeMap;
87use sp_std::collections::btree_set::BTreeSet;
88use sp_std::marker::PhantomData;
89use sp_std::prelude::*;
90use sp_subspace_mmr::ConsensusChainMmrLeafProof;
91use sp_subspace_mmr::subspace_mmr_runtime_interface::consensus_block_hash;
92use sp_version::RuntimeVersion;
93use static_assertions::const_assert;
94use subspace_core_primitives::objects::BlockObjectMapping;
95use subspace_core_primitives::pieces::Piece;
96use subspace_core_primitives::segments::{
97 HistorySize, SegmentCommitment, SegmentHeader, SegmentIndex,
98};
99use subspace_core_primitives::solutions::{
100 SolutionRange, pieces_to_solution_range, solution_range_to_pieces,
101};
102use subspace_core_primitives::{PublicKey, Randomness, SlotNumber, U256};
103use subspace_runtime_primitives::utility::{
104 DefaultNonceProvider, MaybeMultisigCall, MaybeNestedCall, MaybeUtilityCall,
105};
106use subspace_runtime_primitives::{
107 AI3, AccountId, BLOCK_WEIGHT_FOR_2_SEC, Balance, BlockHashFor, BlockNumber,
108 ConsensusEventSegmentSize, DOMAINS_BLOCK_PRUNING_DEPTH, ExtrinsicFor, FindBlockRewardAddress,
109 Hash, HeaderFor, HoldIdentifier, MAX_BLOCK_LENGTH, MIN_REPLICATION_FACTOR, Moment,
110 NORMAL_DISPATCH_RATIO, Nonce, SHANNON, SLOT_PROBABILITY, Signature, SlowAdjustingFeeUpdate,
111 TargetBlockFullness, XdmAdjustedWeightToFee, XdmFeeMultipler, maximum_normal_block_length,
112};
113
114sp_runtime::impl_opaque_keys! {
115 pub struct SessionKeys {
116 }
117}
118
119const MAX_PIECES_IN_SECTOR: u16 = 1000;
121
122#[sp_version::runtime_version]
125pub const VERSION: RuntimeVersion = RuntimeVersion {
126 spec_name: Cow::Borrowed("subspace"),
127 impl_name: Cow::Borrowed("subspace"),
128 authoring_version: 0,
129 spec_version: 2,
131 impl_version: 0,
132 apis: RUNTIME_API_VERSIONS,
133 transaction_version: 0,
134 system_version: 2,
135};
136
137const SLOT_DURATION: u64 = 1000;
142
143const BLOCK_AUTHORING_DELAY: SlotNumber = 4;
145
146const POT_ENTROPY_INJECTION_INTERVAL: BlockNumber = 50;
148
149const POT_ENTROPY_INJECTION_LOOKBACK_DEPTH: u8 = 2;
151
152const POT_ENTROPY_INJECTION_DELAY: SlotNumber = 15;
154
155const_assert!(POT_ENTROPY_INJECTION_INTERVAL as u64 > POT_ENTROPY_INJECTION_DELAY);
158const_assert!(POT_ENTROPY_INJECTION_DELAY > BLOCK_AUTHORING_DELAY + 1);
162
163const ERA_DURATION_IN_BLOCKS: BlockNumber = 2016;
165
166const TX_RANGE_ADJUSTMENT_INTERVAL_BLOCKS: u64 = 100;
168
169const INITIAL_SOLUTION_RANGE: SolutionRange =
171 pieces_to_solution_range(MAX_PIECES_IN_SECTOR as u64, SLOT_PROBABILITY);
172
173const EXPECTED_VOTES_PER_BLOCK: u32 = 9;
177
178const RECENT_SEGMENTS: HistorySize = HistorySize::new(NonZeroU64::new(5).expect("Not zero; qed"));
180const RECENT_HISTORY_FRACTION: (HistorySize, HistorySize) = (
182 HistorySize::new(NonZeroU64::new(1).expect("Not zero; qed")),
183 HistorySize::new(NonZeroU64::new(10).expect("Not zero; qed")),
184);
185const MIN_SECTOR_LIFETIME: HistorySize =
187 HistorySize::new(NonZeroU64::new(4).expect("Not zero; qed"));
188
189parameter_types! {
190 pub const Version: RuntimeVersion = VERSION;
191 pub const BlockHashCount: BlockNumber = 250;
192 pub SubspaceBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults(BLOCK_WEIGHT_FOR_2_SEC, NORMAL_DISPATCH_RATIO);
194 pub SubspaceBlockLength: BlockLength = maximum_normal_block_length();
196}
197
198pub type SS58Prefix = ConstU16<6094>;
199
200impl frame_system::Config for Runtime {
203 type BaseCallFilter = Everything;
208 type BlockWeights = SubspaceBlockWeights;
210 type BlockLength = SubspaceBlockLength;
212 type AccountId = AccountId;
214 type RuntimeCall = RuntimeCall;
216 type RuntimeTask = RuntimeTask;
218 type Lookup = AccountIdLookup<AccountId, ()>;
220 type Nonce = TypeWithDefault<Nonce, DefaultNonceProvider<System, Nonce>>;
222 type Hash = Hash;
224 type Hashing = BlakeTwo256;
226 type Block = Block;
228 type RuntimeEvent = RuntimeEvent;
230 type RuntimeOrigin = RuntimeOrigin;
232 type BlockHashCount = BlockHashCount;
234 type DbWeight = ParityDbWeight;
236 type Version = Version;
238 type PalletInfo = PalletInfo;
242 type OnNewAccount = ();
244 type OnKilledAccount = ();
246 type AccountData = pallet_balances::AccountData<Balance>;
248 type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
250 type SS58Prefix = SS58Prefix;
252 type OnSetCode = ();
254 type SingleBlockMigrations = ();
255 type MultiBlockMigrator = ();
256 type PreInherents = ();
257 type PostInherents = ();
258 type PostTransactions = ();
259 type MaxConsumers = ConstU32<16>;
260 type ExtensionsWeightInfo = frame_system::ExtensionsWeight<Runtime>;
261 type EventSegmentSize = ConsensusEventSegmentSize;
262}
263
264parameter_types! {
265 pub const BlockAuthoringDelay: SlotNumber = BLOCK_AUTHORING_DELAY;
266 pub const PotEntropyInjectionInterval: BlockNumber = POT_ENTROPY_INJECTION_INTERVAL;
267 pub const PotEntropyInjectionLookbackDepth: u8 = POT_ENTROPY_INJECTION_LOOKBACK_DEPTH;
268 pub const PotEntropyInjectionDelay: SlotNumber = POT_ENTROPY_INJECTION_DELAY;
269 pub const EraDuration: u32 = ERA_DURATION_IN_BLOCKS;
270 pub const SlotProbability: (u64, u64) = SLOT_PROBABILITY;
271 pub const ExpectedVotesPerBlock: u32 = EXPECTED_VOTES_PER_BLOCK;
272 pub const RecentSegments: HistorySize = RECENT_SEGMENTS;
273 pub const RecentHistoryFraction: (HistorySize, HistorySize) = RECENT_HISTORY_FRACTION;
274 pub const MinSectorLifetime: HistorySize = MIN_SECTOR_LIFETIME;
275 pub const ShouldAdjustSolutionRange: bool = false;
278 pub const BlockSlotCount: u32 = 6;
279}
280
281pub struct ConfirmationDepthK;
282
283impl Get<BlockNumber> for ConfirmationDepthK {
284 fn get() -> BlockNumber {
285 pallet_runtime_configs::ConfirmationDepthK::<Runtime>::get()
286 }
287}
288
289impl pallet_subspace::Config for Runtime {
290 type RuntimeEvent = RuntimeEvent;
291 type SubspaceOrigin = pallet_subspace::EnsureSubspaceOrigin;
292 type BlockAuthoringDelay = BlockAuthoringDelay;
293 type PotEntropyInjectionInterval = PotEntropyInjectionInterval;
294 type PotEntropyInjectionLookbackDepth = PotEntropyInjectionLookbackDepth;
295 type PotEntropyInjectionDelay = PotEntropyInjectionDelay;
296 type EraDuration = EraDuration;
297 type InitialSolutionRange = ConstU64<INITIAL_SOLUTION_RANGE>;
298 type SlotProbability = SlotProbability;
299 type ConfirmationDepthK = ConfirmationDepthK;
300 type RecentSegments = RecentSegments;
301 type RecentHistoryFraction = RecentHistoryFraction;
302 type MinSectorLifetime = MinSectorLifetime;
303 type ExpectedVotesPerBlock = ExpectedVotesPerBlock;
304 type MaxPiecesInSector = ConstU16<{ MAX_PIECES_IN_SECTOR }>;
305 type ShouldAdjustSolutionRange = ShouldAdjustSolutionRange;
306 type EraChangeTrigger = pallet_subspace::NormalEraChange;
307 type WeightInfo = pallet_subspace::weights::SubstrateWeight<Runtime>;
308 type BlockSlotCount = BlockSlotCount;
309 type ExtensionWeightInfo = pallet_subspace::extensions::weights::SubstrateWeight<Runtime>;
310}
311
312impl pallet_timestamp::Config for Runtime {
313 type Moment = Moment;
315 type OnTimestampSet = ();
316 type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
317 type WeightInfo = ();
318}
319
320parameter_types! {
321 pub const ExistentialDeposit: Balance = 10_000_000_000_000 * SHANNON;
328}
329
330#[derive(
331 PartialEq, Eq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Ord, PartialOrd, Copy, Debug,
332)]
333pub struct HoldIdentifierWrapper(HoldIdentifier);
334
335impl pallet_domains::HoldIdentifier<Runtime> for HoldIdentifierWrapper {
336 fn staking_staked() -> Self {
337 Self(HoldIdentifier::DomainStaking)
338 }
339
340 fn domain_instantiation_id() -> Self {
341 Self(HoldIdentifier::DomainInstantiation)
342 }
343
344 fn storage_fund_withdrawal() -> Self {
345 Self(HoldIdentifier::DomainStorageFund)
346 }
347}
348
349impl pallet_messenger::HoldIdentifier<Runtime> for HoldIdentifierWrapper {
350 fn messenger_channel() -> Self {
351 Self(HoldIdentifier::MessengerChannel)
352 }
353}
354
355impl VariantCount for HoldIdentifierWrapper {
356 const VARIANT_COUNT: u32 = mem::variant_count::<HoldIdentifier>() as u32;
357}
358
359impl pallet_balances::Config for Runtime {
360 type RuntimeFreezeReason = RuntimeFreezeReason;
361 type MaxLocks = ConstU32<50>;
362 type MaxReserves = ();
363 type ReserveIdentifier = [u8; 8];
364 type Balance = Balance;
366 type RuntimeEvent = RuntimeEvent;
368 type DustRemoval = ();
369 type ExistentialDeposit = ExistentialDeposit;
370 type AccountStore = System;
371 type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
372 type FreezeIdentifier = ();
373 type MaxFreezes = ();
374 type RuntimeHoldReason = HoldIdentifierWrapper;
375 type DoneSlashHandler = ();
376}
377
378parameter_types! {
379 pub CreditSupply: Balance = Balances::total_issuance();
380 pub TotalSpacePledged: u128 = {
381 let pieces = solution_range_to_pieces(Subspace::solution_ranges().current, SLOT_PROBABILITY);
382 pieces as u128 * Piece::SIZE as u128
383 };
384 pub BlockchainHistorySize: u128 = u128::from(Subspace::archived_history_size());
385 pub DynamicCostOfStorage: bool = RuntimeConfigs::enable_dynamic_cost_of_storage();
386 pub TransactionWeightFee: Balance = 100_000 * SHANNON;
387}
388
389impl pallet_transaction_fees::Config for Runtime {
390 type RuntimeEvent = RuntimeEvent;
391 type MinReplicationFactor = ConstU16<MIN_REPLICATION_FACTOR>;
392 type CreditSupply = CreditSupply;
393 type TotalSpacePledged = TotalSpacePledged;
394 type BlockchainHistorySize = BlockchainHistorySize;
395 type Currency = Balances;
396 type FindBlockRewardAddress = Subspace;
397 type DynamicCostOfStorage = DynamicCostOfStorage;
398 type WeightInfo = pallet_transaction_fees::weights::SubstrateWeight<Runtime>;
399}
400
401impl pallet_transaction_payment::Config for Runtime {
402 type RuntimeEvent = RuntimeEvent;
403 type OnChargeTransaction = OnChargeTransaction;
404 type OperationalFeeMultiplier = ConstU8<5>;
405 type WeightToFee = ConstantMultiplier<Balance, TransactionWeightFee>;
406 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
407 type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Runtime, TargetBlockFullness>;
408 type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
409}
410
411impl pallet_utility::Config for Runtime {
412 type RuntimeEvent = RuntimeEvent;
413 type RuntimeCall = RuntimeCall;
414 type PalletsOrigin = OriginCaller;
415 type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
416}
417
418impl MaybeMultisigCall<Runtime> for RuntimeCall {
419 fn maybe_multisig_call(&self) -> Option<&pallet_multisig::Call<Runtime>> {
421 match self {
422 RuntimeCall::Multisig(call) => Some(call),
423 _ => None,
424 }
425 }
426}
427
428impl MaybeUtilityCall<Runtime> for RuntimeCall {
429 fn maybe_utility_call(&self) -> Option<&pallet_utility::Call<Runtime>> {
431 match self {
432 RuntimeCall::Utility(call) => Some(call),
433 _ => None,
434 }
435 }
436}
437
438impl MaybeNestedCall<Runtime> for RuntimeCall {
439 fn maybe_nested_call(&self) -> Option<Vec<&RuntimeCallFor<Runtime>>> {
444 let calls = self.maybe_nested_utility_calls();
450 if calls.is_some() {
451 return calls;
452 }
453
454 let calls = self.maybe_nested_multisig_calls();
455 if calls.is_some() {
456 return calls;
457 }
458
459 None
460 }
461}
462
463impl pallet_sudo::Config for Runtime {
464 type RuntimeEvent = RuntimeEvent;
465 type RuntimeCall = RuntimeCall;
466 type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
467}
468
469pub type CouncilCollective = pallet_collective::Instance1;
470
471macro_rules! impl_get_council_democracy_field_block_number {
473 ($field_type_name:ident, $field:ident) => {
474 pub struct $field_type_name;
475
476 impl Get<BlockNumber> for $field_type_name {
477 fn get() -> BlockNumber {
478 pallet_runtime_configs::CouncilDemocracyConfig::<Runtime>::get().$field
479 }
480 }
481 };
482}
483
484impl_get_council_democracy_field_block_number! {CouncilMotionDuration, council_motion_duration}
485
486parameter_types! {
487 pub MaxProposalWeight: Weight = Perbill::from_percent(50) * SubspaceBlockWeights::get().max_block;
490}
491
492pub type EnsureRootOr<O> = EitherOfDiverse<EnsureRoot<AccountId>, O>;
493pub type AllCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>;
494pub type TwoThirdsCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>;
495pub type HalfCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>;
496
497impl pallet_collective::Config<CouncilCollective> for Runtime {
499 type DefaultVote = pallet_collective::PrimeDefaultVote;
500 type MaxMembers = ConstU32<100>;
501 type MaxProposalWeight = MaxProposalWeight;
502 type MaxProposals = ConstU32<100>;
503 type MotionDuration = CouncilMotionDuration;
505 type Proposal = RuntimeCall;
506 type RuntimeEvent = RuntimeEvent;
507 type RuntimeOrigin = RuntimeOrigin;
508 type SetMembersOrigin = EnsureRootOr<AllCouncil>;
509 type WeightInfo = pallet_collective::weights::SubstrateWeight<Runtime>;
510 type DisapproveOrigin = TwoThirdsCouncil;
511 type KillOrigin = TwoThirdsCouncil;
512 type Consideration = ();
515}
516
517parameter_types! {
519 pub PreimageBaseDeposit: Balance = 100 * AI3;
520 pub PreimageByteDeposit: Balance = AI3;
521 pub const PreImageHoldReason: HoldIdentifierWrapper = HoldIdentifierWrapper(HoldIdentifier::Preimage);
522}
523
524impl pallet_preimage::Config for Runtime {
525 type Consideration = HoldConsideration<
526 AccountId,
527 Balances,
528 PreImageHoldReason,
529 LinearStoragePrice<PreimageBaseDeposit, PreimageByteDeposit, Balance>,
530 >;
531 type Currency = Balances;
532 type ManagerOrigin = EnsureRoot<AccountId>;
533 type RuntimeEvent = RuntimeEvent;
534 type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
535}
536
537parameter_types! {
538 pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * SubspaceBlockWeights::get().max_block;
539 pub const NoPreimagePostponement: Option<u32> = Some(10);
541}
542
543impl pallet_scheduler::Config for Runtime {
554 type MaxScheduledPerBlock = ConstU32<50>;
555 type MaximumWeight = MaximumSchedulerWeight;
556 type OriginPrivilegeCmp = EqualPrivilegeOnly;
557 type PalletsOrigin = OriginCaller;
558 type Preimages = Preimage;
559 type RuntimeCall = RuntimeCall;
560 type RuntimeEvent = RuntimeEvent;
561 type RuntimeOrigin = RuntimeOrigin;
562 type ScheduleOrigin = EnsureRoot<AccountId>;
563 type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
564}
565
566type NegativeImbalance = <Balances as Currency<AccountId>>::NegativeImbalance;
567
568pub struct DemocracySlash;
569impl OnUnbalanced<NegativeImbalance> for DemocracySlash {
570 fn on_nonzero_unbalanced(slashed: NegativeImbalance) {
571 Balances::resolve_creating(&TreasuryAccount::get(), slashed);
572 }
573}
574
575impl_get_council_democracy_field_block_number! {CooloffPeriod, democracy_cooloff_period}
576impl_get_council_democracy_field_block_number! {EnactmentPeriod, democracy_enactment_period}
577impl_get_council_democracy_field_block_number! {FastTrackVotingPeriod, democracy_fast_track_voting_period}
578impl_get_council_democracy_field_block_number! {LaunchPeriod, democracy_launch_period}
579impl_get_council_democracy_field_block_number! {VoteLockingPeriod, democracy_vote_locking_period}
580impl_get_council_democracy_field_block_number! {VotingPeriod, democracy_voting_period}
581
582impl pallet_democracy::Config for Runtime {
584 type BlacklistOrigin = EnsureRoot<AccountId>;
585 type CancelProposalOrigin = EnsureRoot<AccountId>;
587 type CancellationOrigin = EnsureRootOr<TwoThirdsCouncil>;
589 type CooloffPeriod = CooloffPeriod;
592 type Currency = Balances;
593 type EnactmentPeriod = EnactmentPeriod;
596 type ExternalDefaultOrigin = AllCouncil;
600 type ExternalMajorityOrigin = HalfCouncil;
604 type ExternalOrigin = HalfCouncil;
607 type FastTrackOrigin = EnsureRootOr<HalfCouncil>;
610 type FastTrackVotingPeriod = FastTrackVotingPeriod;
612 type InstantAllowed = ConstBool<true>;
613 type InstantOrigin = EnsureRootOr<AllCouncil>;
614 type LaunchPeriod = LaunchPeriod;
616 type MaxBlacklisted = ConstU32<100>;
617 type MaxDeposits = ConstU32<100>;
618 type MaxProposals = ConstU32<100>;
619 type MaxVotes = ConstU32<100>;
620 type MinimumDeposit = ConstU128<{ 1000 * AI3 }>;
623 type PalletsOrigin = OriginCaller;
624 type Preimages = Preimage;
625 type RuntimeEvent = RuntimeEvent;
626 type Scheduler = Scheduler;
627 type Slash = DemocracySlash;
629 type SubmitOrigin = EnsureMember<AccountId, CouncilCollective>;
632 type VetoOrigin = EnsureMember<AccountId, CouncilCollective>;
635 type VoteLockingPeriod = VoteLockingPeriod;
636 type VotingPeriod = VotingPeriod;
638 type WeightInfo = pallet_democracy::weights::SubstrateWeight<Runtime>;
639}
640
641parameter_types! {
642 pub const SelfChainId: ChainId = ChainId::Consensus;
643}
644
645pub struct OnXDMRewards;
646
647impl sp_messenger::OnXDMRewards<Balance> for OnXDMRewards {
648 fn on_xdm_rewards(reward: Balance) {
649 if let Some(block_author) = Subspace::find_block_reward_address() {
650 let _ = Balances::deposit_creating(&block_author, reward);
651 }
652 }
653
654 fn on_chain_protocol_fees(chain_id: ChainId, fees: Balance) {
655 if let ChainId::Domain(domain_id) = chain_id {
658 Domains::reward_domain_operators(domain_id, OperatorRewardSource::XDMProtocolFees, fees)
659 }
660 }
661}
662
663pub struct MmrProofVerifier;
664
665impl sp_subspace_mmr::MmrProofVerifier<mmr::Hash, NumberFor<Block>, Hash> for MmrProofVerifier {
666 fn verify_proof_and_extract_leaf(
667 mmr_leaf_proof: ConsensusChainMmrLeafProof<NumberFor<Block>, Hash, mmr::Hash>,
668 ) -> Option<mmr::Leaf> {
669 let mmr_root = SubspaceMmr::mmr_root_hash(mmr_leaf_proof.consensus_block_number)?;
670 Self::verify_proof_stateless(mmr_root, mmr_leaf_proof)
671 }
672
673 fn verify_proof_stateless(
674 mmr_root: mmr::Hash,
675 mmr_leaf_proof: ConsensusChainMmrLeafProof<NumberFor<Block>, Hash, mmr::Hash>,
676 ) -> Option<mmr::Leaf> {
677 let ConsensusChainMmrLeafProof {
678 opaque_mmr_leaf,
679 proof,
680 ..
681 } = mmr_leaf_proof;
682
683 pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(
684 mmr_root,
685 vec![mmr::DataOrHash::Data(
686 EncodableOpaqueLeaf(opaque_mmr_leaf.0.clone()).into_opaque_leaf(),
687 )],
688 proof,
689 )
690 .ok()?;
691
692 let leaf: mmr::Leaf = opaque_mmr_leaf.into_opaque_leaf().try_decode()?;
693
694 Some(leaf)
695 }
696}
697
698pub struct StorageKeys;
699
700impl sp_messenger::StorageKeys for StorageKeys {
701 fn confirmed_domain_block_storage_key(domain_id: DomainId) -> Option<Vec<u8>> {
702 Some(Domains::confirmed_domain_block_storage_key(domain_id))
703 }
704
705 fn outbox_storage_key(chain_id: ChainId, message_key: MessageKey) -> Option<Vec<u8>> {
706 get_storage_key(StorageKeyRequest::OutboxStorageKey {
707 chain_id,
708 message_key,
709 })
710 }
711
712 fn inbox_responses_storage_key(chain_id: ChainId, message_key: MessageKey) -> Option<Vec<u8>> {
713 get_storage_key(StorageKeyRequest::InboxResponseStorageKey {
714 chain_id,
715 message_key,
716 })
717 }
718}
719
720parameter_types! {
721 pub const ChannelReserveFee: Balance = 100 * AI3;
723 pub const ChannelInitReservePortion: Perbill = Perbill::from_percent(20);
724 pub const MaxOutgoingMessages: u32 = MAX_OUTGOING_MESSAGES;
725}
726
727const_assert!(MaxOutgoingMessages::get() >= 1);
729
730pub struct DomainRegistration;
731impl sp_messenger::DomainRegistration for DomainRegistration {
732 fn is_domain_registered(domain_id: DomainId) -> bool {
733 Domains::is_domain_registered(domain_id)
734 }
735}
736
737impl pallet_messenger::Config for Runtime {
738 type RuntimeEvent = RuntimeEvent;
739 type SelfChainId = SelfChainId;
740
741 fn get_endpoint_handler(endpoint: &Endpoint) -> Option<Box<dyn EndpointHandlerT<MessageId>>> {
742 if endpoint == &Endpoint::Id(TransporterEndpointId::get()) {
743 Some(Box::new(EndpointHandler(PhantomData::<Runtime>)))
744 } else {
745 None
746 }
747 }
748
749 type Currency = Balances;
750 type WeightInfo = pallet_messenger::weights::SubstrateWeight<Runtime>;
751 type WeightToFee = ConstantMultiplier<Balance, TransactionWeightFee>;
752 type AdjustedWeightToFee = XdmAdjustedWeightToFee<Runtime>;
753 type FeeMultiplier = XdmFeeMultipler;
754 type OnXDMRewards = OnXDMRewards;
755 type MmrHash = mmr::Hash;
756 type MmrProofVerifier = MmrProofVerifier;
757 #[cfg(feature = "runtime-benchmarks")]
758 type StorageKeys = sp_messenger::BenchmarkStorageKeys;
759 #[cfg(not(feature = "runtime-benchmarks"))]
760 type StorageKeys = StorageKeys;
761 type DomainOwner = Domains;
762 type HoldIdentifier = HoldIdentifierWrapper;
763 type ChannelReserveFee = ChannelReserveFee;
764 type ChannelInitReservePortion = ChannelInitReservePortion;
765 type DomainRegistration = DomainRegistration;
766 type MaxOutgoingMessages = MaxOutgoingMessages;
767 type MessengerOrigin = pallet_messenger::EnsureMessengerOrigin;
768 type NoteChainTransfer = Transporter;
769 type ExtensionWeightInfo = pallet_messenger::extensions::weights::SubstrateWeight<Runtime>;
770}
771
772impl<C> frame_system::offchain::CreateTransactionBase<C> for Runtime
773where
774 RuntimeCall: From<C>,
775{
776 type Extrinsic = UncheckedExtrinsic;
777 type RuntimeCall = RuntimeCall;
778}
779
780impl<C> frame_system::offchain::CreateInherent<C> for Runtime
781where
782 RuntimeCall: From<C>,
783{
784 fn create_inherent(call: Self::RuntimeCall) -> Self::Extrinsic {
785 UncheckedExtrinsic::new_bare(call)
786 }
787}
788
789impl<C> subspace_runtime_primitives::CreateUnsigned<C> for Runtime
790where
791 RuntimeCall: From<C>,
792{
793 fn create_unsigned(call: Self::RuntimeCall) -> Self::Extrinsic {
794 create_unsigned_general_extrinsic(call)
795 }
796}
797
798parameter_types! {
799 pub const TransporterEndpointId: EndpointId = 1;
800 pub const MinimumTransfer: Balance = AI3;
801}
802
803impl pallet_transporter::Config for Runtime {
804 type RuntimeEvent = RuntimeEvent;
805 type SelfChainId = SelfChainId;
806 type SelfEndpointId = TransporterEndpointId;
807 type Currency = Balances;
808 type Sender = Messenger;
809 type AccountIdConverter = AccountIdConverter;
810 type WeightInfo = pallet_transporter::weights::SubstrateWeight<Runtime>;
811 type SkipBalanceTransferChecks = pallet_domains::DomainsSkipBalanceChecks<Runtime>;
812 type MinimumTransfer = MinimumTransfer;
813}
814
815parameter_types! {
816 pub const MaximumReceiptDrift: BlockNumber = 128;
817 pub const InitialDomainTxRange: u64 = INITIAL_DOMAIN_TX_RANGE;
818 pub const DomainTxRangeAdjustmentInterval: u64 = TX_RANGE_ADJUSTMENT_INTERVAL_BLOCKS;
819 pub const MinOperatorStake: Balance = 100 * AI3;
822 pub const MinNominatorStake: Balance = AI3;
825 pub MaxDomainBlockSize: u32 = NORMAL_DISPATCH_RATIO * MAX_BLOCK_LENGTH;
827 pub MaxDomainBlockWeight: Weight = maximum_domain_block_weight();
829 pub const DomainInstantiationDeposit: Balance = 100 * AI3;
830 pub const MaxDomainNameLength: u32 = 32;
831 pub const BlockTreePruningDepth: u32 = DOMAINS_BLOCK_PRUNING_DEPTH;
832 pub const StakeWithdrawalLockingPeriod: DomainNumber = 14_400;
833 pub const StakeEpochDuration: DomainNumber = 100;
836 pub TreasuryAccount: AccountId = PalletId(*b"treasury").into_account_truncating();
837 pub const MaxPendingStakingOperation: u32 = 512;
838 pub const DomainsPalletId: PalletId = PalletId(*b"domains_");
839 pub const MaxInitialDomainAccounts: u32 = 10;
840 pub const MinInitialDomainAccountBalance: Balance = AI3;
841 pub const BundleLongevity: u32 = 5;
842 pub const WithdrawalLimit: u32 = 32;
843}
844
845const_assert!(BlockSlotCount::get() >= 2 && BlockSlotCount::get() > BundleLongevity::get());
848
849const_assert!(BlockHashCount::get() > BlockSlotCount::get());
852
853const_assert!(MinOperatorStake::get() >= MinNominatorStake::get());
855
856const_assert!(StakeWithdrawalLockingPeriod::get() >= BlockTreePruningDepth::get());
858
859pub struct BlockSlot;
860
861impl pallet_domains::BlockSlot<Runtime> for BlockSlot {
862 fn future_slot(block_number: BlockNumber) -> Option<sp_consensus_slots::Slot> {
863 let block_slots = Subspace::block_slots();
864 block_slots
865 .get(&block_number)
866 .map(|slot| *slot + Slot::from(BlockAuthoringDelay::get()))
867 }
868
869 fn slot_produced_after(to_check: sp_consensus_slots::Slot) -> Option<BlockNumber> {
870 let block_slots = Subspace::block_slots();
871 for (block_number, slot) in block_slots.into_iter().rev() {
872 if to_check > slot {
873 return Some(block_number);
874 }
875 }
876 None
877 }
878}
879
880pub struct OnChainRewards;
881
882impl sp_domains::OnChainRewards<Balance> for OnChainRewards {
883 fn on_chain_rewards(chain_id: ChainId, reward: Balance) {
884 match chain_id {
885 ChainId::Consensus => {
886 if let Some(block_author) = Subspace::find_block_reward_address() {
887 let _ = Balances::deposit_creating(&block_author, reward);
888 }
889 }
890 ChainId::Domain(domain_id) => Domains::reward_domain_operators(
891 domain_id,
892 OperatorRewardSource::XDMProtocolFees,
893 reward,
894 ),
895 }
896 }
897}
898
899impl pallet_domains::Config for Runtime {
900 type RuntimeEvent = RuntimeEvent;
901 type DomainOrigin = pallet_domains::EnsureDomainOrigin;
902 type DomainHash = DomainHash;
903 type Balance = Balance;
904 type DomainHeader = sp_runtime::generic::Header<DomainNumber, BlakeTwo256>;
905 type ConfirmationDepthK = ConfirmationDepthK;
906 type Currency = Balances;
907 type Share = Balance;
908 type HoldIdentifier = HoldIdentifierWrapper;
909 type BlockTreePruningDepth = BlockTreePruningDepth;
910 type ConsensusSlotProbability = SlotProbability;
911 type MaxDomainBlockSize = MaxDomainBlockSize;
912 type MaxDomainBlockWeight = MaxDomainBlockWeight;
913 type MaxDomainNameLength = MaxDomainNameLength;
914 type DomainInstantiationDeposit = DomainInstantiationDeposit;
915 type WeightInfo = pallet_domains::weights::SubstrateWeight<Runtime>;
916 type InitialDomainTxRange = InitialDomainTxRange;
917 type DomainTxRangeAdjustmentInterval = DomainTxRangeAdjustmentInterval;
918 type MinOperatorStake = MinOperatorStake;
919 type MinNominatorStake = MinNominatorStake;
920 type StakeWithdrawalLockingPeriod = StakeWithdrawalLockingPeriod;
921 type StakeEpochDuration = StakeEpochDuration;
922 type TreasuryAccount = TreasuryAccount;
923 type MaxPendingStakingOperation = MaxPendingStakingOperation;
924 type Randomness = Subspace;
925 type PalletId = DomainsPalletId;
926 type StorageFee = TransactionFees;
927 type BlockTimestamp = pallet_timestamp::Pallet<Runtime>;
928 type BlockSlot = BlockSlot;
929 type DomainsTransfersTracker = Transporter;
930 type MaxInitialDomainAccounts = MaxInitialDomainAccounts;
931 type MinInitialDomainAccountBalance = MinInitialDomainAccountBalance;
932 type BundleLongevity = BundleLongevity;
933 type DomainBundleSubmitted = Messenger;
934 type OnDomainInstantiated = Messenger;
935 type MmrHash = mmr::Hash;
936 type MmrProofVerifier = MmrProofVerifier;
937 type FraudProofStorageKeyProvider = StorageKeyProvider;
938 type OnChainRewards = OnChainRewards;
939 type WithdrawalLimit = WithdrawalLimit;
940}
941
942parameter_types! {
943 pub const AvgBlockspaceUsageNumBlocks: BlockNumber = 100;
944 pub const ProposerTaxOnVotes: (u32, u32) = (1, 10);
945}
946
947impl pallet_rewards::Config for Runtime {
948 type RuntimeEvent = RuntimeEvent;
949 type Currency = Balances;
950 type AvgBlockspaceUsageNumBlocks = AvgBlockspaceUsageNumBlocks;
951 type TransactionByteFee = TransactionByteFee;
952 type MaxRewardPoints = ConstU32<20>;
953 type ProposerTaxOnVotes = ProposerTaxOnVotes;
954 type RewardsEnabled = Subspace;
955 type FindBlockRewardAddress = Subspace;
956 type FindVotingRewardAddresses = Subspace;
957 type WeightInfo = pallet_rewards::weights::SubstrateWeight<Runtime>;
958 type OnReward = ();
959}
960
961impl pallet_runtime_configs::Config for Runtime {
962 type WeightInfo = pallet_runtime_configs::weights::SubstrateWeight<Runtime>;
963}
964
965mod mmr {
966 use super::Runtime;
967 pub use pallet_mmr::primitives::*;
968
969 pub type Leaf = <<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider>::LeafData;
970 pub type Hashing = <Runtime as pallet_mmr::Config>::Hashing;
971 pub type Hash = <Hashing as sp_runtime::traits::Hash>::Output;
972}
973
974pub struct BlockHashProvider;
975
976impl pallet_mmr::BlockHashProvider<BlockNumber, Hash> for BlockHashProvider {
977 fn block_hash(block_number: BlockNumber) -> Hash {
978 consensus_block_hash(block_number).expect("Hash must exist for a given block number.")
979 }
980}
981
982impl pallet_mmr::Config for Runtime {
983 const INDEXING_PREFIX: &'static [u8] = mmr::INDEXING_PREFIX;
984 type Hashing = Keccak256;
985 type LeafData = SubspaceMmr;
986 type OnNewRoot = SubspaceMmr;
987 type BlockHashProvider = BlockHashProvider;
988 type WeightInfo = ();
989 #[cfg(feature = "runtime-benchmarks")]
990 type BenchmarkHelper = ();
991}
992
993parameter_types! {
994 pub const MmrRootHashCount: u32 = 1024;
995}
996
997impl pallet_subspace_mmr::Config for Runtime {
998 type MmrRootHash = mmr::Hash;
999 type MmrRootHashCount = MmrRootHashCount;
1000}
1001
1002parameter_types! {
1003 pub const MaxSignatories: u32 = 100;
1004}
1005
1006macro_rules! deposit {
1007 ($name:ident, $item_fee:expr, $items:expr, $bytes:expr) => {
1008 pub struct $name;
1009
1010 impl Get<Balance> for $name {
1011 fn get() -> Balance {
1012 $item_fee.saturating_mul($items.into()).saturating_add(
1013 TransactionFees::transaction_byte_fee().saturating_mul($bytes.into()),
1014 )
1015 }
1016 }
1017 };
1018}
1019
1020deposit!(DepositBaseFee, 20 * AI3, 1u32, 88u32);
1023
1024deposit!(DepositFactor, 0u128, 0u32, 32u32);
1026
1027impl pallet_multisig::Config for Runtime {
1028 type RuntimeEvent = RuntimeEvent;
1029 type RuntimeCall = RuntimeCall;
1030 type Currency = Balances;
1031 type DepositBase = DepositBaseFee;
1032 type DepositFactor = DepositFactor;
1033 type MaxSignatories = MaxSignatories;
1034 type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
1035}
1036
1037construct_runtime!(
1038 pub struct Runtime {
1039 System: frame_system = 0,
1040 Timestamp: pallet_timestamp = 1,
1041
1042 Subspace: pallet_subspace = 2,
1043 Rewards: pallet_rewards = 4,
1044
1045 Balances: pallet_balances = 5,
1046 TransactionFees: pallet_transaction_fees = 6,
1047 TransactionPayment: pallet_transaction_payment = 7,
1048 Utility: pallet_utility = 8,
1049
1050 Domains: pallet_domains = 12,
1051 RuntimeConfigs: pallet_runtime_configs = 14,
1052
1053 Mmr: pallet_mmr = 30,
1054 SubspaceMmr: pallet_subspace_mmr = 31,
1055
1056 Messenger: pallet_messenger exclude_parts { Inherent } = 60,
1059 Transporter: pallet_transporter = 61,
1060
1061 Scheduler: pallet_scheduler = 81,
1063 Council: pallet_collective::<Instance1> = 82,
1064 Democracy: pallet_democracy = 83,
1065 Preimage: pallet_preimage = 84,
1066
1067 Multisig: pallet_multisig = 90,
1069
1070 Sudo: pallet_sudo = 100,
1072 }
1073);
1074
1075pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
1077pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
1079pub type Block = generic::Block<Header, UncheckedExtrinsic>;
1081
1082pub type SignedExtra = (
1084 frame_system::CheckNonZeroSender<Runtime>,
1085 frame_system::CheckSpecVersion<Runtime>,
1086 frame_system::CheckTxVersion<Runtime>,
1087 frame_system::CheckGenesis<Runtime>,
1088 frame_system::CheckMortality<Runtime>,
1089 frame_system::CheckNonce<Runtime>,
1090 frame_system::CheckWeight<Runtime>,
1091 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
1092 DisablePallets,
1093 pallet_subspace::extensions::SubspaceExtension<Runtime>,
1094 pallet_domains::extensions::DomainsExtension<Runtime>,
1095 pallet_messenger::extensions::MessengerExtension<Runtime>,
1096);
1097pub type UncheckedExtrinsic =
1099 generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
1100
1101pub type Executive = frame_executive::Executive<
1103 Runtime,
1104 Block,
1105 frame_system::ChainContext<Runtime>,
1106 Runtime,
1107 AllPalletsWithSystem,
1108 (
1110 pallet_domains::migrations::VersionCheckedMigrateDomainsV1ToV5<Runtime>,
1111 pallet_messenger::migrations::VersionCheckedMigrateDomainsV0ToV1<Runtime>,
1112 pallet_messenger::migrations::VersionCheckedMigrateDomainsV1ToV2<Runtime>,
1113 ),
1114>;
1115
1116impl pallet_subspace::extensions::MaybeSubspaceCall<Runtime> for RuntimeCall {
1117 fn maybe_subspace_call(&self) -> Option<&pallet_subspace::Call<Runtime>> {
1118 match self {
1119 RuntimeCall::Subspace(call) => Some(call),
1120 _ => None,
1121 }
1122 }
1123}
1124
1125impl pallet_domains::extensions::MaybeDomainsCall<Runtime> for RuntimeCall {
1126 fn maybe_domains_call(&self) -> Option<&pallet_domains::Call<Runtime>> {
1127 match self {
1128 RuntimeCall::Domains(call) => Some(call),
1129 _ => None,
1130 }
1131 }
1132}
1133
1134impl pallet_messenger::extensions::MaybeMessengerCall<Runtime> for RuntimeCall {
1135 fn maybe_messenger_call(&self) -> Option<&pallet_messenger::Call<Runtime>> {
1136 match self {
1137 RuntimeCall::Messenger(call) => Some(call),
1138 _ => None,
1139 }
1140 }
1141}
1142
1143fn extract_segment_headers(ext: &UncheckedExtrinsic) -> Option<Vec<SegmentHeader>> {
1144 match &ext.function {
1145 RuntimeCall::Subspace(pallet_subspace::Call::store_segment_headers { segment_headers }) => {
1146 Some(segment_headers.clone())
1147 }
1148 _ => None,
1149 }
1150}
1151
1152fn is_xdm_mmr_proof_valid(ext: &ExtrinsicFor<Block>) -> Option<bool> {
1153 match &ext.function {
1154 RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg })
1155 | RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => {
1156 let ConsensusChainMmrLeafProof {
1157 consensus_block_number,
1158 opaque_mmr_leaf,
1159 proof,
1160 ..
1161 } = msg.proof.consensus_mmr_proof();
1162
1163 let mmr_root = SubspaceMmr::mmr_root_hash(consensus_block_number)?;
1164
1165 Some(
1166 pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(
1167 mmr_root,
1168 vec![mmr::DataOrHash::Data(
1169 EncodableOpaqueLeaf(opaque_mmr_leaf.0.clone()).into_opaque_leaf(),
1170 )],
1171 proof,
1172 )
1173 .is_ok(),
1174 )
1175 }
1176 _ => None,
1177 }
1178}
1179
1180fn create_unsigned_general_extrinsic(call: RuntimeCall) -> UncheckedExtrinsic {
1181 let extra: SignedExtra = (
1182 frame_system::CheckNonZeroSender::<Runtime>::new(),
1183 frame_system::CheckSpecVersion::<Runtime>::new(),
1184 frame_system::CheckTxVersion::<Runtime>::new(),
1185 frame_system::CheckGenesis::<Runtime>::new(),
1186 frame_system::CheckMortality::<Runtime>::from(generic::Era::Immortal),
1187 frame_system::CheckNonce::<Runtime>::from(0u32.into()),
1190 frame_system::CheckWeight::<Runtime>::new(),
1191 pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(0u128),
1194 DisablePallets,
1195 pallet_subspace::extensions::SubspaceExtension::<Runtime>::new(),
1196 pallet_domains::extensions::DomainsExtension::<Runtime>::new(),
1197 pallet_messenger::extensions::MessengerExtension::<Runtime>::new(),
1198 );
1199
1200 UncheckedExtrinsic::new_transaction(call, extra)
1201}
1202
1203struct RewardAddress([u8; 32]);
1204
1205impl From<PublicKey> for RewardAddress {
1206 #[inline]
1207 fn from(public_key: PublicKey) -> Self {
1208 Self(*public_key)
1209 }
1210}
1211
1212impl From<RewardAddress> for AccountId32 {
1213 #[inline]
1214 fn from(reward_address: RewardAddress) -> Self {
1215 reward_address.0.into()
1216 }
1217}
1218
1219pub struct StorageKeyProvider;
1220impl FraudProofStorageKeyProvider<NumberFor<Block>> for StorageKeyProvider {
1221 fn storage_key(req: FraudProofStorageKeyRequest<NumberFor<Block>>) -> Vec<u8> {
1222 match req {
1223 FraudProofStorageKeyRequest::InvalidInherentExtrinsicData => {
1224 pallet_domains::BlockInherentExtrinsicData::<Runtime>::hashed_key().to_vec()
1225 }
1226 FraudProofStorageKeyRequest::SuccessfulBundles(domain_id) => {
1227 pallet_domains::SuccessfulBundles::<Runtime>::hashed_key_for(domain_id)
1228 }
1229 FraudProofStorageKeyRequest::DomainAllowlistUpdates(domain_id) => {
1230 Messenger::domain_allow_list_update_storage_key(domain_id)
1231 }
1232 FraudProofStorageKeyRequest::DomainRuntimeUpgrades => {
1233 pallet_domains::DomainRuntimeUpgrades::<Runtime>::hashed_key().to_vec()
1234 }
1235 FraudProofStorageKeyRequest::RuntimeRegistry(runtime_id) => {
1236 pallet_domains::RuntimeRegistry::<Runtime>::hashed_key_for(runtime_id)
1237 }
1238 FraudProofStorageKeyRequest::DomainSudoCall(domain_id) => {
1239 pallet_domains::DomainSudoCalls::<Runtime>::hashed_key_for(domain_id)
1240 }
1241 FraudProofStorageKeyRequest::EvmDomainContractCreationAllowedByCall(domain_id) => {
1242 pallet_domains::EvmDomainContractCreationAllowedByCalls::<Runtime>::hashed_key_for(
1243 domain_id,
1244 )
1245 }
1246 FraudProofStorageKeyRequest::MmrRoot(block_number) => {
1247 pallet_subspace_mmr::MmrRootHashes::<Runtime>::hashed_key_for(block_number)
1248 }
1249 }
1250 }
1251}
1252
1253#[cfg(feature = "runtime-benchmarks")]
1254mod benches {
1255 frame_benchmarking::define_benchmarks!(
1256 [frame_benchmarking, BaselineBench::<Runtime>]
1257 [frame_system, SystemBench::<Runtime>]
1258 [pallet_balances, Balances]
1259 [pallet_domains, Domains]
1260 [pallet_mmr, Mmr]
1261 [pallet_rewards, Rewards]
1262 [pallet_runtime_configs, RuntimeConfigs]
1263 [pallet_subspace, Subspace]
1264 [pallet_timestamp, Timestamp]
1265 [pallet_messenger, Messenger]
1266 [pallet_transporter, Transporter]
1267 [pallet_subspace_extension, SubspaceExtensionBench::<Runtime>]
1268 [pallet_messenger_from_domains_extension, MessengerFromDomainsExtensionBench::<Runtime>]
1269 );
1270}
1271
1272#[cfg(feature = "runtime-benchmarks")]
1273impl frame_system_benchmarking::Config for Runtime {}
1274
1275#[cfg(feature = "runtime-benchmarks")]
1276impl frame_benchmarking::baseline::Config for Runtime {}
1277
1278impl_runtime_apis! {
1279 impl sp_api::Core<Block> for Runtime {
1280 fn version() -> RuntimeVersion {
1281 VERSION
1282 }
1283
1284 fn execute_block(block: Block) {
1285 Executive::execute_block(block);
1286 }
1287
1288 fn initialize_block(header: &HeaderFor<Block>) -> ExtrinsicInclusionMode {
1289 Executive::initialize_block(header)
1290 }
1291 }
1292
1293 impl sp_api::Metadata<Block> for Runtime {
1294 fn metadata() -> OpaqueMetadata {
1295 OpaqueMetadata::new(Runtime::metadata().into())
1296 }
1297
1298 fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
1299 Runtime::metadata_at_version(version)
1300 }
1301
1302 fn metadata_versions() -> Vec<u32> {
1303 Runtime::metadata_versions()
1304 }
1305 }
1306
1307 impl sp_block_builder::BlockBuilder<Block> for Runtime {
1308 fn apply_extrinsic(extrinsic: ExtrinsicFor<Block>) -> ApplyExtrinsicResult {
1309 Executive::apply_extrinsic(extrinsic)
1310 }
1311
1312 fn finalize_block() -> HeaderFor<Block> {
1313 Executive::finalize_block()
1314 }
1315
1316 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<ExtrinsicFor<Block>> {
1317 data.create_extrinsics()
1318 }
1319
1320 fn check_inherents(
1321 block: Block,
1322 data: sp_inherents::InherentData,
1323 ) -> sp_inherents::CheckInherentsResult {
1324 data.check_extrinsics(&block)
1325 }
1326 }
1327
1328 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
1329 fn validate_transaction(
1330 source: TransactionSource,
1331 tx: ExtrinsicFor<Block>,
1332 block_hash: BlockHashFor<Block>,
1333 ) -> TransactionValidity {
1334 Executive::validate_transaction(source, tx, block_hash)
1335 }
1336 }
1337
1338 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
1339 fn offchain_worker(header: &HeaderFor<Block>) {
1340 Executive::offchain_worker(header)
1341 }
1342 }
1343
1344 impl sp_objects::ObjectsApi<Block> for Runtime {
1345 fn extract_block_object_mapping(block: Block) -> BlockObjectMapping {
1346 extract_block_object_mapping(block)
1347 }
1348 }
1349
1350 impl sp_consensus_subspace::SubspaceApi<Block, PublicKey> for Runtime {
1351 fn pot_parameters() -> PotParameters {
1352 Subspace::pot_parameters()
1353 }
1354
1355 fn solution_ranges() -> SolutionRanges {
1356 Subspace::solution_ranges()
1357 }
1358
1359 fn submit_vote_extrinsic(
1360 signed_vote: SignedVote<NumberFor<Block>, BlockHashFor<Block>, PublicKey>,
1361 ) {
1362 let SignedVote { vote, signature } = signed_vote;
1363 let Vote::V0 {
1364 height,
1365 parent_hash,
1366 slot,
1367 solution,
1368 proof_of_time,
1369 future_proof_of_time,
1370 } = vote;
1371
1372 Subspace::submit_vote(SignedVote {
1373 vote: Vote::V0 {
1374 height,
1375 parent_hash,
1376 slot,
1377 solution: solution.into_reward_address_format::<RewardAddress, AccountId32>(),
1378 proof_of_time,
1379 future_proof_of_time,
1380 },
1381 signature,
1382 })
1383 }
1384
1385 fn history_size() -> HistorySize {
1386 <pallet_subspace::Pallet<Runtime>>::history_size()
1387 }
1388
1389 fn max_pieces_in_sector() -> u16 {
1390 MAX_PIECES_IN_SECTOR
1391 }
1392
1393 fn segment_commitment(segment_index: SegmentIndex) -> Option<SegmentCommitment> {
1394 Subspace::segment_commitment(segment_index)
1395 }
1396
1397 fn extract_segment_headers(ext: &ExtrinsicFor<Block>) -> Option<Vec<SegmentHeader >> {
1398 extract_segment_headers(ext)
1399 }
1400
1401 fn is_inherent(ext: &ExtrinsicFor<Block>) -> bool {
1402 match &ext.function {
1403 RuntimeCall::Subspace(call) => Subspace::is_inherent(call),
1404 RuntimeCall::Timestamp(call) => Timestamp::is_inherent(call),
1405 _ => false,
1406 }
1407 }
1408
1409 fn root_plot_public_key() -> Option<PublicKey> {
1410 Subspace::root_plot_public_key()
1411 }
1412
1413 fn should_adjust_solution_range() -> bool {
1414 Subspace::should_adjust_solution_range()
1415 }
1416
1417 fn chain_constants() -> ChainConstants {
1418 ChainConstants::V0 {
1419 confirmation_depth_k: ConfirmationDepthK::get(),
1420 block_authoring_delay: Slot::from(BlockAuthoringDelay::get()),
1421 era_duration: EraDuration::get(),
1422 slot_probability: SlotProbability::get(),
1423 slot_duration: SlotDuration::from_millis(SLOT_DURATION),
1424 recent_segments: RecentSegments::get(),
1425 recent_history_fraction: RecentHistoryFraction::get(),
1426 min_sector_lifetime: MinSectorLifetime::get(),
1427 }
1428 }
1429 }
1430
1431 impl sp_domains::DomainsApi<Block, DomainHeader> for Runtime {
1432 fn submit_bundle_unsigned(
1433 opaque_bundle: sp_domains::OpaqueBundle<NumberFor<Block>, BlockHashFor<Block>, DomainHeader, Balance>,
1434 ) {
1435 Domains::submit_bundle_unsigned(opaque_bundle)
1436 }
1437
1438 fn submit_receipt_unsigned(
1439 singleton_receipt: sp_domains::SealedSingletonReceipt<NumberFor<Block>, BlockHashFor<Block>, DomainHeader, Balance>,
1440 ) {
1441 Domains::submit_receipt_unsigned(singleton_receipt)
1442 }
1443
1444 fn extract_successful_bundles(
1445 domain_id: DomainId,
1446 extrinsics: Vec<ExtrinsicFor<Block>>,
1447 ) -> sp_domains::OpaqueBundles<Block, DomainHeader, Balance> {
1448 crate::domains::extract_successful_bundles(domain_id, extrinsics)
1449 }
1450
1451 fn extrinsics_shuffling_seed() -> Randomness {
1452 Randomness::from(Domains::extrinsics_shuffling_seed().to_fixed_bytes())
1453 }
1454
1455 fn domain_runtime_code(domain_id: DomainId) -> Option<Vec<u8>> {
1456 Domains::domain_runtime_code(domain_id)
1457 }
1458
1459 fn runtime_id(domain_id: DomainId) -> Option<sp_domains::RuntimeId> {
1460 Domains::runtime_id(domain_id)
1461 }
1462
1463 fn runtime_upgrades() -> Vec<sp_domains::RuntimeId> {
1464 Domains::runtime_upgrades()
1465 }
1466
1467 fn domain_instance_data(domain_id: DomainId) -> Option<(DomainInstanceData, NumberFor<Block>)> {
1468 Domains::domain_instance_data(domain_id)
1469 }
1470
1471 fn domain_timestamp() -> Moment {
1472 Domains::timestamp()
1473 }
1474
1475 fn timestamp() -> Moment {
1476 Timestamp::now()
1477 }
1478
1479 fn consensus_transaction_byte_fee() -> Balance {
1480 Domains::consensus_transaction_byte_fee()
1481 }
1482
1483 fn consensus_chain_byte_fee() -> Balance {
1484 DOMAIN_STORAGE_FEE_MULTIPLIER * TransactionFees::transaction_byte_fee()
1485 }
1486
1487 fn domain_tx_range(domain_id: DomainId) -> U256 {
1488 Domains::domain_tx_range(domain_id)
1489 }
1490
1491 fn genesis_state_root(domain_id: DomainId) -> Option<H256> {
1492 Domains::genesis_state_root(domain_id)
1493 }
1494
1495 fn head_receipt_number(domain_id: DomainId) -> DomainNumber {
1496 Domains::head_receipt_number(domain_id)
1497 }
1498
1499 fn oldest_unconfirmed_receipt_number(domain_id: DomainId) -> Option<DomainNumber> {
1500 Domains::oldest_unconfirmed_receipt_number(domain_id)
1501 }
1502
1503 fn domain_bundle_limit(domain_id: DomainId) -> Option<sp_domains::DomainBundleLimit> {
1504 Domains::domain_bundle_limit(domain_id).ok().flatten()
1505 }
1506
1507 fn non_empty_er_exists(domain_id: DomainId) -> bool {
1508 Domains::non_empty_er_exists(domain_id)
1509 }
1510
1511 fn domain_best_number(domain_id: DomainId) -> Option<DomainNumber> {
1512 Domains::domain_best_number(domain_id).ok()
1513 }
1514
1515 fn execution_receipt(receipt_hash: DomainHash) -> Option<ExecutionReceiptFor<DomainHeader, Block, Balance>> {
1516 Domains::execution_receipt(receipt_hash)
1517 }
1518
1519 fn domain_operators(domain_id: DomainId) -> Option<(BTreeMap<OperatorId, Balance>, Vec<OperatorId>)> {
1520 Domains::domain_staking_summary(domain_id).map(|summary| {
1521 let next_operators = summary.next_operators.into_iter().collect();
1522 (summary.current_operators, next_operators)
1523 })
1524 }
1525
1526 fn receipt_hash(domain_id: DomainId, domain_number: DomainNumber) -> Option<DomainHash> {
1527 Domains::receipt_hash(domain_id, domain_number)
1528 }
1529
1530 fn latest_confirmed_domain_block(domain_id: DomainId) -> Option<(DomainNumber, DomainHash)>{
1531 Domains::latest_confirmed_domain_block(domain_id)
1532 }
1533
1534 fn is_bad_er_pending_to_prune(domain_id: DomainId, receipt_hash: DomainHash) -> bool {
1535 Domains::execution_receipt(receipt_hash).map(
1536 |er| Domains::is_bad_er_pending_to_prune(domain_id, er.domain_block_number)
1537 )
1538 .unwrap_or(false)
1539 }
1540
1541 fn storage_fund_account_balance(operator_id: OperatorId) -> Balance {
1542 Domains::storage_fund_account_balance(operator_id)
1543 }
1544
1545 fn is_domain_runtime_upgraded_since(domain_id: DomainId, at: NumberFor<Block>) -> Option<bool> {
1546 Domains::is_domain_runtime_upgraded_since(domain_id, at)
1547 }
1548
1549 fn domain_sudo_call(domain_id: DomainId) -> Option<Vec<u8>> {
1550 Domains::domain_sudo_call(domain_id)
1551 }
1552
1553 fn evm_domain_contract_creation_allowed_by_call(domain_id: DomainId) -> Option<PermissionedActionAllowedBy<EthereumAccountId>> {
1554 Domains::evm_domain_contract_creation_allowed_by_call(domain_id)
1555 }
1556
1557 fn last_confirmed_domain_block_receipt(domain_id: DomainId) -> Option<ExecutionReceiptFor<DomainHeader, Block, Balance>>{
1558 Domains::latest_confirmed_domain_execution_receipt(domain_id)
1559 }
1560 }
1561
1562 impl sp_domains::BundleProducerElectionApi<Block, Balance> for Runtime {
1563 fn bundle_producer_election_params(domain_id: DomainId) -> Option<BundleProducerElectionParams<Balance>> {
1564 Domains::bundle_producer_election_params(domain_id)
1565 }
1566
1567 fn operator(operator_id: OperatorId) -> Option<(OperatorPublicKey, Balance)> {
1568 Domains::operator(operator_id)
1569 }
1570 }
1571
1572 impl sp_session::SessionKeys<Block> for Runtime {
1573 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
1574 SessionKeys::generate(seed)
1575 }
1576
1577 fn decode_session_keys(
1578 encoded: Vec<u8>,
1579 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
1580 SessionKeys::decode_into_raw_public_keys(&encoded)
1581 }
1582 }
1583
1584 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
1585 fn account_nonce(account: AccountId) -> Nonce {
1586 *System::account_nonce(account)
1587 }
1588 }
1589
1590 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
1591 fn query_info(
1592 uxt: ExtrinsicFor<Block>,
1593 len: u32,
1594 ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
1595 TransactionPayment::query_info(uxt, len)
1596 }
1597 fn query_fee_details(
1598 uxt: ExtrinsicFor<Block>,
1599 len: u32,
1600 ) -> pallet_transaction_payment::FeeDetails<Balance> {
1601 TransactionPayment::query_fee_details(uxt, len)
1602 }
1603 fn query_weight_to_fee(weight: Weight) -> Balance {
1604 TransactionPayment::weight_to_fee(weight)
1605 }
1606 fn query_length_to_fee(length: u32) -> Balance {
1607 TransactionPayment::length_to_fee(length)
1608 }
1609 }
1610
1611 impl sp_messenger::MessengerApi<Block, BlockNumber, BlockHashFor<Block>> for Runtime {
1612 fn is_xdm_mmr_proof_valid(
1613 ext: &ExtrinsicFor<Block>
1614 ) -> Option<bool> {
1615 is_xdm_mmr_proof_valid(ext)
1616 }
1617
1618 fn extract_xdm_mmr_proof(ext: &ExtrinsicFor<Block>) -> Option<ConsensusChainMmrLeafProof<BlockNumber, BlockHashFor<Block>, sp_core::H256>> {
1619 match &ext.function {
1620 RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg })
1621 | RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => {
1622 Some(msg.proof.consensus_mmr_proof())
1623 }
1624 _ => None,
1625 }
1626 }
1627
1628 fn batch_extract_xdm_mmr_proof(extrinsics: &Vec<ExtrinsicFor<Block>>) -> BTreeMap<u32, ConsensusChainMmrLeafProof<BlockNumber, BlockHashFor<Block>, sp_core::H256>> {
1629 let mut mmr_proofs = BTreeMap::new();
1630 for (index, ext) in extrinsics.iter().enumerate() {
1631 match &ext.function {
1632 RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg })
1633 | RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => {
1634 mmr_proofs.insert(index as u32, msg.proof.consensus_mmr_proof());
1635 }
1636 _ => {},
1637 }
1638 }
1639 mmr_proofs
1640 }
1641
1642 fn confirmed_domain_block_storage_key(domain_id: DomainId) -> Vec<u8> {
1643 Domains::confirmed_domain_block_storage_key(domain_id)
1644 }
1645
1646 fn outbox_storage_key(message_key: MessageKey) -> Vec<u8> {
1647 Messenger::outbox_storage_key(message_key)
1648 }
1649
1650 fn inbox_response_storage_key(message_key: MessageKey) -> Vec<u8> {
1651 Messenger::inbox_response_storage_key(message_key)
1652 }
1653
1654 fn domain_chains_allowlist_update(domain_id: DomainId) -> Option<DomainAllowlistUpdates>{
1655 Messenger::domain_chains_allowlist_update(domain_id)
1656 }
1657
1658 fn xdm_id(ext: &ExtrinsicFor<Block>) -> Option<XdmId> {
1659 match &ext.function {
1660 RuntimeCall::Messenger(pallet_messenger::Call::relay_message { msg })=> {
1661 Some(XdmId::RelayMessage((msg.src_chain_id, msg.channel_id, msg.nonce)))
1662 }
1663 RuntimeCall::Messenger(pallet_messenger::Call::relay_message_response { msg }) => {
1664 Some(XdmId::RelayResponseMessage((msg.src_chain_id, msg.channel_id, msg.nonce)))
1665 }
1666 _ => None,
1667 }
1668 }
1669
1670 fn channel_nonce(chain_id: ChainId, channel_id: ChannelId) -> Option<ChannelNonce> {
1671 Messenger::channel_nonce(chain_id, channel_id)
1672 }
1673 }
1674
1675 impl sp_messenger::RelayerApi<Block, BlockNumber, BlockNumber, BlockHashFor<Block>> for Runtime {
1676 fn block_messages() -> BlockMessagesWithStorageKey {
1677 BlockMessagesWithStorageKey::default()
1678 }
1679
1680 fn outbox_message_unsigned(msg: CrossDomainMessage<NumberFor<Block>, BlockHashFor<Block>, BlockHashFor<Block>>) -> Option<ExtrinsicFor<Block>> {
1681 Messenger::outbox_message_unsigned(msg)
1682 }
1683
1684 fn inbox_response_message_unsigned(msg: CrossDomainMessage<NumberFor<Block>, BlockHashFor<Block>, BlockHashFor<Block>>) -> Option<ExtrinsicFor<Block>> {
1685 Messenger::inbox_response_message_unsigned(msg)
1686 }
1687
1688 fn should_relay_outbox_message(_: ChainId, _: MessageId) -> bool {
1689 false
1690 }
1691
1692 fn should_relay_inbox_message_response(_: ChainId, _: MessageId) -> bool {
1693 false
1694 }
1695
1696 fn updated_channels() -> BTreeSet<(ChainId, ChannelId)> {
1697 Messenger::updated_channels()
1698 }
1699
1700 fn channel_storage_key(chain_id: ChainId, channel_id: ChannelId) -> Vec<u8> {
1701 Messenger::channel_storage_key(chain_id, channel_id)
1702 }
1703
1704 fn open_channels() -> BTreeSet<(ChainId, ChannelId)> {
1705 Messenger::open_channels()
1706 }
1707
1708 fn block_messages_with_query(query: BlockMessagesQuery) -> MessagesWithStorageKey {
1709 Messenger::get_block_messages(query)
1710 }
1711
1712 fn channels_and_state() -> Vec<(ChainId, ChannelId, ChannelStateWithNonce)> {
1713 Messenger::channels_and_states()
1714 }
1715
1716 fn first_outbox_message_nonce_to_relay(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1717 Messenger::first_outbox_message_nonce_to_relay(dst_chain_id, channel_id, from_nonce)
1718 }
1719
1720 fn first_inbox_message_response_nonce_to_relay(dst_chain_id: ChainId, channel_id: ChannelId, from_nonce: XdmNonce) -> Option<XdmNonce> {
1721 Messenger::first_inbox_message_response_nonce_to_relay(dst_chain_id, channel_id, from_nonce)
1722 }
1723 }
1724
1725 impl sp_domains_fraud_proof::FraudProofApi<Block, DomainHeader> for Runtime {
1726 fn submit_fraud_proof_unsigned(fraud_proof: FraudProof<NumberFor<Block>, BlockHashFor<Block>, DomainHeader, H256>) {
1727 Domains::submit_fraud_proof_unsigned(fraud_proof)
1728 }
1729
1730 fn fraud_proof_storage_key(req: FraudProofStorageKeyRequest<NumberFor<Block>>) -> Vec<u8> {
1731 <StorageKeyProvider as FraudProofStorageKeyProvider<NumberFor<Block>>>::storage_key(req)
1732 }
1733 }
1734
1735 impl mmr::MmrApi<Block, mmr::Hash, BlockNumber> for Runtime {
1736 fn mmr_root() -> Result<mmr::Hash, mmr::Error> {
1737 Ok(Mmr::mmr_root())
1738 }
1739
1740 fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
1741 Ok(Mmr::mmr_leaves())
1742 }
1743
1744 fn generate_proof(
1745 block_numbers: Vec<BlockNumber>,
1746 best_known_block_number: Option<BlockNumber>,
1747 ) -> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::LeafProof<mmr::Hash>), mmr::Error> {
1748 Mmr::generate_proof(block_numbers, best_known_block_number).map(
1749 |(leaves, proof)| {
1750 (
1751 leaves
1752 .into_iter()
1753 .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf))
1754 .collect(),
1755 proof,
1756 )
1757 },
1758 )
1759 }
1760
1761 fn verify_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::LeafProof<mmr::Hash>)
1762 -> Result<(), mmr::Error>
1763 {
1764 let leaves = leaves.into_iter().map(|leaf|
1765 leaf.into_opaque_leaf()
1766 .try_decode()
1767 .ok_or(mmr::Error::Verify)).collect::<Result<Vec<mmr::Leaf>, mmr::Error>>()?;
1768 Mmr::verify_leaves(leaves, proof)
1769 }
1770
1771 fn verify_proof_stateless(
1772 root: mmr::Hash,
1773 leaves: Vec<mmr::EncodableOpaqueLeaf>,
1774 proof: mmr::LeafProof<mmr::Hash>
1775 ) -> Result<(), mmr::Error> {
1776 let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
1777 pallet_mmr::verify_leaves_proof::<mmr::Hashing, _>(root, nodes, proof)
1778 }
1779 }
1780
1781 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
1782 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
1783 build_state::<RuntimeGenesisConfig>(config)
1784 }
1785
1786 fn get_preset(_id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
1787 get_preset::<RuntimeGenesisConfig>(&None, |_| None)
1789 }
1790
1791 fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
1792 vec![]
1793 }
1794 }
1795
1796 #[cfg(feature = "runtime-benchmarks")]
1797 impl frame_benchmarking::Benchmark<Block> for Runtime {
1798 fn benchmark_metadata(extra: bool) -> (
1799 Vec<frame_benchmarking::BenchmarkList>,
1800 Vec<frame_support::traits::StorageInfo>,
1801 ) {
1802 use frame_benchmarking::{baseline, Benchmarking, BenchmarkList};
1803 use frame_support::traits::StorageInfoTrait;
1804 use frame_system_benchmarking::Pallet as SystemBench;
1805 use baseline::Pallet as BaselineBench;
1806 use pallet_subspace::extensions::benchmarking::Pallet as SubspaceExtensionBench;
1807 use pallet_messenger::extensions::benchmarking_from_domains::Pallet as MessengerFromDomainsExtensionBench;
1808
1809 let mut list = Vec::<BenchmarkList>::new();
1810 list_benchmarks!(list, extra);
1811
1812 let storage_info = AllPalletsWithSystem::storage_info();
1813
1814 (list, storage_info)
1815 }
1816
1817 fn dispatch_benchmark(
1818 config: frame_benchmarking::BenchmarkConfig
1819 ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, alloc::string::String> {
1820 use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch};
1821 use sp_core::storage::TrackedStorageKey;
1822
1823 use frame_system_benchmarking::Pallet as SystemBench;
1824 use baseline::Pallet as BaselineBench;
1825 use pallet_subspace::extensions::benchmarking::Pallet as SubspaceExtensionBench;
1826 use pallet_messenger::extensions::benchmarking_from_domains::Pallet as MessengerFromDomainsExtensionBench;
1827
1828 use frame_support::traits::WhitelistedStorageKeys;
1829 let whitelist: Vec<TrackedStorageKey> = AllPalletsWithSystem::whitelisted_storage_keys();
1830
1831 let mut batches = Vec::<BenchmarkBatch>::new();
1832 let params = (&config, &whitelist);
1833 add_benchmarks!(params, batches);
1834
1835 Ok(batches)
1836 }
1837 }
1838}
1839
1840#[cfg(test)]
1841mod tests {
1842 use crate::{Runtime, SubspaceBlockWeights as BlockWeights};
1843 use pallet_domains::bundle_storage_fund::AccountType;
1844 use sp_domains::OperatorId;
1845 use sp_runtime::traits::AccountIdConversion;
1846 use subspace_runtime_primitives::tests_utils::FeeMultiplierUtils;
1847
1848 #[test]
1849 fn multiplier_can_grow_from_zero() {
1850 FeeMultiplierUtils::<Runtime, BlockWeights>::multiplier_can_grow_from_zero()
1851 }
1852
1853 #[test]
1854 fn test_bundle_storage_fund_account_uniqueness() {
1855 let _: <Runtime as frame_system::Config>::AccountId = <Runtime as pallet_domains::Config>::PalletId::get()
1856 .try_into_sub_account((AccountType::StorageFund, OperatorId::MAX))
1857 .expect(
1858 "The `AccountId` type must be large enough to fit the seed of the bundle storage fund account",
1859 );
1860 }
1861}