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