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 DoneSlashHandler = ();
283}
284
285impl pallet_transaction_payment::Config for Runtime {
286 type RuntimeEvent = RuntimeEvent;
287 type OnChargeTransaction = pallet_transaction_payment::FungibleAdapter<Balances, ()>;
288 type WeightToFee = IdentityFee<Balance>;
289 type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
290 type FeeMultiplierUpdate = ();
291 type OperationalFeeMultiplier = ConstU8<5>;
292 type WeightInfo = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
293}
294
295impl pallet_sudo::Config for Runtime {
296 type RuntimeCall = RuntimeCall;
297 type RuntimeEvent = RuntimeEvent;
298 type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
299}
300
301impl pallet_utility::Config for Runtime {
302 type RuntimeCall = RuntimeCall;
303 type RuntimeEvent = RuntimeEvent;
304 type PalletsOrigin = OriginCaller;
305 type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
306}
307
308impl pallet_glutton::Config for Runtime {
309 type RuntimeEvent = RuntimeEvent;
310 type AdminOrigin = EnsureRoot<AccountId>;
311 type WeightInfo = pallet_glutton::weights::SubstrateWeight<Runtime>;
312}
313
314pub struct NoVerification;
320
321impl VerifySchedulingSignature for NoVerification {
322 const V3_SCHEDULING_ENABLED: bool = SCHEDULING_V3_ENABLED;
323
324 fn verify(
325 _signed_info: &cumulus_primitives_core::SignedSchedulingInfo,
326 _relay_slot: cumulus_primitives_core::relay_chain::Slot,
327 ) -> bool {
328 true
329 }
330}
331
332type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
333 Runtime,
334 RELAY_CHAIN_SLOT_DURATION_MILLIS,
335 { block_processing_velocity() },
336 { unincluded_segment_capacity() },
337>;
338impl cumulus_pallet_parachain_system::Config for Runtime {
339 type WeightInfo = ();
340 type SelfParaId = parachain_info::Pallet<Runtime>;
341 type RuntimeEvent = RuntimeEvent;
342 type OnSystemEvent = TestPallet;
343 type OutboundXcmpMessageSource = TestPallet;
344 type DmpQueue = frame_support::traits::EnqueueWithOrigin<(), sp_core::ConstU8<0>>;
346 type ReservedDmpWeight = ();
347 type XcmpMessageHandler = ();
348 type ReservedXcmpWeight = ();
349 type CheckAssociatedRelayNumber =
350 cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
351 type ConsensusHook = ConsensusHook;
352 type RelayParentOffset = ConstU32<{ relay_parent_offset() }>;
353 type SchedulingSignatureVerifier = NoVerification;
354}
355
356impl parachain_info::Config for Runtime {}
357
358impl pallet_aura::Config for Runtime {
359 type AuthorityId = AuraId;
360 type DisabledValidators = ();
361 type MaxAuthorities = ConstU32<32>;
362 type AllowMultipleBlocksPerSlot = ConstBool<{ !cfg!(feature = "sync-backing") }>;
363 type SlotDuration = ConstU64<{ slot_duration() }>;
364}
365
366impl test_pallet::Config for Runtime {}
367
368parameter_types! {
369 pub const Period: u32 = 10;
370}
371
372#[cfg(feature = "with-authority-discovery")]
373impl pallet_session::Config for Runtime {
374 type RuntimeEvent = RuntimeEvent;
375 type ValidatorId = AccountId;
376 type ValidatorIdOf = sp_runtime::traits::ConvertInto;
377 type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
378 type NextSessionRotation = pallet_session::PeriodicSessions<Period, Offset>;
379 type SessionManager = ();
380 type SessionHandler = <SessionKeys as sp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
381 type Keys = SessionKeys;
382 type DisablingStrategy = ();
383 type WeightInfo = ();
384 type Currency = Balances;
385 type KeyDeposit = ();
386}
387
388#[cfg(feature = "with-authority-discovery")]
389impl pallet_authority_discovery::Config for Runtime {
390 type MaxAuthorities = ConstU32<32>;
391}
392
393construct_runtime! {
394 pub enum Runtime
395 {
396 System: frame_system,
397 ParachainSystem: cumulus_pallet_parachain_system,
398 Timestamp: pallet_timestamp,
399 ParachainInfo: parachain_info,
400 Balances: pallet_balances,
401 Sudo: pallet_sudo,
402 Utility: pallet_utility,
403 TransactionPayment: pallet_transaction_payment,
404 TestPallet: test_pallet,
405 Glutton: pallet_glutton,
406 Aura: pallet_aura,
407 #[cfg(feature = "with-authority-discovery")]
410 Session: pallet_session,
411 #[cfg(feature = "with-authority-discovery")]
412 AuthorityDiscovery: pallet_authority_discovery,
413 AuraExt: cumulus_pallet_aura_ext,
414 WeightReclaim: cumulus_pallet_weight_reclaim,
415 }
416}
417
418pub type Nonce = u32;
420pub type Hash = sp_core::H256;
422pub type Balance = u128;
424pub type Signature = MultiSignature;
426pub type BlockNumber = u32;
428pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
431pub type NodeBlock = generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
433
434pub type Address = MultiAddress<AccountId, ()>;
436pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
438pub type Block = generic::Block<Header, UncheckedExtrinsic>;
440pub type SignedBlock = generic::SignedBlock<Block>;
442pub type BlockId = generic::BlockId<Block>;
444pub type TxExtension = cumulus_pallet_parachain_system::block_weight::DynamicMaxBlockWeight<
446 Runtime,
447 cumulus_pallet_weight_reclaim::StorageWeightReclaim<
448 Runtime,
449 (
450 frame_system::AuthorizeCall<Runtime>,
451 frame_system::CheckNonZeroSender<Runtime>,
452 frame_system::CheckSpecVersion<Runtime>,
453 frame_system::CheckGenesis<Runtime>,
454 frame_system::CheckEra<Runtime>,
455 frame_system::CheckNonce<Runtime>,
456 frame_system::CheckWeight<Runtime>,
457 pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
458 test_pallet::TestTransactionExtension<Runtime>,
459 ),
460 >,
461 ConstU32<{ block_processing_velocity() }>,
462>;
463
464pub type UncheckedExtrinsic =
466 generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
467pub type Executive = frame_executive::Executive<
469 Runtime,
470 Block,
471 frame_system::ChainContext<Runtime>,
472 Runtime,
473 AllPalletsWithSystem,
474>;
475
476pub type SignedPayload = generic::SignedPayload<RuntimeCall, TxExtension>;
478
479pub struct VerifyRuntimeUpgrade;
483
484impl OnRuntimeUpgrade for VerifyRuntimeUpgrade {
485 fn on_runtime_upgrade() -> Weight {
486 assert_eq!(
487 sp_io::storage::get(test_pallet::TEST_RUNTIME_UPGRADE_KEY),
488 Some(vec![1, 2, 3, 4].into())
489 );
490 Weight::from_parts(1, 0)
491 }
492}
493
494#[cfg(feature = "with-authority-discovery")]
499pub type SingleBlockMigrations = (VerifyRuntimeUpgrade, migrations::EnableAuthorityDiscovery);
500#[cfg(not(feature = "with-authority-discovery"))]
501pub type SingleBlockMigrations = (VerifyRuntimeUpgrade,);
502
503#[cfg(feature = "with-authority-discovery")]
509pub mod migrations {
510 use super::*;
511 use sp_core::crypto::key_types;
512
513 pub struct EnableAuthorityDiscovery;
514
515 impl OnRuntimeUpgrade for EnableAuthorityDiscovery {
516 fn on_runtime_upgrade() -> Weight {
517 let db: frame_support::weights::RuntimeDbWeight =
518 <Runtime as frame_system::Config>::DbWeight::get();
519
520 if !pallet_session::Validators::<Runtime>::get().is_empty() {
522 return db.reads(1);
523 }
524
525 let aura_authorities = pallet_aura::Authorities::<Runtime>::get();
526 let n = aura_authorities.len() as u64;
527
528 let mut validators: Vec<AccountId> = Vec::with_capacity(aura_authorities.len());
529 let mut queued_keys: Vec<(AccountId, SessionKeys)> =
530 Vec::with_capacity(aura_authorities.len());
531
532 for aura_pub in aura_authorities.iter() {
533 let inner: sp_core::sr25519::Public = aura_pub.clone().into();
535 let raw: [u8; 32] = inner.0;
536 let account: AccountId = sp_core::sr25519::Public::from_raw(raw).into();
537 let aura_key = AuraId::from(sp_core::sr25519::Public::from_raw(raw));
538 let audi_key = AuthorityDiscoveryId::from(sp_core::sr25519::Public::from_raw(raw));
539 let session_keys = SessionKeys { aura: aura_key, authority_discovery: audi_key };
540
541 pallet_session::NextKeys::<Runtime>::insert(&account, &session_keys);
543 let aura_bytes: alloc::vec::Vec<u8> =
546 <AuraId as sp_runtime::RuntimeAppPublic>::to_raw_vec(&session_keys.aura);
547 let audi_bytes: alloc::vec::Vec<u8> =
548 <AuthorityDiscoveryId as sp_runtime::RuntimeAppPublic>::to_raw_vec(
549 &session_keys.authority_discovery,
550 );
551 pallet_session::KeyOwner::<Runtime>::insert(
552 (key_types::AURA, aura_bytes),
553 &account,
554 );
555 pallet_session::KeyOwner::<Runtime>::insert(
556 (key_types::AUTHORITY_DISCOVERY, audi_bytes),
557 &account,
558 );
559
560 if frame_system::Pallet::<Runtime>::providers(&account) > 0 {
564 let inc_ok = frame_system::Pallet::<Runtime>::inc_consumers(&account).is_ok();
565 debug_assert!(inc_ok, "inc_consumers failed despite providers > 0");
566 }
567
568 validators.push(account.clone());
569 queued_keys.push((account, session_keys));
570 }
571
572 pallet_session::Validators::<Runtime>::put(&validators);
574 pallet_session::QueuedKeys::<Runtime>::put(&queued_keys);
575
576 let ad_authorities: Vec<AuthorityDiscoveryId> = aura_authorities
578 .iter()
579 .map(|aura_pub| {
580 let inner: sp_core::sr25519::Public = aura_pub.clone().into();
581 AuthorityDiscoveryId::from(sp_core::sr25519::Public::from_raw(inner.0))
582 })
583 .collect();
584 let bounded = frame_support::WeakBoundedVec::<_, _>::force_from(
585 ad_authorities,
586 Some("EnableAuthorityDiscovery migration: authority count exceeds MaxAuthorities"),
587 );
588 pallet_authority_discovery::Keys::<Runtime>::put(bounded);
589
590 Self::assert_post_upgrade_invariants();
591
592 let reads = n.saturating_add(2);
593 let writes = n.saturating_mul(4).saturating_add(3);
594 db.reads(reads).saturating_add(db.writes(writes))
595 }
596 }
597
598 impl EnableAuthorityDiscovery {
599 fn assert_post_upgrade_invariants() {
600 let aura_count = pallet_aura::Authorities::<Runtime>::get().len();
601 let validators = pallet_session::Validators::<Runtime>::get();
602 let queued = pallet_session::QueuedKeys::<Runtime>::get();
603 let ad_keys = pallet_authority_discovery::Keys::<Runtime>::get();
604
605 assert!(!validators.is_empty(), "Validators empty after migration");
606 assert_eq!(validators.len(), aura_count, "Validators ≠ aura Authorities");
607 assert_eq!(queued.len(), aura_count, "QueuedKeys ≠ aura Authorities");
608 assert_eq!(ad_keys.len(), aura_count, "AuthorityDiscovery::Keys ≠ aura Authorities");
609 assert_eq!(
610 pallet_session::NextKeys::<Runtime>::iter().count(),
611 aura_count,
612 "NextKeys entry count ≠ aura Authorities",
613 );
614 assert_eq!(
615 pallet_session::KeyOwner::<Runtime>::iter().count(),
616 2 * aura_count,
617 "KeyOwner count ≠ 2× aura Authorities (aura + audi)",
618 );
619 for account in &validators {
625 if frame_system::Pallet::<Runtime>::providers(account) > 0 {
626 assert!(
627 frame_system::Pallet::<Runtime>::consumers(account) >= 1,
628 "provisioned validator {account:?} has 0 consumers; \
629 inc_consumers didn't fire",
630 );
631 }
632 }
633 }
634 }
635
636 #[cfg(test)]
637 mod tests {
638 use super::*;
639 use frame_support::traits::OnRuntimeUpgrade;
640 use sp_keyring::Sr25519Keyring;
641
642 fn ext_with_aura(keys: &[Sr25519Keyring]) -> sp_io::TestExternalities {
643 let mut ext = sp_io::TestExternalities::new_empty();
644 ext.execute_with(|| {
645 let aura_keys: alloc::vec::Vec<AuraId> = keys
646 .iter()
647 .map(|k| AuraId::from(sp_core::sr25519::Public::from_raw(k.public().0)))
648 .collect();
649 let bounded = frame_support::BoundedVec::<_, _>::try_from(aura_keys).expect("fits");
650 pallet_aura::Authorities::<Runtime>::put(bounded);
651 for k in keys {
654 let account: AccountId = k.to_account_id();
655 frame_system::Pallet::<Runtime>::inc_providers(&account);
656 }
657 });
658 ext
659 }
660
661 fn expected_weight(n: u64) -> Weight {
662 let db: frame_support::weights::RuntimeDbWeight =
663 <Runtime as frame_system::Config>::DbWeight::get();
664 let reads = n.saturating_add(2);
665 let writes = n.saturating_mul(4).saturating_add(3);
666 db.reads(reads).saturating_add(db.writes(writes))
667 }
668
669 #[test]
670 fn populates_session_state() {
671 let keys = [Sr25519Keyring::Alice, Sr25519Keyring::Bob, Sr25519Keyring::Charlie];
673 ext_with_aura(&keys).execute_with(|| {
674 let w = EnableAuthorityDiscovery::on_runtime_upgrade();
675 assert_eq!(w, expected_weight(keys.len() as u64));
676 });
677 }
678
679 #[test]
680 fn is_idempotent() {
681 let keys = [Sr25519Keyring::Alice, Sr25519Keyring::Bob];
682 ext_with_aura(&keys).execute_with(|| {
683 EnableAuthorityDiscovery::on_runtime_upgrade();
684 let w2 = EnableAuthorityDiscovery::on_runtime_upgrade();
685
686 let db: frame_support::weights::RuntimeDbWeight =
687 <Runtime as frame_system::Config>::DbWeight::get();
688 assert_eq!(w2, db.reads(1), "second call should be a 1-read no-op");
689 });
690 }
691
692 #[test]
693 fn noop_when_validators_already_set() {
694 let keys = [Sr25519Keyring::Alice];
695 ext_with_aura(&keys).execute_with(|| {
696 pallet_session::Validators::<Runtime>::put(alloc::vec![
697 Sr25519Keyring::Alice.to_account_id(),
698 ]);
699 let w = EnableAuthorityDiscovery::on_runtime_upgrade();
700 let db: frame_support::weights::RuntimeDbWeight =
701 <Runtime as frame_system::Config>::DbWeight::get();
702 assert_eq!(w, db.reads(1));
703 assert!(pallet_authority_discovery::Keys::<Runtime>::get().is_empty());
704 });
705 }
706 }
707}
708
709decl_runtime_apis! {
710 pub trait GetLastTimestamp {
711 fn get_last_timestamp() -> u64;
713 }
714}
715
716impl_runtime_apis! {
717 impl sp_api::Core<Block> for Runtime {
718 fn version() -> RuntimeVersion {
719 VERSION
720 }
721
722 fn execute_block(block: <Block as BlockT>::LazyBlock) {
723 Executive::execute_block(block)
724 }
725
726 fn initialize_block(header: &<Block as BlockT>::Header) -> sp_runtime::ExtrinsicInclusionMode {
727 Executive::initialize_block(header)
728 }
729 }
730
731
732 impl cumulus_primitives_aura::AuraUnincludedSegmentApi<Block> for Runtime {
733 fn can_build_upon(
734 included_hash: <Block as BlockT>::Hash,
735 slot: cumulus_primitives_aura::Slot,
736 ) -> bool {
737 ConsensusHook::can_build_upon(included_hash, slot)
738 }
739 }
740
741 impl cumulus_primitives_core::RelayParentOffsetApi<Block> for Runtime {
742 fn relay_parent_offset() -> u32 {
743 relay_parent_offset()
744 }
745
746 fn max_claim_queue_offset() -> u8 {
747 cumulus_pallet_parachain_system::Pallet::<Runtime>::max_claim_queue_offset()
748 }
749 }
750
751 impl cumulus_primitives_core::SchedulingV3EnabledApi<Block> for Runtime {
752 fn scheduling_v3_enabled() -> bool {
753 <Runtime as cumulus_pallet_parachain_system::Config>::SchedulingSignatureVerifier::V3_SCHEDULING_ENABLED
754 }
755 }
756
757 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
758 fn slot_duration() -> sp_consensus_aura::SlotDuration {
759 sp_consensus_aura::SlotDuration::from_millis(slot_duration())
760 }
761
762 fn authorities() -> Vec<AuraId> {
763 pallet_aura::Authorities::<Runtime>::get().into_inner()
764 }
765 }
766
767 impl sp_api::Metadata<Block> for Runtime {
768 fn metadata() -> OpaqueMetadata {
769 OpaqueMetadata::new(Runtime::metadata().into())
770 }
771
772 fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
773 Runtime::metadata_at_version(version)
774 }
775
776 fn metadata_versions() -> Vec<u32> {
777 Runtime::metadata_versions()
778 }
779 }
780
781 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
782 fn account_nonce(account: AccountId) -> Nonce {
783 System::account_nonce(account)
784 }
785 }
786
787 impl sp_block_builder::BlockBuilder<Block> for Runtime {
788 fn apply_extrinsic(
789 extrinsic: <Block as BlockT>::Extrinsic,
790 ) -> ApplyExtrinsicResult {
791 Executive::apply_extrinsic(extrinsic)
792 }
793
794 fn finalize_block() -> <Block as BlockT>::Header {
795 Executive::finalize_block()
796 }
797
798 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
799 data.create_extrinsics()
800 }
801
802 fn check_inherents(block: <Block as BlockT>::LazyBlock, data: sp_inherents::InherentData) -> sp_inherents::CheckInherentsResult {
803 data.check_extrinsics(&block)
804 }
805
806 }
807
808 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
809 fn validate_transaction(
810 source: TransactionSource,
811 tx: <Block as BlockT>::Extrinsic,
812 block_hash: <Block as BlockT>::Hash,
813 ) -> TransactionValidity {
814 Executive::validate_transaction(source, tx, block_hash)
815 }
816 }
817
818 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
819 fn offchain_worker(header: &<Block as BlockT>::Header) {
820 Executive::offchain_worker(header)
821 }
822 }
823
824 impl sp_session::SessionKeys<Block> for Runtime {
825 fn decode_session_keys(
826 encoded: Vec<u8>,
827 ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
828 SessionKeys::decode_into_raw_public_keys(&encoded)
829 }
830
831 fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
832 SessionKeys::generate(&owner, seed).into()
833 }
834 }
835
836 impl crate::GetLastTimestamp<Block> for Runtime {
837 fn get_last_timestamp() -> u64 {
838 Now::<Runtime>::get()
839 }
840 }
841
842 impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
843 fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
844 ParachainSystem::collect_collation_info(header)
845 }
846 }
847
848 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
849 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
850 build_state::<RuntimeGenesisConfig>(config)
851 }
852
853 fn get_preset(id: &Option<sp_genesis_builder::PresetId>) -> Option<Vec<u8>> {
854 get_preset::<RuntimeGenesisConfig>(id, genesis_config_presets::get_preset)
855 }
856
857 fn preset_names() -> Vec<sp_genesis_builder::PresetId> {
858 genesis_config_presets::preset_names()
859 }
860 }
861
862 impl cumulus_primitives_core::GetParachainInfo<Block> for Runtime {
863 fn parachain_id() -> ParaId {
864 ParachainInfo::parachain_id()
865 }
866 }
867
868 impl cumulus_primitives_core::TargetBlockRate<Block> for Runtime {
869 fn target_block_rate() -> u32 {
870 block_processing_velocity()
871 }
872 }
873
874 impl cumulus_primitives_core::KeyToIncludeInRelayProof<Block> for Runtime {
875 fn keys_to_prove() -> cumulus_primitives_core::RelayProofRequest {
876 use cumulus_primitives_core::RelayStorageKey;
877 RelayProofRequest {
878 keys: vec![
879 RelayStorageKey::Top(test_pallet::relay_alice_account_key()),
881 ],
882 }
883 }
884 }
885
886 impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
887 fn authorities() -> Vec<AuthorityDiscoveryId> {
889 #[cfg(feature = "with-authority-discovery")]
890 { AuthorityDiscovery::current_authorities().to_vec() }
891 #[cfg(not(feature = "with-authority-discovery"))]
892 { Vec::new() }
893 }
894 }
895}
896
897cumulus_pallet_parachain_system::register_validate_block! {
898 Runtime = Runtime,
899 BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
900}