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