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