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