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