1#![cfg_attr(not(feature = "std"), no_std)]
21
22extern crate alloc;
23
24#[cfg(feature = "std")]
25pub mod extrinsic;
26#[cfg(feature = "std")]
27pub mod genesismap;
28pub mod substrate_test_pallet;
29
30#[cfg(not(feature = "std"))]
31use alloc::{vec, vec::Vec};
32use codec::{Decode, DecodeWithMemTracking, Encode};
33use frame_support::{
34 construct_runtime, derive_impl,
35 dispatch::DispatchClass,
36 genesis_builder_helper::{build_state, get_preset},
37 parameter_types,
38 traits::{ConstU32, ConstU64},
39 weights::{
40 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_REF_TIME_PER_SECOND},
41 Weight,
42 },
43};
44use frame_system::{
45 limits::{BlockLength, BlockWeights},
46 CheckNonce, CheckWeight,
47};
48use scale_info::TypeInfo;
49use sp_application_crypto::{ecdsa, ed25519, sr25519, RuntimeAppPublic, Ss58Codec};
50use sp_keyring::Sr25519Keyring;
51
52#[cfg(feature = "bls-experimental")]
53use sp_application_crypto::{bls381, ecdsa_bls381};
54
55use sp_core::OpaqueMetadata;
56use sp_trie::{
57 trie_types::{TrieDBBuilder, TrieDBMutBuilderV1},
58 PrefixedMemoryDB, StorageProof,
59};
60use trie_db::{Trie, TrieMut};
61
62use serde_json::json;
63use sp_api::{decl_runtime_apis, impl_runtime_apis};
64pub use sp_core::hash::H256;
65use sp_genesis_builder::PresetId;
66use sp_inherents::{CheckInherentsResult, InherentData};
67use sp_runtime::{
68 impl_opaque_keys, impl_tx_ext_default,
69 traits::{BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, NumberFor, Verify},
70 transaction_validity::{
71 TransactionSource, TransactionValidity, TransactionValidityError, ValidTransaction,
72 },
73 ApplyExtrinsicResult, ExtrinsicInclusionMode, Perbill,
74};
75#[cfg(any(feature = "std", test))]
76use sp_version::NativeVersion;
77use sp_version::RuntimeVersion;
78
79pub use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Slot};
80
81pub use pallet_balances::Call as BalancesCall;
82pub use pallet_utility::Call as UtilityCall;
83
84pub type AuraId = sp_consensus_aura::sr25519::AuthorityId;
85#[cfg(feature = "std")]
86pub use extrinsic::{ExtrinsicBuilder, Transfer};
87
88const LOG_TARGET: &str = "substrate-test-runtime";
89
90#[cfg(feature = "std")]
92include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
93
94#[cfg(feature = "std")]
95pub mod wasm_binary_logging_disabled {
96 include!(concat!(env!("OUT_DIR"), "/wasm_binary_logging_disabled.rs"));
97}
98
99#[cfg(feature = "std")]
101pub fn wasm_binary_unwrap() -> &'static [u8] {
102 WASM_BINARY.expect(
103 "Development wasm binary is not available. Testing is only supported with the flag
104 disabled.",
105 )
106}
107
108#[cfg(feature = "std")]
110pub fn wasm_binary_logging_disabled_unwrap() -> &'static [u8] {
111 wasm_binary_logging_disabled::WASM_BINARY.expect(
112 "Development wasm binary is not available. Testing is only supported with the flag
113 disabled.",
114 )
115}
116
117#[sp_version::runtime_version]
119pub const VERSION: RuntimeVersion = RuntimeVersion {
120 spec_name: alloc::borrow::Cow::Borrowed("test"),
121 impl_name: alloc::borrow::Cow::Borrowed("parity-test"),
122 authoring_version: 1,
123 spec_version: 2,
124 impl_version: 2,
125 apis: RUNTIME_API_VERSIONS,
126 transaction_version: 1,
127 system_version: 1,
128};
129
130fn version() -> RuntimeVersion {
131 VERSION
132}
133
134#[cfg(any(feature = "std", test))]
136pub fn native_version() -> NativeVersion {
137 NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
138}
139
140#[derive(Clone, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo)]
142pub struct TransferData {
143 pub from: AccountId,
144 pub to: AccountId,
145 pub amount: Balance,
146 pub nonce: Nonce,
147}
148
149pub type Address = sp_core::sr25519::Public;
151pub type Signature = sr25519::Signature;
152#[cfg(feature = "std")]
153pub type Pair = sp_core::sr25519::Pair;
154
155pub type TxExtension = (
158 (CheckNonce<Runtime>, CheckWeight<Runtime>),
159 CheckSubstrateCall,
160 frame_metadata_hash_extension::CheckMetadataHash<Runtime>,
161 frame_system::WeightReclaim<Runtime>,
162);
163pub type SignedPayload = sp_runtime::generic::SignedPayload<RuntimeCall, TxExtension>;
165pub type Extrinsic =
167 sp_runtime::generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
168
169pub type AccountId = <Signature as Verify>::Signer;
171pub type Hash = H256;
173pub type Hashing = BlakeTwo256;
175pub type BlockNumber = u64;
177pub type Nonce = u64;
179pub type DigestItem = sp_runtime::generic::DigestItem;
181pub type Digest = sp_runtime::generic::Digest;
183pub type Block = sp_runtime::generic::Block<Header, Extrinsic>;
185pub type Header = sp_runtime::generic::Header<BlockNumber, Hashing>;
187pub type Balance = u64;
189
190#[cfg(feature = "bls-experimental")]
191mod bls {
192 use sp_application_crypto::{bls381, ecdsa_bls381};
193 pub type Bls381Public = bls381::AppPublic;
194 pub type Bls381Pop = bls381::AppProofOfPossession;
195 pub type EcdsaBls381Public = ecdsa_bls381::AppPublic;
196 pub type EcdsaBls381Pop = ecdsa_bls381::AppProofOfPossession;
197}
198#[cfg(not(feature = "bls-experimental"))]
199mod bls {
200 pub type Bls381Public = ();
201 pub type Bls381Pop = ();
202 pub type EcdsaBls381Public = ();
203 pub type EcdsaBls381Pop = ();
204}
205pub use bls::*;
206
207decl_runtime_apis! {
208 #[api_version(2)]
209 pub trait TestAPI {
210 fn balance_of(id: AccountId) -> u64;
212 fn benchmark_add_one(val: &u64) -> u64;
214 fn benchmark_vector_add_one(vec: &Vec<u64>) -> Vec<u64>;
217 #[changed_in(2)]
219 fn function_signature_changed() -> Vec<u64>;
220 fn function_signature_changed() -> u64;
222 fn use_trie() -> u64;
224 fn benchmark_indirect_call() -> u64;
226 fn benchmark_direct_call() -> u64;
228 fn vec_with_capacity(size: u32) -> Vec<u8>;
230 fn get_block_number() -> u64;
232 fn test_ed25519_crypto() -> (ed25519::AppSignature, ed25519::AppPublic, ed25519::AppProofOfPossession);
236 fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic, sr25519::AppProofOfPossession);
240 fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, ecdsa::AppProofOfPossession);
244 fn test_bls381_crypto() -> (Bls381Pop, Bls381Public);
248 fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public);
252 fn test_storage();
254 fn test_witness(proof: StorageProof, root: crate::Hash);
256 fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32);
259 fn do_trace_log();
261 fn verify_ed25519(sig: ed25519::Signature, public: ed25519::Public, message: Vec<u8>) -> bool;
263 fn write_key_value(key: Vec<u8>, value: Vec<u8>, panic: bool);
265 }
266}
267
268pub type Executive = frame_executive::Executive<
269 Runtime,
270 Block,
271 frame_system::ChainContext<Runtime>,
272 Runtime,
273 AllPalletsWithSystem,
274>;
275
276#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo)]
277pub struct CheckSubstrateCall;
278
279impl sp_runtime::traits::Printable for CheckSubstrateCall {
280 fn print(&self) {
281 "CheckSubstrateCall".print()
282 }
283}
284
285impl sp_runtime::traits::RefundWeight for CheckSubstrateCall {
286 fn refund(&mut self, _weight: frame_support::weights::Weight) {}
287}
288impl sp_runtime::traits::ExtensionPostDispatchWeightHandler<CheckSubstrateCall>
289 for CheckSubstrateCall
290{
291 fn set_extension_weight(&mut self, _info: &CheckSubstrateCall) {}
292}
293
294impl sp_runtime::traits::Dispatchable for CheckSubstrateCall {
295 type RuntimeOrigin = RuntimeOrigin;
296 type Config = CheckSubstrateCall;
297 type Info = CheckSubstrateCall;
298 type PostInfo = CheckSubstrateCall;
299
300 fn dispatch(
301 self,
302 _origin: Self::RuntimeOrigin,
303 ) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
304 panic!("This implementation should not be used for actual dispatch.");
305 }
306}
307
308impl sp_runtime::traits::TransactionExtension<RuntimeCall> for CheckSubstrateCall {
309 const IDENTIFIER: &'static str = "CheckSubstrateCall";
310 type Implicit = ();
311 type Pre = ();
312 type Val = ();
313 impl_tx_ext_default!(RuntimeCall; weight prepare);
314
315 fn validate(
316 &self,
317 origin: <RuntimeCall as Dispatchable>::RuntimeOrigin,
318 call: &RuntimeCall,
319 _info: &DispatchInfoOf<RuntimeCall>,
320 _len: usize,
321 _self_implicit: Self::Implicit,
322 _inherited_implication: &impl Encode,
323 _source: TransactionSource,
324 ) -> Result<
325 (ValidTransaction, Self::Val, <RuntimeCall as Dispatchable>::RuntimeOrigin),
326 TransactionValidityError,
327 > {
328 log::trace!(target: LOG_TARGET, "validate");
329 let v = match call {
330 RuntimeCall::SubstrateTest(ref substrate_test_call) => {
331 substrate_test_pallet::validate_runtime_call(substrate_test_call)?
332 },
333 _ => Default::default(),
334 };
335 Ok((v, (), origin))
336 }
337}
338
339construct_runtime!(
340 pub enum Runtime
341 {
342 System: frame_system,
343 Babe: pallet_babe,
344 SubstrateTest: substrate_test_pallet::pallet,
345 Utility: pallet_utility,
346 Balances: pallet_balances,
347 }
348);
349
350const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
353const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
356const MAXIMUM_BLOCK_WEIGHT: Weight =
358 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
359
360parameter_types! {
361 pub const BlockHashCount: BlockNumber = 2400;
362 pub const Version: RuntimeVersion = VERSION;
363
364 pub RuntimeBlockLength: BlockLength = BlockLength::builder()
365 .max_length(5 * 1024 * 1024)
366 .modify_max_length_for_class(DispatchClass::Normal, |m| {
367 *m = NORMAL_DISPATCH_RATIO * *m
368 })
369 .build();
370
371 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
372 .base_block(BlockExecutionWeight::get())
373 .for_class(DispatchClass::all(), |weights| {
374 weights.base_extrinsic = ExtrinsicBaseWeight::get();
375 })
376 .for_class(DispatchClass::Normal, |weights| {
377 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
378 })
379 .for_class(DispatchClass::Operational, |weights| {
380 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
381 weights.reserved = Some(
384 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
385 );
386 })
387 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
388 .build_or_panic();
389}
390
391#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
392impl frame_system::pallet::Config for Runtime {
393 type BlockWeights = RuntimeBlockWeights;
394 type Nonce = Nonce;
395 type AccountId = AccountId;
396 type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
397 type Block = Block;
398 type AccountData = pallet_balances::AccountData<Balance>;
399}
400
401pub mod currency {
402 use crate::Balance;
403 const MILLICENTS: Balance = 1_000_000_000;
404 const CENTS: Balance = 1_000 * MILLICENTS; pub const DOLLARS: Balance = 100 * CENTS;
406}
407
408parameter_types! {
409 pub const ExistentialDeposit: Balance = 1 * currency::DOLLARS;
410 pub const MaxLocks: u32 = 50;
413 pub const MaxReserves: u32 = 50;
414}
415
416impl pallet_balances::Config for Runtime {
417 type MaxLocks = MaxLocks;
418 type MaxReserves = MaxReserves;
419 type ReserveIdentifier = [u8; 8];
420 type Balance = Balance;
421 type DustRemoval = ();
422 type RuntimeEvent = RuntimeEvent;
423 type ExistentialDeposit = ExistentialDeposit;
424 type AccountStore = System;
425 type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
426 type FreezeIdentifier = ();
427 type MaxFreezes = ();
428 type RuntimeHoldReason = RuntimeHoldReason;
429 type RuntimeFreezeReason = RuntimeFreezeReason;
430 type DoneSlashHandler = ();
431}
432
433impl pallet_utility::Config for Runtime {
434 type RuntimeEvent = RuntimeEvent;
435 type PalletsOrigin = OriginCaller;
436 type RuntimeCall = RuntimeCall;
437 type WeightInfo = ();
438}
439
440impl substrate_test_pallet::Config for Runtime {}
441
442impl pallet_timestamp::Config for Runtime {
444 type Moment = u64;
445 type OnTimestampSet = Babe;
446 type MinimumPeriod = ConstU64<500>;
447 type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
448}
449
450parameter_types! {
451 pub const EpochDuration: u64 = 6;
452}
453
454impl pallet_babe::Config for Runtime {
455 type EpochDuration = EpochDuration;
456 type ExpectedBlockTime = ConstU64<10_000>;
457 type EpochChangeTrigger = pallet_babe::SameAuthoritiesForever;
458 type DisabledValidators = ();
459 type KeyOwnerProof = sp_core::Void;
460 type EquivocationReportSystem = ();
461 type WeightInfo = ();
462 type MaxAuthorities = ConstU32<10>;
463 type MaxNominators = ConstU32<100>;
464}
465
466#[inline(never)]
468fn benchmark_add_one(i: u64) -> u64 {
469 i + 1
470}
471
472fn code_using_trie() -> u64 {
473 let pairs = [
474 (b"0103000000000000000464".to_vec(), b"0400000000".to_vec()),
475 (b"0103000000000000000469".to_vec(), b"0401000000".to_vec()),
476 ]
477 .to_vec();
478
479 let mut mdb = PrefixedMemoryDB::default();
480 let mut root = core::default::Default::default();
481 {
482 let mut t = TrieDBMutBuilderV1::<Hashing>::new(&mut mdb, &mut root).build();
483 for (key, value) in &pairs {
484 if t.insert(key, value).is_err() {
485 return 101;
486 }
487 }
488 }
489
490 let trie = TrieDBBuilder::<Hashing>::new(&mdb, &root).build();
491 let res = if let Ok(iter) = trie.iter() { iter.flatten().count() as u64 } else { 102 };
492
493 res
494}
495
496pub const TEST_OWNER: &[u8; 5] = b"owner";
498
499impl_opaque_keys! {
500 pub struct SessionKeys {
501 pub ed25519: ed25519::AppPublic,
502 pub sr25519: sr25519::AppPublic,
503 pub ecdsa: ecdsa::AppPublic,
504 }
505}
506
507pub const TEST_RUNTIME_BABE_EPOCH_CONFIGURATION: BabeEpochConfiguration = BabeEpochConfiguration {
508 c: (3, 10),
509 allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots,
510};
511
512impl_runtime_apis! {
513 impl sp_api::Core<Block> for Runtime {
514 fn version() -> RuntimeVersion {
515 version()
516 }
517
518 fn execute_block(block: <Block as BlockT>::LazyBlock) {
519 log::trace!(target: LOG_TARGET, "execute_block: {block:#?}");
520 Executive::execute_block(block);
521 }
522
523 fn initialize_block(header: &<Block as BlockT>::Header) -> ExtrinsicInclusionMode {
524 log::trace!(target: LOG_TARGET, "initialize_block: {header:#?}");
525 Executive::initialize_block(header)
526 }
527 }
528
529 impl sp_api::Metadata<Block> for Runtime {
530 fn metadata() -> OpaqueMetadata {
531 OpaqueMetadata::new(Runtime::metadata().into())
532 }
533
534 fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
535 Runtime::metadata_at_version(version)
536 }
537 fn metadata_versions() -> alloc::vec::Vec<u32> {
538 Runtime::metadata_versions()
539 }
540 }
541
542 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
543 fn validate_transaction(
544 source: TransactionSource,
545 utx: <Block as BlockT>::Extrinsic,
546 block_hash: <Block as BlockT>::Hash,
547 ) -> TransactionValidity {
548 let validity = Executive::validate_transaction(source, utx.clone(), block_hash);
549 log::trace!(target: LOG_TARGET, "validate_transaction {:?} {:?}", utx, validity);
550 validity
551 }
552 }
553
554 impl sp_block_builder::BlockBuilder<Block> for Runtime {
555 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
556 Executive::apply_extrinsic(extrinsic)
557 }
558
559 fn finalize_block() -> <Block as BlockT>::Header {
560 log::trace!(target: LOG_TARGET, "finalize_block");
561 Executive::finalize_block()
562 }
563
564 fn inherent_extrinsics(_data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
565 vec![]
566 }
567
568 fn check_inherents(_block: <Block as BlockT>::LazyBlock, _data: InherentData) -> CheckInherentsResult {
569 CheckInherentsResult::new()
570 }
571 }
572
573 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
574 fn account_nonce(account: AccountId) -> Nonce {
575 System::account_nonce(account)
576 }
577 }
578
579 impl self::TestAPI<Block> for Runtime {
580 fn balance_of(id: AccountId) -> u64 {
581 Balances::free_balance(id)
582 }
583
584 fn benchmark_add_one(val: &u64) -> u64 {
585 val + 1
586 }
587
588 fn benchmark_vector_add_one(vec: &Vec<u64>) -> Vec<u64> {
589 let mut vec = vec.clone();
590 vec.iter_mut().for_each(|v| *v += 1);
591 vec
592 }
593
594 fn function_signature_changed() -> u64 {
595 1
596 }
597
598 fn use_trie() -> u64 {
599 code_using_trie()
600 }
601
602 fn benchmark_indirect_call() -> u64 {
603 let function = benchmark_add_one;
604 (0..1000).fold(0, |p, i| p + function(i))
605 }
606 fn benchmark_direct_call() -> u64 {
607 (0..1000).fold(0, |p, i| p + benchmark_add_one(i))
608 }
609
610 fn vec_with_capacity(size: u32) -> Vec<u8> {
611 Vec::with_capacity(size as usize)
612 }
613
614 fn get_block_number() -> u64 {
615 System::block_number()
616 }
617
618 fn test_ed25519_crypto() -> (ed25519::AppSignature, ed25519::AppPublic, ed25519::AppProofOfPossession) {
619 test_ed25519_crypto()
620 }
621
622 fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic, sr25519::AppProofOfPossession) {
623 test_sr25519_crypto()
624 }
625
626 fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, ecdsa::AppProofOfPossession) {
627 test_ecdsa_crypto()
628 }
629
630 #[cfg(feature = "bls-experimental")]
631 fn test_bls381_crypto() -> (Bls381Pop, Bls381Public) {
632 test_bls381_crypto()
633 }
634
635 #[cfg(feature = "bls-experimental")]
636 fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public) {
637 test_ecdsa_bls381_crypto()
638 }
639
640 #[cfg(not(feature = "bls-experimental"))]
641 fn test_bls381_crypto() -> (Bls381Pop, Bls381Public) {
642 ((),())
643 }
644
645 #[cfg(not(feature = "bls-experimental"))]
646 fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public) {
647 ((), ())
648 }
649
650 fn test_storage() {
651 test_read_storage();
652 test_read_child_storage();
653 }
654
655 fn test_witness(proof: StorageProof, root: crate::Hash) {
656 test_witness(proof, root);
657 }
658
659 fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32) {
660 assert_eq!(&data[..], &other[..]);
661 assert_eq!(data.len(), num as usize);
662 }
663
664 fn do_trace_log() {
665 log::trace!(target: "test", "Hey I'm runtime");
666
667 let data = "THIS IS TRACING";
668
669 tracing::trace!(target: "test", %data, "Hey, I'm tracing");
670 }
671
672 fn verify_ed25519(sig: ed25519::Signature, public: ed25519::Public, message: Vec<u8>) -> bool {
673 sp_io::crypto::ed25519_verify(&sig, &message, &public)
674 }
675
676 fn write_key_value(key: Vec<u8>, value: Vec<u8>, panic: bool) {
677 sp_io::storage::set(&key, &value);
678
679 if panic {
680 panic!("I'm just following my master");
681 }
682 }
683 }
684
685 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
686 fn slot_duration() -> sp_consensus_aura::SlotDuration {
687 sp_consensus_aura::SlotDuration::from_millis(1000)
688 }
689
690 fn authorities() -> Vec<AuraId> {
691 SubstrateTest::authorities().into_iter().map(|auth| AuraId::from(auth)).collect()
692 }
693 }
694
695 impl sp_consensus_babe::BabeApi<Block> for Runtime {
696 fn configuration() -> sp_consensus_babe::BabeConfiguration {
697 let epoch_config = Babe::epoch_config().unwrap_or(TEST_RUNTIME_BABE_EPOCH_CONFIGURATION);
698 sp_consensus_babe::BabeConfiguration {
699 slot_duration: Babe::slot_duration(),
700 epoch_length: EpochDuration::get(),
701 c: epoch_config.c,
702 authorities: Babe::authorities().to_vec(),
703 randomness: Babe::randomness(),
704 allowed_slots: epoch_config.allowed_slots,
705 }
706 }
707
708 fn current_epoch_start() -> Slot {
709 Babe::current_epoch_start()
710 }
711
712 fn current_epoch() -> sp_consensus_babe::Epoch {
713 Babe::current_epoch()
714 }
715
716 fn next_epoch() -> sp_consensus_babe::Epoch {
717 Babe::next_epoch()
718 }
719
720 fn submit_report_equivocation_unsigned_extrinsic(
721 _equivocation_proof: sp_consensus_babe::EquivocationProof<
722 <Block as BlockT>::Header,
723 >,
724 _key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof,
725 ) -> Option<()> {
726 None
727 }
728
729 fn generate_key_ownership_proof(
730 _slot: sp_consensus_babe::Slot,
731 _authority_id: sp_consensus_babe::AuthorityId,
732 ) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
733 None
734 }
735 }
736
737 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
738 fn offchain_worker(header: &<Block as BlockT>::Header) {
739 let ext = Extrinsic::new_bare(
740 substrate_test_pallet::pallet::Call::storage_change{
741 key:b"some_key".encode(),
742 value:Some(header.number.encode())
743 }.into(),
744 );
745 sp_io::offchain::submit_transaction(ext.encode()).unwrap();
746 Executive::offchain_worker(header);
747 }
748 }
749
750 impl sp_session::SessionKeys<Block> for Runtime {
751 fn generate_session_keys(owner: Vec<u8>, _: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
752 SessionKeys::generate(&owner, None).into()
753 }
754
755 fn decode_session_keys(
756 encoded: Vec<u8>,
757 ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
758 SessionKeys::decode_into_raw_public_keys(&encoded)
759 }
760 }
761
762 impl sp_consensus_grandpa::GrandpaApi<Block> for Runtime {
763 fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList {
764 Vec::new()
765 }
766
767 fn current_set_id() -> sp_consensus_grandpa::SetId {
768 0
769 }
770
771 fn submit_report_equivocation_unsigned_extrinsic(
772 _equivocation_proof: sp_consensus_grandpa::EquivocationProof<
773 <Block as BlockT>::Hash,
774 NumberFor<Block>,
775 >,
776 _key_owner_proof: sp_consensus_grandpa::OpaqueKeyOwnershipProof,
777 ) -> Option<()> {
778 None
779 }
780
781 fn generate_key_ownership_proof(
782 _set_id: sp_consensus_grandpa::SetId,
783 _authority_id: sp_consensus_grandpa::AuthorityId,
784 ) -> Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof> {
785 None
786 }
787 }
788
789 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
790 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
791 build_state::<RuntimeGenesisConfig>(config)
792 }
793
794 fn get_preset(name: &Option<PresetId>) -> Option<Vec<u8>> {
795 get_preset::<RuntimeGenesisConfig>(name, |name| {
796 let patch = match name.as_ref() {
797 "staging" => {
798 let endowed_accounts: Vec<AccountId> = vec![
799 Sr25519Keyring::Bob.public().into(),
800 Sr25519Keyring::Charlie.public().into(),
801 ];
802
803 json!({
804 "balances": {
805 "balances": endowed_accounts.into_iter().map(|k| (k, 10 * currency::DOLLARS)).collect::<Vec<_>>(),
806 },
807 "substrateTest": {
808 "authorities": [
809 Sr25519Keyring::Alice.public().to_ss58check(),
810 Sr25519Keyring::Ferdie.public().to_ss58check()
811 ],
812 }
813 })
814 },
815 "foobar" => json!({"foo":"bar"}),
816 _ => return None,
817 };
818 Some(serde_json::to_string(&patch)
819 .expect("serialization to json is expected to work. qed.")
820 .into_bytes())
821 })
822 }
823
824 fn preset_names() -> Vec<PresetId> {
825 vec![PresetId::from("foobar"), PresetId::from("staging")]
826 }
827 }
828}
829
830fn test_ed25519_crypto(
831) -> (ed25519::AppSignature, ed25519::AppPublic, ed25519::AppProofOfPossession) {
832 let mut public0 = ed25519::AppPublic::generate_pair(None);
833 let public1 = ed25519::AppPublic::generate_pair(None);
834 let public2 = ed25519::AppPublic::generate_pair(None);
835
836 let all = ed25519::AppPublic::all();
837 assert!(all.contains(&public0));
838 assert!(all.contains(&public1));
839 assert!(all.contains(&public2));
840
841 let proof_of_possession = public0
842 .generate_proof_of_possession(b"owner")
843 .expect("Cant generate proof_of_possession for ed25519");
844 assert!(public0.verify_proof_of_possession(b"owner", &proof_of_possession));
845
846 let signature = public0.sign(&"ed25519").expect("Generates a valid `ed25519` signature.");
847 assert!(public0.verify(&"ed25519", &signature));
848 (signature, public0, proof_of_possession)
849}
850
851fn test_sr25519_crypto(
852) -> (sr25519::AppSignature, sr25519::AppPublic, sr25519::AppProofOfPossession) {
853 let mut public0 = sr25519::AppPublic::generate_pair(None);
854 let public1 = sr25519::AppPublic::generate_pair(None);
855 let public2 = sr25519::AppPublic::generate_pair(None);
856
857 let all = sr25519::AppPublic::all();
858 assert!(all.contains(&public0));
859 assert!(all.contains(&public1));
860 assert!(all.contains(&public2));
861
862 let proof_of_possession = public0
863 .generate_proof_of_possession(b"owner")
864 .expect("Cant generate proof_of_possession for sr25519");
865 assert!(public0.verify_proof_of_possession(b"owner", &proof_of_possession));
866
867 let signature = public0.sign(&"sr25519").expect("Generates a valid `sr25519` signature.");
868 assert!(public0.verify(&"sr25519", &signature));
869 (signature, public0, proof_of_possession)
870}
871
872fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, ecdsa::AppProofOfPossession) {
873 let mut public0 = ecdsa::AppPublic::generate_pair(None);
874 let public1 = ecdsa::AppPublic::generate_pair(None);
875 let public2 = ecdsa::AppPublic::generate_pair(None);
876
877 let all = ecdsa::AppPublic::all();
878 assert!(all.contains(&public0));
879 assert!(all.contains(&public1));
880 assert!(all.contains(&public2));
881
882 let proof_of_possession = public0
883 .generate_proof_of_possession(b"owner")
884 .expect("Cant generate proof_of_possession for ecdsa");
885 assert!(public0.verify_proof_of_possession(b"owner", &proof_of_possession));
886
887 let signature = public0.sign(&"ecdsa").expect("Generates a valid `ecdsa` signature.");
888
889 assert!(public0.verify(&"ecdsa", &signature));
890 (signature, public0, proof_of_possession)
891}
892
893#[cfg(feature = "bls-experimental")]
894fn test_bls381_crypto() -> (Bls381Pop, Bls381Public) {
895 let mut public0 = bls381::AppPublic::generate_pair(None);
896
897 let proof_of_possession = public0
898 .generate_proof_of_possession(b"owner")
899 .expect("Cant generate proof_of_possession for bls381");
900 assert!(public0.verify_proof_of_possession(b"owner", &proof_of_possession));
901
902 (proof_of_possession, public0)
903}
904
905#[cfg(feature = "bls-experimental")]
906fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public) {
907 let mut public0 = ecdsa_bls381::AppPublic::generate_pair(None);
908
909 let proof_of_possession = public0
910 .generate_proof_of_possession(b"owner")
911 .expect("Cant Generate proof_of_possession for ecdsa_bls381");
912 assert!(public0.verify_proof_of_possession(b"owner", &proof_of_possession));
913
914 (proof_of_possession, public0)
915}
916
917fn test_read_storage() {
918 const KEY: &[u8] = b":read_storage";
919 sp_io::storage::set(KEY, b"test");
920
921 let mut v = [0u8; 4];
922 let r = sp_io::storage::read(KEY, &mut v, 0);
923 assert_eq!(r, Some(4));
924 assert_eq!(&v, b"test");
925
926 let mut v = [0u8; 4];
927 let r = sp_io::storage::read(KEY, &mut v, 4);
928 assert_eq!(r, Some(0));
929 assert_eq!(&v, &[0, 0, 0, 0]);
930}
931
932fn test_read_child_storage() {
933 const STORAGE_KEY: &[u8] = b"unique_id_1";
934 const KEY: &[u8] = b":read_child_storage";
935 sp_io::default_child_storage::set(STORAGE_KEY, KEY, b"test");
936
937 let mut v = [0u8; 4];
938 let r = sp_io::default_child_storage::read(STORAGE_KEY, KEY, &mut v, 0);
939 assert_eq!(r, Some(4));
940 assert_eq!(&v, b"test");
941
942 let mut v = [0u8; 4];
943 let r = sp_io::default_child_storage::read(STORAGE_KEY, KEY, &mut v, 8);
944 assert_eq!(r, Some(0));
945 assert_eq!(&v, &[0, 0, 0, 0]);
946}
947
948fn test_witness(proof: StorageProof, root: crate::Hash) {
949 use sp_externalities::Externalities;
950 let db: sp_trie::MemoryDB<crate::Hashing> = proof.into_memory_db();
951 let backend = sp_state_machine::TrieBackendBuilder::<_, crate::Hashing>::new(db, root).build();
952 let mut overlay = sp_state_machine::OverlayedChanges::default();
953 let mut ext = sp_state_machine::Ext::new(
954 &mut overlay,
955 &backend,
956 #[cfg(feature = "std")]
957 None,
958 );
959 assert!(ext.storage(b"value3").is_some());
960 assert!(ext.storage_root(Default::default()).as_slice() == &root[..]);
961 ext.place_storage(vec![0], Some(vec![1]));
962 assert!(ext.storage_root(Default::default()).as_slice() != &root[..]);
963}
964
965#[cfg(feature = "std")]
969pub mod storage_key_generator {
970 use super::*;
971 use sp_core::Pair;
972
973 pub(super) fn hex<T>(x: T) -> String
975 where
976 T: array_bytes::Hex,
977 {
978 x.hex(Default::default())
979 }
980
981 fn concat_hashes(input: &Vec<&[u8]>) -> String {
982 input.iter().map(|s| sp_crypto_hashing::twox_128(s)).map(hex).collect()
983 }
984
985 fn twox_64_concat(x: &[u8]) -> Vec<u8> {
986 sp_crypto_hashing::twox_64(x).iter().chain(x.iter()).cloned().collect()
987 }
988
989 pub fn generate_expected_storage_hashed_keys(custom_heap_pages: bool) -> Vec<String> {
992 let mut literals: Vec<&[u8]> = vec![b":code", b":extrinsic_index"];
993
994 if custom_heap_pages {
995 literals.push(b":heappages");
996 }
997
998 let keys: Vec<Vec<&[u8]>> = vec![
999 vec![b"Babe", b":__STORAGE_VERSION__:"],
1000 vec![b"Babe", b"Authorities"],
1001 vec![b"Babe", b"EpochConfig"],
1002 vec![b"Babe", b"NextAuthorities"],
1003 vec![b"Babe", b"SegmentIndex"],
1004 vec![b"Balances", b":__STORAGE_VERSION__:"],
1005 vec![b"Balances", b"TotalIssuance"],
1006 vec![b"SubstrateTest", b":__STORAGE_VERSION__:"],
1007 vec![b"SubstrateTest", b"Authorities"],
1008 vec![b"System", b":__STORAGE_VERSION__:"],
1009 vec![b"System", b"LastRuntimeUpgrade"],
1010 vec![b"System", b"ParentHash"],
1011 vec![b"System", b"UpgradedToTripleRefCount"],
1012 vec![b"System", b"UpgradedToU32RefCount"],
1013 vec![b"Utility", b":__STORAGE_VERSION__:"],
1014 ];
1015
1016 let mut expected_keys = keys.iter().map(concat_hashes).collect::<Vec<String>>();
1017 expected_keys.extend(literals.into_iter().map(hex));
1018
1019 let balances_map_keys = (0..16_usize)
1020 .into_iter()
1021 .map(|i| Sr25519Keyring::numeric(i).public().to_vec())
1022 .chain(vec![
1023 Sr25519Keyring::Alice.public().to_vec(),
1024 Sr25519Keyring::Bob.public().to_vec(),
1025 Sr25519Keyring::Charlie.public().to_vec(),
1026 ])
1027 .map(|pubkey| {
1028 sp_crypto_hashing::blake2_128(&pubkey)
1029 .iter()
1030 .chain(pubkey.iter())
1031 .cloned()
1032 .collect::<Vec<u8>>()
1033 })
1034 .map(|hash_pubkey| {
1035 [concat_hashes(&vec![b"System", b"Account"]), hex(hash_pubkey)].concat()
1036 });
1037
1038 expected_keys.extend(balances_map_keys);
1039
1040 expected_keys.push(
1041 [
1042 concat_hashes(&vec![b"System", b"BlockHash"]),
1043 hex(0u64.using_encoded(twox_64_concat)),
1044 ]
1045 .concat(),
1046 );
1047
1048 expected_keys.sort();
1049 expected_keys
1050 }
1051
1052 pub fn get_expected_storage_hashed_keys(custom_heap_pages: bool) -> Vec<&'static str> {
1060 let mut res = vec![
1061 "00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429",
1063 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1065 "1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429",
1067 "1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d",
1069 "1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4",
1071 "1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c",
1073 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1075 "26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429",
1077 "26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710",
1079 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1081 "26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000",
1083 "26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439",
1085
1086 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da901cae4e3edfbb32c91ed3f01ab964f4eeeab50338d8e5176d3141802d7b010a55dadcd5f23cf8aaafa724627e967e90e",
1088 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da91b614bd4a126f2d5d294e9a8af9da25248d7e931307afb4b68d8d565d4c66e00d856c6d65f5fed6bb82dcfb60e936c67",
1090 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94b21aff9fe1e8b2fc4b0775b8cbeff28ba8e2c7594dd74730f3ca835e95455d199261897edc9735d602ea29615e2b10b",
1092 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
1094 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95786a2916fcb81e1bd5dcd81e0d2452884617f575372edb5a36d85c04cdf2e4699f96fe33eb5f94a28c041b88e398d0c",
1096 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95b8542d9672c7b7e779cc7c1e6b605691c2115d06120ea2bee32dd601d02f36367564e7ddf84ae2717ca3f097459652e",
1098 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da996c30bdbfab640838e6b6d3c33ab4adb4211b79e34ee8072eab506edd4b93a7b85a14c9a05e5cdd056d98e7dbca87730",
1100 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99dc65b1339ec388fbf2ca0cdef51253512c6cfd663203ea16968594f24690338befd906856c4d2f4ef32dad578dba20c",
1102 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99e6eb5abd62f5fd54793da91a47e6af6125d57171ff9241f07acaa1bb6a6103517965cf2cd00e643b27e7599ebccba70",
1104 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
1106 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d0052993b6f3bd0544fd1f5e4125b9fbde3e789ecd53431fe5c06c12b72137153496dace35c695b5f4d7b41f7ed5763b",
1108 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d6b7e9a5f12bc571053265dade10d3b4b606fc73f57f03cdb4c932d475ab426043e429cecc2ffff0d2672b0df8398c48",
1110 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
1112 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e1a35f56ee295d39287cbffcfc60c4b346f136b564e1fad55031404dd84e5cd3fa76bfe7cc7599b39d38fd06663bbc0a",
1114 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e2c1dc507e2035edbbd8776c440d870460c57f0008067cc01c5ff9eb2e2f9b3a94299a915a91198bd1021a6c55596f57",
1116 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9eca0e653a94f4080f6311b4e7b6934eb2afba9278e30ccf6a6ceb3a8b6e336b70068f045c666f2e7f4f9cc5f47db8972",
1118 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ee8bf7ef90fc56a8aa3b90b344c599550c29b161e27ff8ba45bf6bad4711f326fc506a8803453a4d7e3158e993495f10",
1120 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f5d6f1c082fe63eec7a71fcad00f4a892e3d43b7b0d04e776e69e7be35247cecdac65504c579195731eaf64b7940966e",
1122 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9fbf0818841edf110e05228a6379763c4fc3c37459d9bdc61f58a5ebc01e9e2305a19d390c0543dc733861ec3cf1de01f",
1124 "26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8",
1126 "3a636f6465",
1128 "3a65787472696e7369635f696e646578",
1130 "c2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429",
1132 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1134 "d5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429",
1136 ];
1137
1138 if custom_heap_pages {
1139 res.push("3a686561707061676573");
1141 }
1142
1143 res
1144 }
1145}
1146
1147#[cfg(test)]
1148mod tests {
1149 use super::*;
1150 use codec::Encode;
1151 use frame_support::dispatch::DispatchInfo;
1152 use pretty_assertions::assert_eq;
1153 use sc_block_builder::BlockBuilderBuilder;
1154 use sp_api::{ApiExt, ProvideRuntimeApi};
1155 use sp_consensus::BlockOrigin;
1156 use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext};
1157 use sp_runtime::{
1158 traits::{DispatchTransaction, Hash as _},
1159 transaction_validity::{InvalidTransaction, TransactionSource::External, ValidTransaction},
1160 };
1161 use substrate_test_runtime_client::{
1162 prelude::*, runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder,
1163 };
1164
1165 #[test]
1166 fn expected_keys_vec_are_matching() {
1167 assert_eq!(
1168 storage_key_generator::get_expected_storage_hashed_keys(false),
1169 storage_key_generator::generate_expected_storage_hashed_keys(false),
1170 );
1171 }
1172
1173 #[test]
1174 fn heap_pages_is_respected() {
1175 let client = TestClientBuilder::new().set_heap_pages(8).build();
1179 let best_hash = client.chain_info().best_hash;
1180
1181 let mut runtime_api = client.runtime_api();
1184 runtime_api.set_call_context(CallContext::Onchain { import: false });
1186 let ret = runtime_api.vec_with_capacity(best_hash, 1048576);
1187 assert!(ret.is_err());
1188
1189 let (new_at_hash, block) = {
1192 let mut builder = BlockBuilderBuilder::new(&client)
1193 .on_parent_block(best_hash)
1194 .with_parent_block_number(0)
1195 .build()
1196 .unwrap();
1197 builder.push_storage_change(HEAP_PAGES.to_vec(), Some(32u64.encode())).unwrap();
1198 let block = builder.build().unwrap().block;
1199 let hash = block.header.hash();
1200 (hash, block)
1201 };
1202
1203 futures::executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
1204
1205 let ret = client.runtime_api().vec_with_capacity(new_at_hash, 1048576);
1207 assert!(ret.is_ok());
1208 }
1209
1210 #[test]
1211 fn test_storage() {
1212 let client = TestClientBuilder::new().build();
1213 let runtime_api = client.runtime_api();
1214 let best_hash = client.chain_info().best_hash;
1215
1216 runtime_api.test_storage(best_hash).unwrap();
1217 }
1218
1219 fn witness_backend() -> (sp_trie::MemoryDB<crate::Hashing>, crate::Hash) {
1220 let mut root = crate::Hash::default();
1221 let mut mdb = sp_trie::MemoryDB::<crate::Hashing>::default();
1222 {
1223 let mut trie =
1224 sp_trie::trie_types::TrieDBMutBuilderV1::new(&mut mdb, &mut root).build();
1225 trie.insert(b"value3", &[142]).expect("insert failed");
1226 trie.insert(b"value4", &[124]).expect("insert failed");
1227 };
1228 (mdb, root)
1229 }
1230
1231 #[test]
1232 fn witness_backend_works() {
1233 let (db, root) = witness_backend();
1234 let backend =
1235 sp_state_machine::TrieBackendBuilder::<_, crate::Hashing>::new(db, root).build();
1236 let proof = sp_state_machine::prove_read(backend, vec![b"value3"]).unwrap();
1237 let client = TestClientBuilder::new().build();
1238 let runtime_api = client.runtime_api();
1239 let best_hash = client.chain_info().best_hash;
1240
1241 runtime_api.test_witness(best_hash, proof, root).unwrap();
1242 }
1243
1244 pub fn new_test_ext() -> sp_io::TestExternalities {
1245 genesismap::GenesisStorageBuilder::new(
1246 vec![Sr25519Keyring::One.public().into(), Sr25519Keyring::Two.public().into()],
1247 vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()],
1248 1000 * currency::DOLLARS,
1249 )
1250 .build()
1251 .into()
1252 }
1253
1254 #[test]
1255 fn validate_storage_keys() {
1256 assert_eq!(
1257 genesismap::GenesisStorageBuilder::default()
1258 .build()
1259 .top
1260 .keys()
1261 .cloned()
1262 .map(storage_key_generator::hex)
1263 .collect::<Vec<_>>(),
1264 storage_key_generator::get_expected_storage_hashed_keys(false)
1265 );
1266 }
1267
1268 #[test]
1269 #[allow(deprecated)]
1270 fn validate_unsigned_works() {
1271 sp_tracing::try_init_simple();
1272 new_test_ext().execute_with(|| {
1273 let failing_calls = vec![
1274 substrate_test_pallet::Call::bench_call { transfer: Default::default() },
1275 substrate_test_pallet::Call::include_data { data: vec![] },
1276 substrate_test_pallet::Call::fill_block { ratio: Perbill::from_percent(50) },
1277 ];
1278 let succeeding_calls = vec![
1279 substrate_test_pallet::Call::deposit_log_digest_item {
1280 log: DigestItem::Other(vec![]),
1281 },
1282 substrate_test_pallet::Call::storage_change { key: vec![], value: None },
1283 substrate_test_pallet::Call::read { count: 0 },
1284 substrate_test_pallet::Call::read_and_panic { count: 0 },
1285 ];
1286
1287 for call in failing_calls {
1288 assert_eq!(
1289 <SubstrateTest as sp_runtime::traits::ValidateUnsigned>::validate_unsigned(
1290 TransactionSource::External,
1291 &call,
1292 ),
1293 InvalidTransaction::Call.into(),
1294 );
1295 }
1296
1297 for call in succeeding_calls {
1298 assert_eq!(
1299 <SubstrateTest as sp_runtime::traits::ValidateUnsigned>::validate_unsigned(
1300 TransactionSource::External,
1301 &call,
1302 ),
1303 Ok(ValidTransaction {
1304 provides: vec![BlakeTwo256::hash_of(&call).encode()],
1305 ..Default::default()
1306 })
1307 );
1308 }
1309 });
1310 }
1311
1312 #[test]
1313 fn check_substrate_check_signed_extension_works() {
1314 sp_tracing::try_init_simple();
1315 new_test_ext().execute_with(|| {
1316 let x = Sr25519Keyring::Alice.into();
1317 let info = DispatchInfo::default();
1318 let len = 0_usize;
1319 assert_eq!(
1320 CheckSubstrateCall {}
1321 .validate_only(
1322 Some(x).into(),
1323 &ExtrinsicBuilder::new_call_with_priority(16).build().function,
1324 &info,
1325 len,
1326 External,
1327 0,
1328 )
1329 .unwrap()
1330 .0
1331 .priority,
1332 16
1333 );
1334
1335 assert_eq!(
1336 CheckSubstrateCall {}
1337 .validate_only(
1338 Some(x).into(),
1339 &ExtrinsicBuilder::new_call_do_not_propagate().build().function,
1340 &info,
1341 len,
1342 External,
1343 0,
1344 )
1345 .unwrap()
1346 .0
1347 .propagate,
1348 false
1349 );
1350 })
1351 }
1352
1353 mod genesis_builder_tests {
1354 use super::*;
1355 use crate::genesismap::GenesisStorageBuilder;
1356 use pretty_assertions::assert_eq;
1357 use sc_executor::{error::Result, WasmExecutor};
1358 use sc_executor_common::runtime_blob::RuntimeBlob;
1359 use serde_json::json;
1360 use sp_application_crypto::Ss58Codec;
1361 use sp_core::traits::Externalities;
1362 use sp_genesis_builder::Result as BuildResult;
1363 use sp_state_machine::BasicExternalities;
1364 use std::{fs, io::Write};
1365 use storage_key_generator::hex;
1366
1367 pub fn executor_call(
1368 ext: &mut dyn Externalities,
1369 method: &str,
1370 data: &[u8],
1371 ) -> Result<Vec<u8>> {
1372 let executor = WasmExecutor::<sp_io::SubstrateHostFunctions>::builder().build();
1373 executor.uncached_call(
1374 RuntimeBlob::uncompress_if_needed(wasm_binary_unwrap()).unwrap(),
1375 ext,
1376 true,
1377 method,
1378 data,
1379 )
1380 }
1381
1382 #[test]
1383 fn build_minimal_genesis_config_works() {
1384 sp_tracing::try_init_simple();
1385 let default_minimal_json = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c": [ 3, 10 ],"allowed_slots":"PrimaryAndSecondaryPlainSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
1386 let mut t = BasicExternalities::new_empty();
1387
1388 executor_call(&mut t, "GenesisBuilder_build_state", &default_minimal_json.encode())
1389 .unwrap();
1390
1391 let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
1392 keys.sort();
1393
1394 let mut expected = [
1395 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1397 "1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4",
1399 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1401 "26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710",
1403 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1405 "26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000",
1407 "26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439",
1409
1410 "26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8",
1412 "3a65787472696e7369635f696e646578",
1414 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1416
1417 "c2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429",
1420 "26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429",
1422 "1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429",
1424 "00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429",
1426 "d5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429",
1428 ].into_iter().map(String::from).collect::<Vec<_>>();
1429 expected.sort();
1430
1431 assert_eq!(expected, keys);
1432 }
1433
1434 #[test]
1435 fn default_config_as_json_works() {
1436 sp_tracing::try_init_simple();
1437 let mut t = BasicExternalities::new_empty();
1438 let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode())
1439 .unwrap();
1440 let r = Option::<Vec<u8>>::decode(&mut &r[..])
1441 .unwrap()
1442 .expect("default config is there");
1443 let json = String::from_utf8(r.into()).expect("returned value is json. qed.");
1444
1445 let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c":[1,4],"allowed_slots":"PrimaryAndSecondaryVRFSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[],"devAccounts":null}}"#;
1446 assert_eq!(expected.to_string(), json);
1447 }
1448
1449 #[test]
1450 fn preset_names_listing_works() {
1451 sp_tracing::try_init_simple();
1452 let mut t = BasicExternalities::new_empty();
1453 let r = executor_call(&mut t, "GenesisBuilder_preset_names", &vec![]).unwrap();
1454 let r = Vec::<PresetId>::decode(&mut &r[..]).unwrap();
1455 assert_eq!(r, vec![PresetId::from("foobar"), PresetId::from("staging"),]);
1456 log::info!("r: {:#?}", r);
1457 }
1458
1459 #[test]
1460 fn named_config_works() {
1461 sp_tracing::try_init_simple();
1462 let f = |cfg_name: &str, expected: &str| {
1463 let mut t = BasicExternalities::new_empty();
1464 let name = cfg_name.to_string();
1465 let r = executor_call(
1466 &mut t,
1467 "GenesisBuilder_get_preset",
1468 &Some(name.as_bytes()).encode(),
1469 )
1470 .unwrap();
1471 let r = Option::<Vec<u8>>::decode(&mut &r[..]).unwrap();
1472 let json =
1473 String::from_utf8(r.unwrap().into()).expect("returned value is json. qed.");
1474 log::info!("json: {:#?}", json);
1475 assert_eq!(expected.to_string(), json);
1476 };
1477
1478 f("foobar", r#"{"foo":"bar"}"#);
1479 f(
1480 "staging",
1481 r#"{"balances":{"balances":[["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",1000000000000000],["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",1000000000000000]]},"substrateTest":{"authorities":["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"]}}"#,
1482 );
1483 }
1484
1485 #[test]
1486 fn build_config_from_json_works() {
1487 sp_tracing::try_init_simple();
1488 let j = include_str!("../res/default_genesis_config.json");
1489
1490 let mut t = BasicExternalities::new_empty();
1491 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1492 let r = BuildResult::decode(&mut &r[..]);
1493 assert!(r.is_ok());
1494
1495 let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
1496
1497 keys.push(hex(b":code"));
1500 keys.sort();
1501
1502 assert_eq!(keys, storage_key_generator::get_expected_storage_hashed_keys(false));
1503 }
1504
1505 #[test]
1506 fn build_config_from_invalid_json_fails() {
1507 sp_tracing::try_init_simple();
1508 let j = include_str!("../res/default_genesis_config_invalid.json");
1509 let mut t = BasicExternalities::new_empty();
1510 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1511 let r = BuildResult::decode(&mut &r[..]).unwrap();
1512 log::info!("result: {:#?}", r);
1513 assert_eq!(r, Err(
1514 "Invalid JSON blob: unknown field `renamed_authorities`, expected `authorities` or `epochConfig` at line 4 column 25".to_string(),
1515 ));
1516 }
1517
1518 #[test]
1519 fn build_config_from_invalid_json_fails_2() {
1520 sp_tracing::try_init_simple();
1521 let j = include_str!("../res/default_genesis_config_invalid_2.json");
1522 let mut t = BasicExternalities::new_empty();
1523 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1524 let r = BuildResult::decode(&mut &r[..]).unwrap();
1525 assert_eq!(r, Err(
1526 "Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 3 column 9".to_string(),
1527 ));
1528 }
1529
1530 #[test]
1531 fn build_config_from_incomplete_json_fails() {
1532 sp_tracing::try_init_simple();
1533 let j = include_str!("../res/default_genesis_config_incomplete.json");
1534
1535 let mut t = BasicExternalities::new_empty();
1536 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1537 let r = core::result::Result::<(), String>::decode(&mut &r[..]).unwrap();
1538 assert_eq!(
1539 r,
1540 Err("Invalid JSON blob: missing field `authorities` at line 11 column 3"
1541 .to_string())
1542 );
1543 }
1544
1545 #[test]
1546 fn write_default_config_to_tmp_file() {
1547 if std::env::var("WRITE_DEFAULT_JSON_FOR_STR_GC").is_ok() {
1548 sp_tracing::try_init_simple();
1549 let mut file = fs::OpenOptions::new()
1550 .create(true)
1551 .write(true)
1552 .open("/tmp/default_genesis_config.json")
1553 .unwrap();
1554
1555 let j = serde_json::to_string(&GenesisStorageBuilder::default().genesis_config())
1556 .unwrap()
1557 .into_bytes();
1558 file.write_all(&j).unwrap();
1559 }
1560 }
1561
1562 #[test]
1563 fn build_genesis_config_with_patch_json_works() {
1564 sp_tracing::try_init_simple();
1566
1567 let mut t = BasicExternalities::new_empty();
1568 let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode())
1569 .unwrap();
1570 let r = Option::<Vec<u8>>::decode(&mut &r[..])
1571 .unwrap()
1572 .expect("default config is there");
1573 let mut default_config: serde_json::Value =
1574 serde_json::from_slice(&r[..]).expect("returned value is json. qed.");
1575
1576 let patch = json!({
1578 "babe": {
1579 "epochConfig": {
1580 "c": [
1581 7,
1582 10
1583 ],
1584 "allowed_slots": "PrimaryAndSecondaryPlainSlots"
1585 }
1586 },
1587 "substrateTest": {
1588 "authorities": [
1589 Sr25519Keyring::Ferdie.public().to_ss58check(),
1590 Sr25519Keyring::Alice.public().to_ss58check()
1591 ],
1592 }
1593 });
1594
1595 sc_chain_spec::json_merge(&mut default_config, patch);
1596
1597 let mut t = BasicExternalities::new_empty();
1599 executor_call(
1600 &mut t,
1601 "GenesisBuilder_build_state",
1602 &default_config.to_string().encode(),
1603 )
1604 .unwrap();
1605
1606 let storage = t.into_storages();
1608 let get_from_storage = |key: &str| -> Vec<u8> {
1609 storage.top.get(&array_bytes::hex2bytes(key).unwrap()).unwrap().clone()
1610 };
1611
1612 let value: Vec<u8> = get_from_storage(
1614 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1615 );
1616 let authority_key_vec =
1617 Vec::<sp_core::sr25519::Public>::decode(&mut &value[..]).unwrap();
1618 assert_eq!(authority_key_vec.len(), 2);
1619 assert_eq!(authority_key_vec[0], Sr25519Keyring::Ferdie.public());
1620 assert_eq!(authority_key_vec[1], Sr25519Keyring::Alice.public());
1621
1622 let value: Vec<u8> = get_from_storage(
1624 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1625 );
1626 assert_eq!(
1627 BabeEpochConfiguration::decode(&mut &value[..]).unwrap(),
1628 BabeEpochConfiguration {
1629 c: (7, 10),
1630 allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots
1631 }
1632 );
1633
1634 let value: Vec<u8> = get_from_storage(
1637 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1638 );
1639 assert_eq!(u64::decode(&mut &value[..]).unwrap(), 0);
1640
1641 let value: Vec<u8> = get_from_storage(
1643 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1644 );
1645 assert_eq!(H256::decode(&mut &value[..]).unwrap(), [69u8; 32].into());
1646 }
1647 }
1648}