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