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::AppSignature;
197 pub type EcdsaBls381Public = ecdsa_bls381::AppPublic;
198 pub type EcdsaBls381Pop = ecdsa_bls381::AppSignature;
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
209pub type EcdsaPop = ecdsa::AppSignature;
210pub type Sr25519Pop = sr25519::AppSignature;
211pub type Ed25519Pop = ed25519::AppSignature;
212
213decl_runtime_apis! {
214 #[api_version(2)]
215 pub trait TestAPI {
216 fn balance_of(id: AccountId) -> u64;
218 fn benchmark_add_one(val: &u64) -> u64;
220 fn benchmark_vector_add_one(vec: &Vec<u64>) -> Vec<u64>;
223 #[changed_in(2)]
225 fn function_signature_changed() -> Vec<u64>;
226 fn function_signature_changed() -> u64;
228 fn use_trie() -> u64;
230 fn benchmark_indirect_call() -> u64;
232 fn benchmark_direct_call() -> u64;
234 fn vec_with_capacity(size: u32) -> Vec<u8>;
236 fn get_block_number() -> u64;
238 fn test_ed25519_crypto() -> (ed25519::AppSignature, ed25519::AppPublic, Ed25519Pop);
242 fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic, Sr25519Pop);
246 fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, EcdsaPop);
250 fn test_bls381_crypto() -> (Bls381Pop, Bls381Public);
254 fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public);
258 fn test_storage();
260 fn test_witness(proof: StorageProof, root: crate::Hash);
262 fn test_multiple_arguments(data: Vec<u8>, other: Vec<u8>, num: u32);
265 fn do_trace_log();
267 fn verify_ed25519(sig: ed25519::Signature, public: ed25519::Public, message: Vec<u8>) -> bool;
269 fn write_key_value(key: Vec<u8>, value: Vec<u8>, panic: bool);
271 }
272}
273
274pub type Executive = frame_executive::Executive<
275 Runtime,
276 Block,
277 frame_system::ChainContext<Runtime>,
278 Runtime,
279 AllPalletsWithSystem,
280>;
281
282#[derive(
283 Copy, Clone, PartialEq, Eq, Encode, Decode, DecodeWithMemTracking, RuntimeDebug, TypeInfo,
284)]
285pub struct CheckSubstrateCall;
286
287impl sp_runtime::traits::Printable for CheckSubstrateCall {
288 fn print(&self) {
289 "CheckSubstrateCall".print()
290 }
291}
292
293impl sp_runtime::traits::RefundWeight for CheckSubstrateCall {
294 fn refund(&mut self, _weight: frame_support::weights::Weight) {}
295}
296impl sp_runtime::traits::ExtensionPostDispatchWeightHandler<CheckSubstrateCall>
297 for CheckSubstrateCall
298{
299 fn set_extension_weight(&mut self, _info: &CheckSubstrateCall) {}
300}
301
302impl sp_runtime::traits::Dispatchable for CheckSubstrateCall {
303 type RuntimeOrigin = RuntimeOrigin;
304 type Config = CheckSubstrateCall;
305 type Info = CheckSubstrateCall;
306 type PostInfo = CheckSubstrateCall;
307
308 fn dispatch(
309 self,
310 _origin: Self::RuntimeOrigin,
311 ) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
312 panic!("This implementation should not be used for actual dispatch.");
313 }
314}
315
316impl sp_runtime::traits::TransactionExtension<RuntimeCall> for CheckSubstrateCall {
317 const IDENTIFIER: &'static str = "CheckSubstrateCall";
318 type Implicit = ();
319 type Pre = ();
320 type Val = ();
321 impl_tx_ext_default!(RuntimeCall; weight prepare);
322
323 fn validate(
324 &self,
325 origin: <RuntimeCall as Dispatchable>::RuntimeOrigin,
326 call: &RuntimeCall,
327 _info: &DispatchInfoOf<RuntimeCall>,
328 _len: usize,
329 _self_implicit: Self::Implicit,
330 _inherited_implication: &impl Encode,
331 _source: TransactionSource,
332 ) -> Result<
333 (ValidTransaction, Self::Val, <RuntimeCall as Dispatchable>::RuntimeOrigin),
334 TransactionValidityError,
335 > {
336 log::trace!(target: LOG_TARGET, "validate");
337 let v = match call {
338 RuntimeCall::SubstrateTest(ref substrate_test_call) =>
339 substrate_test_pallet::validate_runtime_call(substrate_test_call)?,
340 _ => Default::default(),
341 };
342 Ok((v, (), origin))
343 }
344}
345
346construct_runtime!(
347 pub enum Runtime
348 {
349 System: frame_system,
350 Babe: pallet_babe,
351 SubstrateTest: substrate_test_pallet::pallet,
352 Utility: pallet_utility,
353 Balances: pallet_balances,
354 }
355);
356
357const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
360const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
363const MAXIMUM_BLOCK_WEIGHT: Weight =
365 Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);
366
367parameter_types! {
368 pub const BlockHashCount: BlockNumber = 2400;
369 pub const Version: RuntimeVersion = VERSION;
370
371 pub RuntimeBlockLength: BlockLength =
372 BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
373
374 pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
375 .base_block(BlockExecutionWeight::get())
376 .for_class(DispatchClass::all(), |weights| {
377 weights.base_extrinsic = ExtrinsicBaseWeight::get();
378 })
379 .for_class(DispatchClass::Normal, |weights| {
380 weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
381 })
382 .for_class(DispatchClass::Operational, |weights| {
383 weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
384 weights.reserved = Some(
387 MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
388 );
389 })
390 .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
391 .build_or_panic();
392}
393
394#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
395impl frame_system::pallet::Config for Runtime {
396 type BlockWeights = RuntimeBlockWeights;
397 type Nonce = Nonce;
398 type AccountId = AccountId;
399 type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
400 type Block = Block;
401 type AccountData = pallet_balances::AccountData<Balance>;
402}
403
404pub mod currency {
405 use crate::Balance;
406 const MILLICENTS: Balance = 1_000_000_000;
407 const CENTS: Balance = 1_000 * MILLICENTS; pub const DOLLARS: Balance = 100 * CENTS;
409}
410
411parameter_types! {
412 pub const ExistentialDeposit: Balance = 1 * currency::DOLLARS;
413 pub const MaxLocks: u32 = 50;
416 pub const MaxReserves: u32 = 50;
417}
418
419impl pallet_balances::Config for Runtime {
420 type MaxLocks = MaxLocks;
421 type MaxReserves = MaxReserves;
422 type ReserveIdentifier = [u8; 8];
423 type Balance = Balance;
424 type DustRemoval = ();
425 type RuntimeEvent = RuntimeEvent;
426 type ExistentialDeposit = ExistentialDeposit;
427 type AccountStore = System;
428 type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
429 type FreezeIdentifier = ();
430 type MaxFreezes = ();
431 type RuntimeHoldReason = RuntimeHoldReason;
432 type RuntimeFreezeReason = RuntimeFreezeReason;
433 type DoneSlashHandler = ();
434}
435
436impl pallet_utility::Config for Runtime {
437 type RuntimeEvent = RuntimeEvent;
438 type PalletsOrigin = OriginCaller;
439 type RuntimeCall = RuntimeCall;
440 type WeightInfo = ();
441}
442
443impl substrate_test_pallet::Config for Runtime {}
444
445impl pallet_timestamp::Config for Runtime {
447 type Moment = u64;
448 type OnTimestampSet = Babe;
449 type MinimumPeriod = ConstU64<500>;
450 type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
451}
452
453parameter_types! {
454 pub const EpochDuration: u64 = 6;
455}
456
457impl pallet_babe::Config for Runtime {
458 type EpochDuration = EpochDuration;
459 type ExpectedBlockTime = ConstU64<10_000>;
460 type EpochChangeTrigger = pallet_babe::SameAuthoritiesForever;
461 type DisabledValidators = ();
462 type KeyOwnerProof = sp_core::Void;
463 type EquivocationReportSystem = ();
464 type WeightInfo = ();
465 type MaxAuthorities = ConstU32<10>;
466 type MaxNominators = ConstU32<100>;
467}
468
469#[inline(never)]
471fn benchmark_add_one(i: u64) -> u64 {
472 i + 1
473}
474
475fn code_using_trie() -> u64 {
476 let pairs = [
477 (b"0103000000000000000464".to_vec(), b"0400000000".to_vec()),
478 (b"0103000000000000000469".to_vec(), b"0401000000".to_vec()),
479 ]
480 .to_vec();
481
482 let mut mdb = PrefixedMemoryDB::default();
483 let mut root = core::default::Default::default();
484 {
485 let mut t = TrieDBMutBuilderV1::<Hashing>::new(&mut mdb, &mut root).build();
486 for (key, value) in &pairs {
487 if t.insert(key, value).is_err() {
488 return 101
489 }
490 }
491 }
492
493 let trie = TrieDBBuilder::<Hashing>::new(&mdb, &root).build();
494 let res = if let Ok(iter) = trie.iter() { iter.flatten().count() as u64 } else { 102 };
495
496 res
497}
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) {
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, _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, Ed25519Pop) {
619 test_ed25519_crypto()
620 }
621
622 fn test_sr25519_crypto() -> (sr25519::AppSignature, sr25519::AppPublic, Sr25519Pop) {
623 test_sr25519_crypto()
624 }
625
626 fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, EcdsaPop) {
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 }
747 }
748
749 impl sp_session::SessionKeys<Block> for Runtime {
750 fn generate_session_keys(_: Option<Vec<u8>>) -> Vec<u8> {
751 SessionKeys::generate(None)
752 }
753
754 fn decode_session_keys(
755 encoded: Vec<u8>,
756 ) -> Option<Vec<(Vec<u8>, sp_core::crypto::KeyTypeId)>> {
757 SessionKeys::decode_into_raw_public_keys(&encoded)
758 }
759 }
760
761 impl sp_consensus_grandpa::GrandpaApi<Block> for Runtime {
762 fn grandpa_authorities() -> sp_consensus_grandpa::AuthorityList {
763 Vec::new()
764 }
765
766 fn current_set_id() -> sp_consensus_grandpa::SetId {
767 0
768 }
769
770 fn submit_report_equivocation_unsigned_extrinsic(
771 _equivocation_proof: sp_consensus_grandpa::EquivocationProof<
772 <Block as BlockT>::Hash,
773 NumberFor<Block>,
774 >,
775 _key_owner_proof: sp_consensus_grandpa::OpaqueKeyOwnershipProof,
776 ) -> Option<()> {
777 None
778 }
779
780 fn generate_key_ownership_proof(
781 _set_id: sp_consensus_grandpa::SetId,
782 _authority_id: sp_consensus_grandpa::AuthorityId,
783 ) -> Option<sp_consensus_grandpa::OpaqueKeyOwnershipProof> {
784 None
785 }
786 }
787
788 impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
789 fn build_state(config: Vec<u8>) -> sp_genesis_builder::Result {
790 build_state::<RuntimeGenesisConfig>(config)
791 }
792
793 fn get_preset(name: &Option<PresetId>) -> Option<Vec<u8>> {
794 get_preset::<RuntimeGenesisConfig>(name, |name| {
795 let patch = match name.as_ref() {
796 "staging" => {
797 let endowed_accounts: Vec<AccountId> = vec![
798 Sr25519Keyring::Bob.public().into(),
799 Sr25519Keyring::Charlie.public().into(),
800 ];
801
802 json!({
803 "balances": {
804 "balances": endowed_accounts.into_iter().map(|k| (k, 10 * currency::DOLLARS)).collect::<Vec<_>>(),
805 },
806 "substrateTest": {
807 "authorities": [
808 Sr25519Keyring::Alice.public().to_ss58check(),
809 Sr25519Keyring::Ferdie.public().to_ss58check()
810 ],
811 }
812 })
813 },
814 "foobar" => json!({"foo":"bar"}),
815 _ => return None,
816 };
817 Some(serde_json::to_string(&patch)
818 .expect("serialization to json is expected to work. qed.")
819 .into_bytes())
820 })
821 }
822
823 fn preset_names() -> Vec<PresetId> {
824 vec![PresetId::from("foobar"), PresetId::from("staging")]
825 }
826 }
827}
828
829fn test_ed25519_crypto() -> (ed25519::AppSignature, ed25519::AppPublic, Ed25519Pop) {
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()
841 .expect("Cant generate proof_of_possession for ed25519");
842 assert!(public0.verify_proof_of_possession(&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() -> (sr25519::AppSignature, sr25519::AppPublic, Sr25519Pop) {
850 let mut public0 = sr25519::AppPublic::generate_pair(None);
851 let public1 = sr25519::AppPublic::generate_pair(None);
852 let public2 = sr25519::AppPublic::generate_pair(None);
853
854 let all = sr25519::AppPublic::all();
855 assert!(all.contains(&public0));
856 assert!(all.contains(&public1));
857 assert!(all.contains(&public2));
858
859 let proof_of_possession = public0
860 .generate_proof_of_possession()
861 .expect("Cant generate proof_of_possession for sr25519");
862 assert!(public0.verify_proof_of_possession(&proof_of_possession));
863
864 let signature = public0.sign(&"sr25519").expect("Generates a valid `sr25519` signature.");
865 assert!(public0.verify(&"sr25519", &signature));
866 (signature, public0, proof_of_possession)
867}
868
869fn test_ecdsa_crypto() -> (ecdsa::AppSignature, ecdsa::AppPublic, EcdsaPop) {
870 let mut public0 = ecdsa::AppPublic::generate_pair(None);
871 let public1 = ecdsa::AppPublic::generate_pair(None);
872 let public2 = ecdsa::AppPublic::generate_pair(None);
873
874 let all = ecdsa::AppPublic::all();
875 assert!(all.contains(&public0));
876 assert!(all.contains(&public1));
877 assert!(all.contains(&public2));
878
879 let proof_of_possession = public0
880 .generate_proof_of_possession()
881 .expect("Cant generate proof_of_possession for ecdsa");
882 assert!(public0.verify_proof_of_possession(&proof_of_possession));
883
884 let signature = public0.sign(&"ecdsa").expect("Generates a valid `ecdsa` signature.");
885
886 assert!(public0.verify(&"ecdsa", &signature));
887 (signature, public0, proof_of_possession)
888}
889
890#[cfg(feature = "bls-experimental")]
891fn test_bls381_crypto() -> (Bls381Pop, Bls381Public) {
892 let mut public0 = bls381::AppPublic::generate_pair(None);
893
894 let proof_of_possession = public0
895 .generate_proof_of_possession()
896 .expect("Cant generate proof_of_possession for bls381");
897 assert!(public0.verify_proof_of_possession(&proof_of_possession));
898
899 (proof_of_possession, public0)
900}
901
902#[cfg(feature = "bls-experimental")]
903fn test_ecdsa_bls381_crypto() -> (EcdsaBls381Pop, EcdsaBls381Public) {
904 let mut public0 = ecdsa_bls381::AppPublic::generate_pair(None);
905
906 let proof_of_possession = public0
907 .generate_proof_of_possession()
908 .expect("Cant Generate proof_of_possession for ecdsa_bls381");
909 assert!(public0.verify_proof_of_possession(&proof_of_possession));
910
911 (proof_of_possession, public0)
912}
913
914fn test_read_storage() {
915 const KEY: &[u8] = b":read_storage";
916 sp_io::storage::set(KEY, b"test");
917
918 let mut v = [0u8; 4];
919 let r = sp_io::storage::read(KEY, &mut v, 0);
920 assert_eq!(r, Some(4));
921 assert_eq!(&v, b"test");
922
923 let mut v = [0u8; 4];
924 let r = sp_io::storage::read(KEY, &mut v, 4);
925 assert_eq!(r, Some(0));
926 assert_eq!(&v, &[0, 0, 0, 0]);
927}
928
929fn test_read_child_storage() {
930 const STORAGE_KEY: &[u8] = b"unique_id_1";
931 const KEY: &[u8] = b":read_child_storage";
932 sp_io::default_child_storage::set(STORAGE_KEY, KEY, b"test");
933
934 let mut v = [0u8; 4];
935 let r = sp_io::default_child_storage::read(STORAGE_KEY, KEY, &mut v, 0);
936 assert_eq!(r, Some(4));
937 assert_eq!(&v, b"test");
938
939 let mut v = [0u8; 4];
940 let r = sp_io::default_child_storage::read(STORAGE_KEY, KEY, &mut v, 8);
941 assert_eq!(r, Some(0));
942 assert_eq!(&v, &[0, 0, 0, 0]);
943}
944
945fn test_witness(proof: StorageProof, root: crate::Hash) {
946 use sp_externalities::Externalities;
947 let db: sp_trie::MemoryDB<crate::Hashing> = proof.into_memory_db();
948 let backend = sp_state_machine::TrieBackendBuilder::<_, crate::Hashing>::new(db, root).build();
949 let mut overlay = sp_state_machine::OverlayedChanges::default();
950 let mut ext = sp_state_machine::Ext::new(
951 &mut overlay,
952 &backend,
953 #[cfg(feature = "std")]
954 None,
955 );
956 assert!(ext.storage(b"value3").is_some());
957 assert!(ext.storage_root(Default::default()).as_slice() == &root[..]);
958 ext.place_storage(vec![0], Some(vec![1]));
959 assert!(ext.storage_root(Default::default()).as_slice() != &root[..]);
960}
961
962#[cfg(feature = "std")]
966pub mod storage_key_generator {
967 use super::*;
968 use sp_core::Pair;
969
970 pub(super) fn hex<T>(x: T) -> String
972 where
973 T: array_bytes::Hex,
974 {
975 x.hex(Default::default())
976 }
977
978 fn concat_hashes(input: &Vec<&[u8]>) -> String {
979 input.iter().map(|s| sp_crypto_hashing::twox_128(s)).map(hex).collect()
980 }
981
982 fn twox_64_concat(x: &[u8]) -> Vec<u8> {
983 sp_crypto_hashing::twox_64(x).iter().chain(x.iter()).cloned().collect()
984 }
985
986 pub fn generate_expected_storage_hashed_keys(custom_heap_pages: bool) -> Vec<String> {
989 let mut literals: Vec<&[u8]> = vec![b":code", b":extrinsic_index"];
990
991 if custom_heap_pages {
992 literals.push(b":heappages");
993 }
994
995 let keys: Vec<Vec<&[u8]>> = vec![
996 vec![b"Babe", b":__STORAGE_VERSION__:"],
997 vec![b"Babe", b"Authorities"],
998 vec![b"Babe", b"EpochConfig"],
999 vec![b"Babe", b"NextAuthorities"],
1000 vec![b"Babe", b"SegmentIndex"],
1001 vec![b"Balances", b":__STORAGE_VERSION__:"],
1002 vec![b"Balances", b"TotalIssuance"],
1003 vec![b"SubstrateTest", b":__STORAGE_VERSION__:"],
1004 vec![b"SubstrateTest", b"Authorities"],
1005 vec![b"System", b":__STORAGE_VERSION__:"],
1006 vec![b"System", b"LastRuntimeUpgrade"],
1007 vec![b"System", b"ParentHash"],
1008 vec![b"System", b"UpgradedToTripleRefCount"],
1009 vec![b"System", b"UpgradedToU32RefCount"],
1010 vec![b"Utility", b":__STORAGE_VERSION__:"],
1011 ];
1012
1013 let mut expected_keys = keys.iter().map(concat_hashes).collect::<Vec<String>>();
1014 expected_keys.extend(literals.into_iter().map(hex));
1015
1016 let balances_map_keys = (0..16_usize)
1017 .into_iter()
1018 .map(|i| Sr25519Keyring::numeric(i).public().to_vec())
1019 .chain(vec![
1020 Sr25519Keyring::Alice.public().to_vec(),
1021 Sr25519Keyring::Bob.public().to_vec(),
1022 Sr25519Keyring::Charlie.public().to_vec(),
1023 ])
1024 .map(|pubkey| {
1025 sp_crypto_hashing::blake2_128(&pubkey)
1026 .iter()
1027 .chain(pubkey.iter())
1028 .cloned()
1029 .collect::<Vec<u8>>()
1030 })
1031 .map(|hash_pubkey| {
1032 [concat_hashes(&vec![b"System", b"Account"]), hex(hash_pubkey)].concat()
1033 });
1034
1035 expected_keys.extend(balances_map_keys);
1036
1037 expected_keys.push(
1038 [
1039 concat_hashes(&vec![b"System", b"BlockHash"]),
1040 hex(0u64.using_encoded(twox_64_concat)),
1041 ]
1042 .concat(),
1043 );
1044
1045 expected_keys.sort();
1046 expected_keys
1047 }
1048
1049 pub fn get_expected_storage_hashed_keys(custom_heap_pages: bool) -> Vec<&'static str> {
1057 let mut res = vec![
1058 "00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429",
1060 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1062 "1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429",
1064 "1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d",
1066 "1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4",
1068 "1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c",
1070 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1072 "26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429",
1074 "26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710",
1076 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1078 "26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000",
1080 "26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439",
1082
1083 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da901cae4e3edfbb32c91ed3f01ab964f4eeeab50338d8e5176d3141802d7b010a55dadcd5f23cf8aaafa724627e967e90e",
1085 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da91b614bd4a126f2d5d294e9a8af9da25248d7e931307afb4b68d8d565d4c66e00d856c6d65f5fed6bb82dcfb60e936c67",
1087 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94b21aff9fe1e8b2fc4b0775b8cbeff28ba8e2c7594dd74730f3ca835e95455d199261897edc9735d602ea29615e2b10b",
1089 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48",
1091 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95786a2916fcb81e1bd5dcd81e0d2452884617f575372edb5a36d85c04cdf2e4699f96fe33eb5f94a28c041b88e398d0c",
1093 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da95b8542d9672c7b7e779cc7c1e6b605691c2115d06120ea2bee32dd601d02f36367564e7ddf84ae2717ca3f097459652e",
1095 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da996c30bdbfab640838e6b6d3c33ab4adb4211b79e34ee8072eab506edd4b93a7b85a14c9a05e5cdd056d98e7dbca87730",
1097 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99dc65b1339ec388fbf2ca0cdef51253512c6cfd663203ea16968594f24690338befd906856c4d2f4ef32dad578dba20c",
1099 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da99e6eb5abd62f5fd54793da91a47e6af6125d57171ff9241f07acaa1bb6a6103517965cf2cd00e643b27e7599ebccba70",
1101 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
1103 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d0052993b6f3bd0544fd1f5e4125b9fbde3e789ecd53431fe5c06c12b72137153496dace35c695b5f4d7b41f7ed5763b",
1105 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9d6b7e9a5f12bc571053265dade10d3b4b606fc73f57f03cdb4c932d475ab426043e429cecc2ffff0d2672b0df8398c48",
1107 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
1109 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e1a35f56ee295d39287cbffcfc60c4b346f136b564e1fad55031404dd84e5cd3fa76bfe7cc7599b39d38fd06663bbc0a",
1111 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9e2c1dc507e2035edbbd8776c440d870460c57f0008067cc01c5ff9eb2e2f9b3a94299a915a91198bd1021a6c55596f57",
1113 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9eca0e653a94f4080f6311b4e7b6934eb2afba9278e30ccf6a6ceb3a8b6e336b70068f045c666f2e7f4f9cc5f47db8972",
1115 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9ee8bf7ef90fc56a8aa3b90b344c599550c29b161e27ff8ba45bf6bad4711f326fc506a8803453a4d7e3158e993495f10",
1117 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9f5d6f1c082fe63eec7a71fcad00f4a892e3d43b7b0d04e776e69e7be35247cecdac65504c579195731eaf64b7940966e",
1119 "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9fbf0818841edf110e05228a6379763c4fc3c37459d9bdc61f58a5ebc01e9e2305a19d390c0543dc733861ec3cf1de01f",
1121 "26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8",
1123 "3a636f6465",
1125 "3a65787472696e7369635f696e646578",
1127 "c2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429",
1129 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1131 "d5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429",
1133 ];
1134
1135 if custom_heap_pages {
1136 res.push("3a686561707061676573");
1138 }
1139
1140 res
1141 }
1142}
1143
1144#[cfg(test)]
1145mod tests {
1146 use super::*;
1147 use codec::Encode;
1148 use frame_support::dispatch::DispatchInfo;
1149 use pretty_assertions::assert_eq;
1150 use sc_block_builder::BlockBuilderBuilder;
1151 use sp_api::{ApiExt, ProvideRuntimeApi};
1152 use sp_consensus::BlockOrigin;
1153 use sp_core::{storage::well_known_keys::HEAP_PAGES, traits::CallContext};
1154 use sp_runtime::{
1155 traits::{DispatchTransaction, Hash as _},
1156 transaction_validity::{InvalidTransaction, TransactionSource::External, ValidTransaction},
1157 };
1158 use substrate_test_runtime_client::{
1159 prelude::*, runtime::TestAPI, DefaultTestClientBuilderExt, TestClientBuilder,
1160 };
1161
1162 #[test]
1163 fn expected_keys_vec_are_matching() {
1164 assert_eq!(
1165 storage_key_generator::get_expected_storage_hashed_keys(false),
1166 storage_key_generator::generate_expected_storage_hashed_keys(false),
1167 );
1168 }
1169
1170 #[test]
1171 fn heap_pages_is_respected() {
1172 let client = TestClientBuilder::new().set_heap_pages(8).build();
1176 let best_hash = client.chain_info().best_hash;
1177
1178 let mut runtime_api = client.runtime_api();
1181 runtime_api.set_call_context(CallContext::Onchain);
1183 let ret = runtime_api.vec_with_capacity(best_hash, 1048576);
1184 assert!(ret.is_err());
1185
1186 let (new_at_hash, block) = {
1189 let mut builder = BlockBuilderBuilder::new(&client)
1190 .on_parent_block(best_hash)
1191 .with_parent_block_number(0)
1192 .build()
1193 .unwrap();
1194 builder.push_storage_change(HEAP_PAGES.to_vec(), Some(32u64.encode())).unwrap();
1195 let block = builder.build().unwrap().block;
1196 let hash = block.header.hash();
1197 (hash, block)
1198 };
1199
1200 futures::executor::block_on(client.import(BlockOrigin::Own, block)).unwrap();
1201
1202 let ret = client.runtime_api().vec_with_capacity(new_at_hash, 1048576);
1204 assert!(ret.is_ok());
1205 }
1206
1207 #[test]
1208 fn test_storage() {
1209 let client = TestClientBuilder::new().build();
1210 let runtime_api = client.runtime_api();
1211 let best_hash = client.chain_info().best_hash;
1212
1213 runtime_api.test_storage(best_hash).unwrap();
1214 }
1215
1216 fn witness_backend() -> (sp_trie::MemoryDB<crate::Hashing>, crate::Hash) {
1217 let mut root = crate::Hash::default();
1218 let mut mdb = sp_trie::MemoryDB::<crate::Hashing>::default();
1219 {
1220 let mut trie =
1221 sp_trie::trie_types::TrieDBMutBuilderV1::new(&mut mdb, &mut root).build();
1222 trie.insert(b"value3", &[142]).expect("insert failed");
1223 trie.insert(b"value4", &[124]).expect("insert failed");
1224 };
1225 (mdb, root)
1226 }
1227
1228 #[test]
1229 fn witness_backend_works() {
1230 let (db, root) = witness_backend();
1231 let backend =
1232 sp_state_machine::TrieBackendBuilder::<_, crate::Hashing>::new(db, root).build();
1233 let proof = sp_state_machine::prove_read(backend, vec![b"value3"]).unwrap();
1234 let client = TestClientBuilder::new().build();
1235 let runtime_api = client.runtime_api();
1236 let best_hash = client.chain_info().best_hash;
1237
1238 runtime_api.test_witness(best_hash, proof, root).unwrap();
1239 }
1240
1241 pub fn new_test_ext() -> sp_io::TestExternalities {
1242 genesismap::GenesisStorageBuilder::new(
1243 vec![Sr25519Keyring::One.public().into(), Sr25519Keyring::Two.public().into()],
1244 vec![Sr25519Keyring::One.into(), Sr25519Keyring::Two.into()],
1245 1000 * currency::DOLLARS,
1246 )
1247 .build()
1248 .into()
1249 }
1250
1251 #[test]
1252 fn validate_storage_keys() {
1253 assert_eq!(
1254 genesismap::GenesisStorageBuilder::default()
1255 .build()
1256 .top
1257 .keys()
1258 .cloned()
1259 .map(storage_key_generator::hex)
1260 .collect::<Vec<_>>(),
1261 storage_key_generator::get_expected_storage_hashed_keys(false)
1262 );
1263 }
1264
1265 #[test]
1266 fn validate_unsigned_works() {
1267 sp_tracing::try_init_simple();
1268 new_test_ext().execute_with(|| {
1269 let failing_calls = vec![
1270 substrate_test_pallet::Call::bench_call { transfer: Default::default() },
1271 substrate_test_pallet::Call::include_data { data: vec![] },
1272 substrate_test_pallet::Call::fill_block { ratio: Perbill::from_percent(50) },
1273 ];
1274 let succeeding_calls = vec![
1275 substrate_test_pallet::Call::deposit_log_digest_item {
1276 log: DigestItem::Other(vec![]),
1277 },
1278 substrate_test_pallet::Call::storage_change { key: vec![], value: None },
1279 substrate_test_pallet::Call::read { count: 0 },
1280 substrate_test_pallet::Call::read_and_panic { count: 0 },
1281 ];
1282
1283 for call in failing_calls {
1284 assert_eq!(
1285 <SubstrateTest as sp_runtime::traits::ValidateUnsigned>::validate_unsigned(
1286 TransactionSource::External,
1287 &call,
1288 ),
1289 InvalidTransaction::Call.into(),
1290 );
1291 }
1292
1293 for call in succeeding_calls {
1294 assert_eq!(
1295 <SubstrateTest as sp_runtime::traits::ValidateUnsigned>::validate_unsigned(
1296 TransactionSource::External,
1297 &call,
1298 ),
1299 Ok(ValidTransaction {
1300 provides: vec![BlakeTwo256::hash_of(&call).encode()],
1301 ..Default::default()
1302 })
1303 );
1304 }
1305 });
1306 }
1307
1308 #[test]
1309 fn check_substrate_check_signed_extension_works() {
1310 sp_tracing::try_init_simple();
1311 new_test_ext().execute_with(|| {
1312 let x = Sr25519Keyring::Alice.into();
1313 let info = DispatchInfo::default();
1314 let len = 0_usize;
1315 assert_eq!(
1316 CheckSubstrateCall {}
1317 .validate_only(
1318 Some(x).into(),
1319 &ExtrinsicBuilder::new_call_with_priority(16).build().function,
1320 &info,
1321 len,
1322 External,
1323 0,
1324 )
1325 .unwrap()
1326 .0
1327 .priority,
1328 16
1329 );
1330
1331 assert_eq!(
1332 CheckSubstrateCall {}
1333 .validate_only(
1334 Some(x).into(),
1335 &ExtrinsicBuilder::new_call_do_not_propagate().build().function,
1336 &info,
1337 len,
1338 External,
1339 0,
1340 )
1341 .unwrap()
1342 .0
1343 .propagate,
1344 false
1345 );
1346 })
1347 }
1348
1349 mod genesis_builder_tests {
1350 use super::*;
1351 use crate::genesismap::GenesisStorageBuilder;
1352 use pretty_assertions::assert_eq;
1353 use sc_executor::{error::Result, WasmExecutor};
1354 use sc_executor_common::runtime_blob::RuntimeBlob;
1355 use serde_json::json;
1356 use sp_application_crypto::Ss58Codec;
1357 use sp_core::traits::Externalities;
1358 use sp_genesis_builder::Result as BuildResult;
1359 use sp_state_machine::BasicExternalities;
1360 use std::{fs, io::Write};
1361 use storage_key_generator::hex;
1362
1363 pub fn executor_call(
1364 ext: &mut dyn Externalities,
1365 method: &str,
1366 data: &[u8],
1367 ) -> Result<Vec<u8>> {
1368 let executor = WasmExecutor::<sp_io::SubstrateHostFunctions>::builder().build();
1369 executor.uncached_call(
1370 RuntimeBlob::uncompress_if_needed(wasm_binary_unwrap()).unwrap(),
1371 ext,
1372 true,
1373 method,
1374 data,
1375 )
1376 }
1377
1378 #[test]
1379 fn build_minimal_genesis_config_works() {
1380 sp_tracing::try_init_simple();
1381 let default_minimal_json = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c": [ 3, 10 ],"allowed_slots":"PrimaryAndSecondaryPlainSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[]}}"#;
1382 let mut t = BasicExternalities::new_empty();
1383
1384 executor_call(&mut t, "GenesisBuilder_build_state", &default_minimal_json.encode())
1385 .unwrap();
1386
1387 let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
1388 keys.sort();
1389
1390 let mut expected = [
1391 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1393 "1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4",
1395 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1397 "26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710",
1399 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1401 "26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000",
1403 "26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439",
1405
1406 "26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8",
1408 "3a65787472696e7369635f696e646578",
1410 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1412
1413 "c2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429",
1416 "26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429",
1418 "1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429",
1420 "00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429",
1422 "d5e1a2fa16732ce6906189438c0a82c64e7b9012096b41c4eb3aaf947f6ea429",
1424 ].into_iter().map(String::from).collect::<Vec<_>>();
1425 expected.sort();
1426
1427 assert_eq!(expected, keys);
1428 }
1429
1430 #[test]
1431 fn default_config_as_json_works() {
1432 sp_tracing::try_init_simple();
1433 let mut t = BasicExternalities::new_empty();
1434 let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode())
1435 .unwrap();
1436 let r = Option::<Vec<u8>>::decode(&mut &r[..])
1437 .unwrap()
1438 .expect("default config is there");
1439 let json = String::from_utf8(r.into()).expect("returned value is json. qed.");
1440
1441 let expected = r#"{"system":{},"babe":{"authorities":[],"epochConfig":{"c":[1,4],"allowed_slots":"PrimaryAndSecondaryVRFSlots"}},"substrateTest":{"authorities":[]},"balances":{"balances":[],"devAccounts":null}}"#;
1442 assert_eq!(expected.to_string(), json);
1443 }
1444
1445 #[test]
1446 fn preset_names_listing_works() {
1447 sp_tracing::try_init_simple();
1448 let mut t = BasicExternalities::new_empty();
1449 let r = executor_call(&mut t, "GenesisBuilder_preset_names", &vec![]).unwrap();
1450 let r = Vec::<PresetId>::decode(&mut &r[..]).unwrap();
1451 assert_eq!(r, vec![PresetId::from("foobar"), PresetId::from("staging"),]);
1452 log::info!("r: {:#?}", r);
1453 }
1454
1455 #[test]
1456 fn named_config_works() {
1457 sp_tracing::try_init_simple();
1458 let f = |cfg_name: &str, expected: &str| {
1459 let mut t = BasicExternalities::new_empty();
1460 let name = cfg_name.to_string();
1461 let r = executor_call(
1462 &mut t,
1463 "GenesisBuilder_get_preset",
1464 &Some(name.as_bytes()).encode(),
1465 )
1466 .unwrap();
1467 let r = Option::<Vec<u8>>::decode(&mut &r[..]).unwrap();
1468 let json =
1469 String::from_utf8(r.unwrap().into()).expect("returned value is json. qed.");
1470 log::info!("json: {:#?}", json);
1471 assert_eq!(expected.to_string(), json);
1472 };
1473
1474 f("foobar", r#"{"foo":"bar"}"#);
1475 f(
1476 "staging",
1477 r#"{"balances":{"balances":[["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",1000000000000000],["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",1000000000000000]]},"substrateTest":{"authorities":["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"]}}"#,
1478 );
1479 }
1480
1481 #[test]
1482 fn build_config_from_json_works() {
1483 sp_tracing::try_init_simple();
1484 let j = include_str!("../res/default_genesis_config.json");
1485
1486 let mut t = BasicExternalities::new_empty();
1487 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1488 let r = BuildResult::decode(&mut &r[..]);
1489 assert!(r.is_ok());
1490
1491 let mut keys = t.into_storages().top.keys().cloned().map(hex).collect::<Vec<String>>();
1492
1493 keys.push(hex(b":code"));
1496 keys.sort();
1497
1498 assert_eq!(keys, storage_key_generator::get_expected_storage_hashed_keys(false));
1499 }
1500
1501 #[test]
1502 fn build_config_from_invalid_json_fails() {
1503 sp_tracing::try_init_simple();
1504 let j = include_str!("../res/default_genesis_config_invalid.json");
1505 let mut t = BasicExternalities::new_empty();
1506 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1507 let r = BuildResult::decode(&mut &r[..]).unwrap();
1508 log::info!("result: {:#?}", r);
1509 assert_eq!(r, Err(
1510 "Invalid JSON blob: unknown field `renamed_authorities`, expected `authorities` or `epochConfig` at line 4 column 25".to_string(),
1511 ));
1512 }
1513
1514 #[test]
1515 fn build_config_from_invalid_json_fails_2() {
1516 sp_tracing::try_init_simple();
1517 let j = include_str!("../res/default_genesis_config_invalid_2.json");
1518 let mut t = BasicExternalities::new_empty();
1519 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1520 let r = BuildResult::decode(&mut &r[..]).unwrap();
1521 assert_eq!(r, Err(
1522 "Invalid JSON blob: unknown field `babex`, expected one of `system`, `babe`, `substrateTest`, `balances` at line 3 column 9".to_string(),
1523 ));
1524 }
1525
1526 #[test]
1527 fn build_config_from_incomplete_json_fails() {
1528 sp_tracing::try_init_simple();
1529 let j = include_str!("../res/default_genesis_config_incomplete.json");
1530
1531 let mut t = BasicExternalities::new_empty();
1532 let r = executor_call(&mut t, "GenesisBuilder_build_state", &j.encode()).unwrap();
1533 let r = core::result::Result::<(), String>::decode(&mut &r[..]).unwrap();
1534 assert_eq!(
1535 r,
1536 Err("Invalid JSON blob: missing field `authorities` at line 11 column 3"
1537 .to_string())
1538 );
1539 }
1540
1541 #[test]
1542 fn write_default_config_to_tmp_file() {
1543 if std::env::var("WRITE_DEFAULT_JSON_FOR_STR_GC").is_ok() {
1544 sp_tracing::try_init_simple();
1545 let mut file = fs::OpenOptions::new()
1546 .create(true)
1547 .write(true)
1548 .open("/tmp/default_genesis_config.json")
1549 .unwrap();
1550
1551 let j = serde_json::to_string(&GenesisStorageBuilder::default().genesis_config())
1552 .unwrap()
1553 .into_bytes();
1554 file.write_all(&j).unwrap();
1555 }
1556 }
1557
1558 #[test]
1559 fn build_genesis_config_with_patch_json_works() {
1560 sp_tracing::try_init_simple();
1562
1563 let mut t = BasicExternalities::new_empty();
1564 let r = executor_call(&mut t, "GenesisBuilder_get_preset", &None::<&PresetId>.encode())
1565 .unwrap();
1566 let r = Option::<Vec<u8>>::decode(&mut &r[..])
1567 .unwrap()
1568 .expect("default config is there");
1569 let mut default_config: serde_json::Value =
1570 serde_json::from_slice(&r[..]).expect("returned value is json. qed.");
1571
1572 let patch = json!({
1574 "babe": {
1575 "epochConfig": {
1576 "c": [
1577 7,
1578 10
1579 ],
1580 "allowed_slots": "PrimaryAndSecondaryPlainSlots"
1581 }
1582 },
1583 "substrateTest": {
1584 "authorities": [
1585 Sr25519Keyring::Ferdie.public().to_ss58check(),
1586 Sr25519Keyring::Alice.public().to_ss58check()
1587 ],
1588 }
1589 });
1590
1591 sc_chain_spec::json_merge(&mut default_config, patch);
1592
1593 let mut t = BasicExternalities::new_empty();
1595 executor_call(
1596 &mut t,
1597 "GenesisBuilder_build_state",
1598 &default_config.to_string().encode(),
1599 )
1600 .unwrap();
1601
1602 let storage = t.into_storages();
1604 let get_from_storage = |key: &str| -> Vec<u8> {
1605 storage.top.get(&array_bytes::hex2bytes(key).unwrap()).unwrap().clone()
1606 };
1607
1608 let value: Vec<u8> = get_from_storage(
1610 "00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d",
1611 );
1612 let authority_key_vec =
1613 Vec::<sp_core::sr25519::Public>::decode(&mut &value[..]).unwrap();
1614 assert_eq!(authority_key_vec.len(), 2);
1615 assert_eq!(authority_key_vec[0], Sr25519Keyring::Ferdie.public());
1616 assert_eq!(authority_key_vec[1], Sr25519Keyring::Alice.public());
1617
1618 let value: Vec<u8> = get_from_storage(
1620 "1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef",
1621 );
1622 assert_eq!(
1623 BabeEpochConfiguration::decode(&mut &value[..]).unwrap(),
1624 BabeEpochConfiguration {
1625 c: (7, 10),
1626 allowed_slots: AllowedSlots::PrimaryAndSecondaryPlainSlots
1627 }
1628 );
1629
1630 let value: Vec<u8> = get_from_storage(
1633 "c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80",
1634 );
1635 assert_eq!(u64::decode(&mut &value[..]).unwrap(), 0);
1636
1637 let value: Vec<u8> = get_from_storage(
1639 "26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc",
1640 );
1641 assert_eq!(H256::decode(&mut &value[..]).unwrap(), [69u8; 32].into());
1642 }
1643 }
1644}