1#![cfg_attr(not(feature = "std"), no_std)]
18#![recursion_limit = "256"]
20
21#[cfg(feature = "std")]
23include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
24
25mod features;
26mod flavors;
27mod genesis_config_presets;
28pub mod test_pallet;
29
30extern crate alloc;
31
32use features::*;
33
34use alloc::{vec, vec::Vec};
35use frame_support::{derive_impl, traits::OnRuntimeUpgrade, PalletId};
36use sp_api::{decl_runtime_apis, impl_runtime_apis};
37pub use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
38pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
39use sp_core::{ConstBool, ConstU32, ConstU64, Get, OpaqueMetadata};
40
41use sp_runtime::{
42 generic, impl_opaque_keys,
43 traits::{BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
44 transaction_validity::{TransactionSource, TransactionValidity},
45 ApplyExtrinsicResult, MultiAddress, MultiSignature,
46};
47#[cfg(feature = "std")]
48use sp_version::NativeVersion;
49use sp_version::RuntimeVersion;
50
51use cumulus_primitives_core::{ParaId, RelayProofRequest, VerifySchedulingSignature};
52
53define_flavors!(consts wasm);
54
55pub use frame_support::{
57 construct_runtime,
58 dispatch::DispatchClass,
59 genesis_builder_helper::{build_state, get_preset},
60 parameter_types,
61 traits::{ConstU8, Randomness},
62 weights::{
63 constants::{
64 BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
65 },
66 ConstantMultiplier, IdentityFee, Weight,
67 },
68 StorageValue,
69};
70pub use frame_system::Call as SystemCall;
71use frame_system::{
72 limits::{BlockLength, BlockWeights},
73 EnsureRoot,
74};
75pub use pallet_balances::Call as BalancesCall;
76pub use pallet_glutton::Call as GluttonCall;
77pub use pallet_sudo::Call as SudoCall;
78pub use pallet_timestamp::{Call as TimestampCall, Now};
79#[cfg(any(feature = "std", test))]
80pub use sp_runtime::BuildStorage;
81pub use sp_runtime::{Perbill, Permill};
82pub use test_pallet::{Call as TestPalletCall, TestTransactionExtension};
83
84pub type SessionHandlers = ();
85
86#[cfg(not(feature = "with-authority-discovery"))]
87impl_opaque_keys! {
88 pub struct SessionKeys {
89 pub aura: Aura,
90 }
91}
92
93#[cfg(feature = "with-authority-discovery")]
94impl_opaque_keys! {
95 pub struct SessionKeys {
96 pub aura: Aura,
97 pub authority_discovery: AuthorityDiscovery,
98 }
99}
100
101pub const PARACHAIN_ID: u32 = 100;
103
104const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6000;
105
106#[cfg(all(not(feature = "spec-version-3"), not(feature = "spec-version-4"),))]
119#[sp_version::runtime_version]
120pub const VERSION: RuntimeVersion = RuntimeVersion {
121 spec_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
122 impl_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
123 authoring_version: 1,
124 spec_version: 2,
126 impl_version: 1,
127 apis: RUNTIME_API_VERSIONS,
128 transaction_version: 1,
129 system_version: 3,
130};
131
132#[cfg(all(feature = "spec-version-3", not(feature = "spec-version-4"),))]
133#[sp_version::runtime_version]
134pub const VERSION: RuntimeVersion = RuntimeVersion {
135 spec_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
136 impl_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
137 authoring_version: 1,
138 spec_version: 3,
140 impl_version: 1,
141 apis: RUNTIME_API_VERSIONS,
142 transaction_version: 1,
143 system_version: 3,
144};
145
146#[cfg(feature = "spec-version-4")]
147#[sp_version::runtime_version]
148pub const VERSION: RuntimeVersion = RuntimeVersion {
149 spec_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
150 impl_name: alloc::borrow::Cow::Borrowed("cumulus-test-parachain"),
151 authoring_version: 1,
152 spec_version: 4,
154 impl_version: 1,
155 apis: RUNTIME_API_VERSIONS,
156 transaction_version: 1,
157 system_version: 3,
158};
159
160pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES;
161
162pub const MINUTES: BlockNumber = 60_000 / (slot_duration() as BlockNumber);
164pub const HOURS: BlockNumber = MINUTES * 60;
165pub const DAYS: BlockNumber = HOURS * 24;
166
167pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
169
170#[cfg(feature = "std")]
172pub fn native_version() -> NativeVersion {
173 NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
174}
175
176const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
179const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
182
183type MaximumBlockWeight = cumulus_pallet_parachain_system::block_weight::MaxParachainBlockWeight<
184 Runtime,
185 ConstU32<{ block_processing_velocity() }>,
186>;
187
188parameter_types! {
189 pub const NumberOfBlocksPerRelaySlot: u32 = 12;
191 pub const BlockHashCount: BlockNumber = 250;
192 pub const Version: RuntimeVersion = VERSION;
193 pub RuntimeBlockLength: BlockLength =
195 BlockLength::builder().max_length(10 * 1024 * 1024).max_header_size(5 * 1024 * 1024).build();
196 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
197 .base_block(BlockExecutionWeight::get())
198 .for_class(DispatchClass::all(), |weights| {
199 weights.base_extrinsic = ExtrinsicBaseWeight::get();
200 })
201 .for_class(DispatchClass::Normal, |weights| {
202 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MaximumBlockWeight::get());
203 })
204 .for_class(DispatchClass::Operational, |weights| {
205 weights.max_total = Some(MaximumBlockWeight::get());
206 weights.reserved = Some(
209 MaximumBlockWeight::get() - NORMAL_DISPATCH_RATIO * MaximumBlockWeight::get()
210 );
211 })
212 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
213 .build_or_panic();
214 pub const SS58Prefix: u8 = 42;
215}
216
217#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig)]
218impl frame_system::Config for Runtime {
219 type AccountId = AccountId;
221 type Nonce = Nonce;
223 type Hash = Hash;
225 type Block = Block;
227 type BlockHashCount = BlockHashCount;
229 type Version = Version;
231 type AccountData = pallet_balances::AccountData<Balance>;
232 type BlockWeights = RuntimeBlockWeights;
233 type BlockLength = RuntimeBlockLength;
234 type SS58Prefix = SS58Prefix;
235 type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
236 type MaxConsumers = frame_support::traits::ConstU32<16>;
237 type PreInherents = cumulus_pallet_parachain_system::block_weight::DynamicMaxBlockWeightHooks<
238 Runtime,
239 ConstU32<{ block_processing_velocity() }>,
240 >;
241 type SingleBlockMigrations = SingleBlockMigrations;
242}
243
244impl cumulus_pallet_weight_reclaim::Config for Runtime {
245 type WeightInfo = ();
246}
247
248parameter_types! {
249 pub const MinimumPeriod: u64 = 0;
250}
251
252parameter_types! {
253 pub const PotId: PalletId = PalletId(*b"PotStake");
254 pub const SessionLength: BlockNumber = 10 * MINUTES;
255 pub const Offset: u32 = 0;
256}
257
258impl cumulus_pallet_aura_ext::Config for Runtime {}
259
260impl pallet_timestamp::Config for Runtime {
261 type Moment = u64;
263 type OnTimestampSet = Aura;
264 type MinimumPeriod = MinimumPeriod;
265 type WeightInfo = ();
266}
267
268parameter_types! {
269 pub const ExistentialDeposit: u128 = 500;
270 pub const TransferFee: u128 = 0;
271 pub const CreationFee: u128 = 0;
272 pub const TransactionByteFee: u128 = 1;
273 pub const MaxReserves: u32 = 50;
274}
275
276impl pallet_balances::Config for Runtime {
277 type Balance = Balance;
279 type RuntimeEvent = RuntimeEvent;
281 type DustRemoval = ();
282 type ExistentialDeposit = ExistentialDeposit;
283 type AccountStore = System;
284 type WeightInfo = ();
285 type MaxLocks = ();
286 type MaxReserves = MaxReserves;
287 type ReserveIdentifier = [u8; 8];
288 type RuntimeHoldReason = RuntimeHoldReason;
289 type RuntimeFreezeReason = RuntimeFreezeReason;
290 type FreezeIdentifier = ();
291 type MaxFreezes = ConstU32<0>;
292 type DoneSlashHandler = ();
293}
294
295impl pallet_transaction_payment::Config for Runtime {
296 type RuntimeEvent = RuntimeEvent;
297 type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
298 type WeightToFee = IdentityFee<Balance>;
299 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
300 type FeeMultiplierUpdate = ();
301 type OperationalFeeMultiplier = ConstU8<5>;
302 type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
303}
304
305impl pallet_sudo::Config for Runtime {
306 type RuntimeCall = RuntimeCall;
307 type RuntimeEvent = RuntimeEvent;
308 type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
309}
310
311impl pallet_utility::Config for Runtime {
312 type RuntimeCall = RuntimeCall;
313 type RuntimeEvent = RuntimeEvent;
314 type PalletsOrigin = OriginCaller;
315 type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
316}
317
318impl pallet_glutton::Config for Runtime {
319 type RuntimeEvent = RuntimeEvent;
320 type AdminOrigin = EnsureRoot<AccountId>;
321 type WeightInfo = pallet_glutton::weights::SubstrateWeight<Runtime>;
322}
323
324pub struct NoVerification;
330
331impl VerifySchedulingSignature for NoVerification {
332 const V3_SCHEDULING_ENABLED: bool = SCHEDULING_V3_ENABLED;
333
334 fn verify(
335 _signed_info: &cumulus_primitives_core::SignedSchedulingInfo,
336 _relay_slot: cumulus_primitives_core::relay_chain::Slot,
337 ) -> bool {
338 true
339 }
340}
341
342type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
343 Runtime,
344 RELAY_CHAIN_SLOT_DURATION_MILLIS,
345 { block_processing_velocity() },
346 { unincluded_segment_capacity() },
347>;
348impl cumulus_pallet_parachain_system::Config for Runtime {
349 type WeightInfo = ();
350 type SelfParaId = parachain_info::Pallet<Runtime>;
351 type RuntimeEvent = RuntimeEvent;
352 type OnSystemEvent = TestPallet;
353 type OutboundXcmpMessageSource = TestPallet;
354 type DmpQueue = frame_support::traits::EnqueueWithOrigin<(), sp_core::ConstU8<0>>;
356 type ReservedDmpWeight = ();
357 type XcmpMessageHandler = ();
358 type ReservedXcmpWeight = ();
359 type CheckAssociatedRelayNumber =
360 cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
361 type ConsensusHook = ConsensusHook;
362 type RelayParentOffset = ConstU32<{ relay_parent_offset() }>;
363 type SchedulingSignatureVerifier = NoVerification;
364}
365
366impl parachain_info::Config for Runtime {}
367
368impl pallet_aura::Config for Runtime {
369 type AuthorityId = AuraId;
370 type DisabledValidators = ();
371 type MaxAuthorities = ConstU32<32>;
372 type AllowMultipleBlocksPerSlot = ConstBool<{ !cfg!(feature = "sync-backing") }>;
373 type SlotDuration = ConstU64<{ slot_duration() }>;
374}
375
376impl test_pallet::Config for Runtime {}
377
378parameter_types! {
379 pub const Period: u32 = 10;
380}
381
382#[cfg(feature = "with-authority-discovery")]
383impl pallet_session::Config for Runtime {
384 type RuntimeEvent = RuntimeEvent;
385 type ValidatorId = AccountId;
386 type ValidatorIdOf = sp_runtime::traits::ConvertInto;
387 type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
388 type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
389 type SessionManager = ();
390 type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
391 type Keys = SessionKeys;
392 type DisablingStrategy = ();
393 type WeightInfo = ();
394 type Currency = Balances;
395 type KeyDeposit = ();
396}
397
398#[cfg(feature = "with-authority-discovery")]
399impl pallet_authority_discovery::Config for Runtime {
400 type MaxAuthorities = ConstU32<32>;
401}
402
403construct_runtime! {
404 pub enum Runtime
405 {
406 System: frame_system,
407 ParachainSystem: cumulus_pallet_parachain_system,
408 Timestamp: pallet_timestamp,
409 ParachainInfo: parachain_info,
410 Balances: pallet_balances,
411 Sudo: pallet_sudo,
412 Utility: pallet_utility,
413 TransactionPayment: pallet_transaction_payment,
414 TestPallet: test_pallet,
415 Glutton: pallet_glutton,
416 Aura: pallet_aura,
417 #[cfg(feature = "with-authority-discovery")]
420 Session: pallet_session,
421 #[cfg(feature = "with-authority-discovery")]
422 AuthorityDiscovery: pallet_authority_discovery,
423 AuraExt: cumulus_pallet_aura_ext,
424 WeightReclaim: cumulus_pallet_weight_reclaim,
425 }
426}
427
428pub type Nonce = u32;
430pub type Hash = sp_core::H256;
432pub type Balance = u128;
434pub type Signature = MultiSignature;
436pub type BlockNumber = u32;
438pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
441pub type NodeBlock = generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
443
444pub type Address = MultiAddress<AccountId, ()>;
446pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
448pub type Block = generic::Block<Header, UncheckedExtrinsic>;
450pub type SignedBlock = generic::SignedBlock<Block>;
452pub type BlockId = generic::BlockId<Block>;
454pub type TxExtension = cumulus_pallet_parachain_system::block_weight::DynamicMaxBlockWeight<
456 Runtime,
457 cumulus_pallet_weight_reclaim::StorageWeightReclaim<
458 Runtime,
459 (
460 frame_system::AuthorizeCall<Runtime>,
461 frame_system::CheckNonZeroSender<Runtime>,
462 frame_system::CheckSpecVersion<Runtime>,
463 frame_system::CheckGenesis<Runtime>,
464 frame_system::CheckEra<Runtime>,
465 frame_system::CheckNonce<Runtime>,
466 frame_system::CheckWeight<Runtime>,
467 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
468 test_pallet::TestTransactionExtension<Runtime>,
469 ),
470 >,
471 ConstU32<{ block_processing_velocity() }>,
472>;
473
474pub type UncheckedExtrinsic =
476 generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
477pub type Executive = frame_executive::Executive<
479 Runtime,
480 Block,
481 frame_system::ChainContext<Runtime>,
482 Runtime,
483 AllPalletsWithSystem,
484>;
485
486pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
488
489pub struct VerifyRuntimeUpgrade;
493
494impl OnRuntimeUpgrade for VerifyRuntimeUpgrade {
495 fn on_runtime_upgrade() -> Weight {
496 assert_eq!(
497 sp_io::storage::get(test_pallet::TEST_RUNTIME_UPGRADE_KEY),
498 Some(vec![1, 2, 3, 4].into())
499 );
500 Weight::from_parts(1, 0)
501 }
502}
503
504#[cfg(feature = "with-authority-discovery")]
509pub type SingleBlockMigrations = (VerifyRuntimeUpgrade, migrations::EnableAuthorityDiscovery);
510#[cfg(not(feature = "with-authority-discovery"))]
511pub type SingleBlockMigrations = (VerifyRuntimeUpgrade,);
512
513#[cfg(feature = "with-authority-discovery")]
519pub mod migrations {
520 use super::*;
521 use sp_core::crypto::key_types;
522
523 pub struct EnableAuthorityDiscovery;
524
525 impl OnRuntimeUpgrade for EnableAuthorityDiscovery {
526 fn on_runtime_upgrade() -> Weight {
527 let db: frame_support::weights::RuntimeDbWeight =
528 <Runtime as frame_system::Config>::DbWeight::get();
529
530 if !pallet_session::Validators::<Runtime>::get().is_empty() {
532 return db.reads(1);
533 }
534
535 let aura_authorities = pallet_aura::Authorities::<Runtime>::get();
536 let n = aura_authorities.len() as u64;
537
538 let mut validators: Vec<AccountId> = Vec::with_capacity(aura_authorities.len());
539 let mut queued_keys: Vec<(AccountId, SessionKeys)> =
540 Vec::with_capacity(aura_authorities.len());
541
542 for aura_pub in aura_authorities.iter() {
543 let inner: sp_core::sr25519::Public = aura_pub.clone().into();
545 let raw: [u8; 32] = inner.0;
546 let account: AccountId = sp_core::sr25519::Public::from_raw(raw).into();
547 let aura_key = AuraId::from(sp_core::sr25519::Public::from_raw(raw));
548 let audi_key = AuthorityDiscoveryId::from(sp_core::sr25519::Public::from_raw(raw));
549 let session_keys = SessionKeys { aura: aura_key, authority_discovery: audi_key };
550
551 pallet_session::NextKeys::<Runtime>::insert(&account, &session_keys);
553 let aura_bytes: alloc::vec::Vec<u8> =
556 <AuraId as sp_runtime::RuntimeAppPublic>::to_raw_vec(&session_keys.aura);
557 let audi_bytes: alloc::vec::Vec<u8> =
558 <AuthorityDiscoveryId as sp_runtime::RuntimeAppPublic>::to_raw_vec(
559 &session_keys.authority_discovery,
560 );
561 pallet_session::KeyOwner::<Runtime>::insert(
562 (key_types::AURA, aura_bytes),
563 &account,
564 );
565 pallet_session::KeyOwner::<Runtime>::insert(
566 (key_types::AUTHORITY_DISCOVERY, audi_bytes),
567 &account,
568 );
569
570 if frame_system::Pallet::<Runtime>::providers(&account) > 0 {
574 let inc_ok = frame_system::Pallet::<Runtime>::inc_consumers(&account).is_ok();
575 debug_assert!(inc_ok, "inc_consumers failed despite providers > 0");
576 }
577
578 validators.push(account.clone());
579 queued_keys.push((account, session_keys));
580 }
581
582 pallet_session::Validators::<Runtime>::put(&validators);
584 pallet_session::QueuedKeys::<Runtime>::put(&queued_keys);
585
586 let ad_authorities: Vec<AuthorityDiscoveryId> = aura_authorities
588 .iter()
589 .map(|aura_pub| {
590 let inner: sp_core::sr25519::Public = aura_pub.clone().into();
591 AuthorityDiscoveryId::from(sp_core::sr25519::Public::from_raw(inner.0))
592 })
593 .collect();
594 let bounded = frame_support::WeakBoundedVec::<_, _>::force_from(
595 ad_authorities,
596 Some("EnableAuthorityDiscovery migration: authority count exceeds MaxAuthorities"),
597 );
598 pallet_authority_discovery::Keys::<Runtime>::put(bounded);
599
600 Self::assert_post_upgrade_invariants();
601
602 let reads = n.saturating_add(2);
603 let writes = n.saturating_mul(4).saturating_add(3);
604 db.reads(reads).saturating_add(db.writes(writes))
605 }
606 }
607
608 impl EnableAuthorityDiscovery {
609 fn assert_post_upgrade_invariants() {
610 let aura_count = pallet_aura::Authorities::<Runtime>::get().len();
611 let validators = pallet_session::Validators::<Runtime>::get();
612 let queued = pallet_session::QueuedKeys::<Runtime>::get();
613 let ad_keys = pallet_authority_discovery::Keys::<Runtime>::get();
614
615 assert!(!validators.is_empty(), "Validators empty after migration");
616 assert_eq!(validators.len(), aura_count, "Validators ≠ aura Authorities");
617 assert_eq!(queued.len(), aura_count, "QueuedKeys ≠ aura Authorities");
618 assert_eq!(ad_keys.len(), aura_count, "AuthorityDiscovery::Keys ≠ aura Authorities");
619 assert_eq!(
620 pallet_session::NextKeys::<Runtime>::iter().count(),
621 aura_count,
622 "NextKeys entry count ≠ aura Authorities",
623 );
624 assert_eq!(
625 pallet_session::KeyOwner::<Runtime>::iter().count(),
626 2 * aura_count,
627 "KeyOwner count ≠ 2× aura Authorities (aura + audi)",
628 );
629 for account in &validators {
635 if frame_system::Pallet::<Runtime>::providers(account) > 0 {
636 assert!(
637 frame_system::Pallet::<Runtime>::consumers(account) >= 1,
638 "provisioned validator {account:?} has 0 consumers; \
639 inc_consumers didn't fire",
640 );
641 }
642 }
643 }
644 }
645
646 #[cfg(test)]
647 mod tests {
648 use super::*;
649 use frame_support::traits::OnRuntimeUpgrade;
650 use sp_keyring::Sr25519Keyring;
651
652 fn ext_with_aura(keys: &[Sr25519Keyring]) -> sp_io::TestExternalities {
653 let mut ext = sp_io::TestExternalities::new_empty();
654 ext.execute_with(|| {
655 let aura_keys: alloc::vec::Vec<AuraId> = keys
656 .iter()
657 .map(|k| AuraId::from(sp_core::sr25519::Public::from_raw(k.public().0)))
658 .collect();
659 let bounded = frame_support::BoundedVec::<_, _>::try_from(aura_keys).expect("fits");
660 pallet_aura::Authorities::<Runtime>::put(bounded);
661 for k in keys {
664 let account: AccountId = k.to_account_id();
665 frame_system::Pallet::<Runtime>::inc_providers(&account);
666 }
667 });
668 ext
669 }
670
671 fn expected_weight(n: u64) -> Weight {
672 let db: frame_support::weights::RuntimeDbWeight =
673 <Runtime as frame_system::Config>::DbWeight::get();
674 let reads = n.saturating_add(2);
675 let writes = n.saturating_mul(4).saturating_add(3);
676 db.reads(reads).saturating_add(db.writes(writes))
677 }
678
679 #[test]
680 fn populates_session_state() {
681 let keys = [Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie];
683 ext_with_aura(&keys).execute_with(|| {
684 let w = EnableAuthorityDiscovery::on_runtime_upgrade();
685 assert_eq!(w, expected_weight(keys.len() as u64));
686 });
687 }
688
689 #[test]
690 fn is_idempotent() {
691 let keys = [Sr25519Keyring::Alice, Sr25519Keyring::Bob];
692 ext_with_aura(&keys).execute_with(|| {
693 EnableAuthorityDiscovery::on_runtime_upgrade();
694 let w2 = EnableAuthorityDiscovery::on_runtime_upgrade();
695
696 let db: frame_support::weights::RuntimeDbWeight =
697 <Runtime as frame_system::Config>::DbWeight::get();
698 assert_eq!(w2, db.reads(1), "second call should be a 1-read no-op");
699 });
700 }
701
702 #[test]
703 fn noop_when_validators_already_set() {
704 let keys = [Sr25519Keyring::Alice];
705 ext_with_aura(&keys).execute_with(|| {
706 pallet_session::Validators::<Runtime>::put(alloc::vec![
707 Sr25519Keyring::Alice.to_account_id(),
708 ]);
709 let w = EnableAuthorityDiscovery::on_runtime_upgrade();
710 let db: frame_support::weights::RuntimeDbWeight =
711 <Runtime as frame_system::Config>::DbWeight::get();
712 assert_eq!(w, db.reads(1));
713 assert!(pallet_authority_discovery::Keys::<Runtime>::get().is_empty());
714 });
715 }
716 }
717}
718
719decl_runtime_apis! {
720 pub trait GetLastTimestamp {
721 fn get_last_timestamp() -> u64;
723 }
724}
725
726impl_runtime_apis! {
727 impl sp_api::Core<Block> for Runtime {
728 fn version() -> RuntimeVersion {
729 VERSION
730 }
731
732 fn execute_block(block: <Block as BlockT>::LazyBlock) {
733 Executive::execute_block(block)
734 }
735
736 fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
737 Executive::initialize_block(header)
738 }
739 }
740
741
742 impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
743 fn can_build_upon(
744 included_hash: <Block as BlockT>::Hash,
745 slot: cumulus_primitives_aura::Slot,
746 ) -> bool {
747 ConsensusHook::can_build_upon(included_hash, slot)
748 }
749 }
750
751 impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
752 fn relay_parent_offset() -> u32 {
753 relay_parent_offset()
754 }
755
756 fn max_claim_queue_offset() -> u8 {
757 cumulus_pallet_parachain_system::Pallet::<Runtime>::max_claim_queue_offset()
758 }
759 }
760
761 impl cumulus_primitives_core::SchedulingV3EnabledApi<Block> for Runtime {
762 fn scheduling_v3_enabled() -> bool {
763 <Runtime as cumulus_pallet_parachain_system::Config>::SchedulingSignatureVerifier::V3_SCHEDULING_ENABLED
764 }
765 }
766
767 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
768 fn slot_duration() -> sp_consensus_aura::SlotDuration {
769 sp_consensus_aura::SlotDuration::from_millis(slot_duration())
770 }
771
772 fn authorities() -> Vec<AuraId> {
773 pallet_aura::Authorities::<Runtime>::get().into_inner()
774 }
775 }
776
777 impl sp_api::Metadata<Block> for Runtime {
778 fn metadata() -> OpaqueMetadata {
779 OpaqueMetadata::new(Runtime::metadata().into())
780 }
781
782 fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
783 Runtime::metadata_at_version(version)
784 }
785
786 fn metadata_versions() -> Vec<u32> {
787 Runtime::metadata_versions()
788 }
789 }
790
791 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
792 fn account_nonce(account: AccountId) -> Nonce {
793 System::account_nonce(account)
794 }
795 }
796
797 impl sp_block_builder::BlockBuilder<Block> for Runtime {
798 fn apply_extrinsic(
799 extrinsic: <Block as BlockT>::Extrinsic,
800 ) -> ApplyExtrinsicResult {
801 Executive::apply_extrinsic(extrinsic)
802 }
803
804 fn finalize_block() -> <Block as BlockT>::Header {
805 Executive::finalize_block()
806 }
807
808 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
809 data.create_extrinsics()
810 }
811
812 fn check_inherents(block: <Block as BlockT>::LazyBlock, data: sp_inherents::InherentData) -> sp_inherents::CheckInherentsResult {
813 data.check_extrinsics(&block)
814 }
815
816 }
817
818 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
819 fn validate_transaction(
820 source: TransactionSource,
821 tx: <Block as BlockT>::Extrinsic,
822 block_hash: <Block as BlockT>::Hash,
823 ) -> TransactionValidity {
824 Executive::validate_transaction(source, tx, block_hash)
825 }
826 }
827
828 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
829 fn offchain_worker(header: &<Block as BlockT>::Header) {
830 Executive::offchain_worker(header)
831 }
832 }
833
834 impl sp_session::SessionKeys<Block> for Runtime {
835 fn decode_session_keys(
836 encoded: Vec<u8>,
837 ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
838 SessionKeys::decode_into_raw_public_keys(&encoded)
839 }
840
841 fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
842 SessionKeys::generate(&owner, seed).into()
843 }
844 }
845
846 impl crate::GetLastTimestamp<Block> for Runtime {
847 fn get_last_timestamp() -> u64 {
848 Now::<Runtime>::get()
849 }
850 }
851
852 impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
853 fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
854 ParachainSystem::collect_collation_info(header)
855 }
856 }
857
858 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
859 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
860 build_state::<RuntimeGenesisConfig>(config)
861 }
862
863 fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
864 get_preset::<RuntimeGenesisConfig>(id, genesis_config_presets::get_preset)
865 }
866
867 fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
868 genesis_config_presets::preset_names()
869 }
870 }
871
872 impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
873 fn parachain_id() -> ParaId {
874 ParachainInfo::parachain_id()
875 }
876 }
877
878 impl cumulus_primitives_core::TargetBlockRate<Block> for Runtime {
879 fn target_block_rate() -> u32 {
880 block_processing_velocity()
881 }
882 }
883
884 impl cumulus_primitives_core::KeyToIncludeInRelayProof<Block> for Runtime {
885 fn keys_to_prove() -> cumulus_primitives_core::RelayProofRequest {
886 use cumulus_primitives_core::RelayStorageKey;
887 RelayProofRequest {
888 keys: vec![
889 RelayStorageKey::Top(test_pallet::relay_alice_account_key()),
891 ],
892 }
893 }
894 }
895
896 impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
897 fn authorities() -> Vec<AuthorityDiscoveryId> {
899 #[cfg(feature = "with-authority-discovery")]
900 { AuthorityDiscovery::current_authorities().to_vec() }
901 #[cfg(not(feature = "with-authority-discovery"))]
902 { Vec::new() }
903 }
904 }
905}
906
907cumulus_pallet_parachain_system::register_validate_block! {
908 Runtime = Runtime,
909 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
910}