1#![warn(missing_docs)]
77#![cfg_attr(not(feature = "std"), no_std)]
78#![cfg_attr(enable_alloc_error_handler, feature(alloc_error_handler))]
79
80extern crate alloc;
81
82use alloc::vec::Vec;
83
84#[cfg(feature = "std")]
85use tracing;
86
87#[cfg(feature = "std")]
88use sp_core::{
89 crypto::Pair,
90 hexdisplay::HexDisplay,
91 offchain::{OffchainDbExt, OffchainWorkerExt, TransactionPoolExt},
92 storage::ChildInfo,
93};
94#[cfg(feature = "std")]
95use sp_keystore::KeystoreExt;
96
97use sp_core::{
98 crypto::KeyTypeId,
99 ecdsa, ed25519,
100 offchain::{
101 HttpError, HttpRequestId, HttpRequestStatus, OpaqueNetworkState, StorageKind, Timestamp,
102 },
103 sr25519,
104 storage::StateVersion,
105 LogLevel, LogLevelFilter, OpaquePeerId, H256,
106};
107
108#[cfg(feature = "bls-experimental")]
109use sp_core::{bls381, ecdsa_bls381};
110
111#[cfg(feature = "std")]
112use sp_trie::{LayoutV0, LayoutV1, TrieConfiguration};
113
114use sp_runtime_interface::{
115 pass_by::{PassBy, PassByCodec},
116 runtime_interface, Pointer,
117};
118
119use codec::{Decode, Encode};
120
121#[cfg(feature = "std")]
122use secp256k1::{
123 ecdsa::{RecoverableSignature, RecoveryId},
124 Message, SECP256K1,
125};
126
127#[cfg(feature = "std")]
128use sp_externalities::{Externalities, ExternalitiesExt};
129
130pub use sp_externalities::MultiRemovalResults;
131
132#[cfg(all(not(feature = "disable_allocator"), substrate_runtime, target_family = "wasm"))]
133mod global_alloc_wasm;
134
135#[cfg(all(
136 not(feature = "disable_allocator"),
137 substrate_runtime,
138 any(target_arch = "riscv32", target_arch = "riscv64")
139))]
140mod global_alloc_riscv;
141
142#[cfg(feature = "std")]
143const LOG_TARGET: &str = "runtime::io";
144
145#[derive(Encode, Decode)]
147pub enum EcdsaVerifyError {
148 BadRS,
150 BadV,
152 BadSignature,
154}
155
156#[derive(PassByCodec, Encode, Decode)]
159pub enum KillStorageResult {
160 AllRemoved(u32),
163 SomeRemaining(u32),
166}
167
168impl From<MultiRemovalResults> for KillStorageResult {
169 fn from(r: MultiRemovalResults) -> Self {
170 match r.maybe_cursor {
174 None => Self::AllRemoved(r.loops),
175 Some(..) => Self::SomeRemaining(r.loops),
176 }
177 }
178}
179
180#[runtime_interface]
182pub trait Storage {
183 fn get(&mut self, key: &[u8]) -> Option<bytes::Bytes> {
185 self.storage(key).map(bytes::Bytes::from)
186 }
187
188 fn read(&mut self, key: &[u8], value_out: &mut [u8], value_offset: u32) -> Option<u32> {
194 self.storage(key).map(|value| {
195 let value_offset = value_offset as usize;
196 let data = &value[value_offset.min(value.len())..];
197 let written = std::cmp::min(data.len(), value_out.len());
198 value_out[..written].copy_from_slice(&data[..written]);
199 data.len() as u32
200 })
201 }
202
203 fn set(&mut self, key: &[u8], value: &[u8]) {
205 self.set_storage(key.to_vec(), value.to_vec());
206 }
207
208 fn clear(&mut self, key: &[u8]) {
210 self.clear_storage(key)
211 }
212
213 fn exists(&mut self, key: &[u8]) -> bool {
215 self.exists_storage(key)
216 }
217
218 fn clear_prefix(&mut self, prefix: &[u8]) {
220 let _ = Externalities::clear_prefix(*self, prefix, None, None);
221 }
222
223 #[version(2)]
249 fn clear_prefix(&mut self, prefix: &[u8], limit: Option<u32>) -> KillStorageResult {
250 Externalities::clear_prefix(*self, prefix, limit, None).into()
251 }
252
253 #[version(3, register_only)]
285 fn clear_prefix(
286 &mut self,
287 maybe_prefix: &[u8],
288 maybe_limit: Option<u32>,
289 maybe_cursor: Option<Vec<u8>>, ) -> MultiRemovalResults {
291 Externalities::clear_prefix(
292 *self,
293 maybe_prefix,
294 maybe_limit,
295 maybe_cursor.as_ref().map(|x| &x[..]),
296 )
297 .into()
298 }
299
300 fn append(&mut self, key: &[u8], value: Vec<u8>) {
309 self.storage_append(key.to_vec(), value);
310 }
311
312 fn root(&mut self) -> Vec<u8> {
318 self.storage_root(StateVersion::V0)
319 }
320
321 #[version(2)]
327 fn root(&mut self, version: StateVersion) -> Vec<u8> {
328 self.storage_root(version)
329 }
330
331 fn changes_root(&mut self, _parent_hash: &[u8]) -> Option<Vec<u8>> {
333 None
334 }
335
336 fn next_key(&mut self, key: &[u8]) -> Option<Vec<u8>> {
338 self.next_storage_key(key)
339 }
340
341 fn start_transaction(&mut self) {
354 self.storage_start_transaction();
355 }
356
357 fn rollback_transaction(&mut self) {
365 self.storage_rollback_transaction()
366 .expect("No open transaction that can be rolled back.");
367 }
368
369 fn commit_transaction(&mut self) {
377 self.storage_commit_transaction()
378 .expect("No open transaction that can be committed.");
379 }
380}
381
382#[runtime_interface]
385pub trait DefaultChildStorage {
386 fn get(&mut self, storage_key: &[u8], key: &[u8]) -> Option<Vec<u8>> {
391 let child_info = ChildInfo::new_default(storage_key);
392 self.child_storage(&child_info, key).map(|s| s.to_vec())
393 }
394
395 fn read(
403 &mut self,
404 storage_key: &[u8],
405 key: &[u8],
406 value_out: &mut [u8],
407 value_offset: u32,
408 ) -> Option<u32> {
409 let child_info = ChildInfo::new_default(storage_key);
410 self.child_storage(&child_info, key).map(|value| {
411 let value_offset = value_offset as usize;
412 let data = &value[value_offset.min(value.len())..];
413 let written = std::cmp::min(data.len(), value_out.len());
414 value_out[..written].copy_from_slice(&data[..written]);
415 data.len() as u32
416 })
417 }
418
419 fn set(&mut self, storage_key: &[u8], key: &[u8], value: &[u8]) {
423 let child_info = ChildInfo::new_default(storage_key);
424 self.set_child_storage(&child_info, key.to_vec(), value.to_vec());
425 }
426
427 fn clear(&mut self, storage_key: &[u8], key: &[u8]) {
431 let child_info = ChildInfo::new_default(storage_key);
432 self.clear_child_storage(&child_info, key);
433 }
434
435 fn storage_kill(&mut self, storage_key: &[u8]) {
440 let child_info = ChildInfo::new_default(storage_key);
441 let _ = self.kill_child_storage(&child_info, None, None);
442 }
443
444 #[version(2)]
448 fn storage_kill(&mut self, storage_key: &[u8], limit: Option<u32>) -> bool {
449 let child_info = ChildInfo::new_default(storage_key);
450 let r = self.kill_child_storage(&child_info, limit, None);
451 r.maybe_cursor.is_none()
452 }
453
454 #[version(3)]
458 fn storage_kill(&mut self, storage_key: &[u8], limit: Option<u32>) -> KillStorageResult {
459 let child_info = ChildInfo::new_default(storage_key);
460 self.kill_child_storage(&child_info, limit, None).into()
461 }
462
463 #[version(4, register_only)]
467 fn storage_kill(
468 &mut self,
469 storage_key: &[u8],
470 maybe_limit: Option<u32>,
471 maybe_cursor: Option<Vec<u8>>,
472 ) -> MultiRemovalResults {
473 let child_info = ChildInfo::new_default(storage_key);
474 self.kill_child_storage(&child_info, maybe_limit, maybe_cursor.as_ref().map(|x| &x[..]))
475 .into()
476 }
477
478 fn exists(&mut self, storage_key: &[u8], key: &[u8]) -> bool {
482 let child_info = ChildInfo::new_default(storage_key);
483 self.exists_child_storage(&child_info, key)
484 }
485
486 fn clear_prefix(&mut self, storage_key: &[u8], prefix: &[u8]) {
490 let child_info = ChildInfo::new_default(storage_key);
491 let _ = self.clear_child_prefix(&child_info, prefix, None, None);
492 }
493
494 #[version(2)]
498 fn clear_prefix(
499 &mut self,
500 storage_key: &[u8],
501 prefix: &[u8],
502 limit: Option<u32>,
503 ) -> KillStorageResult {
504 let child_info = ChildInfo::new_default(storage_key);
505 self.clear_child_prefix(&child_info, prefix, limit, None).into()
506 }
507
508 #[version(3, register_only)]
512 fn clear_prefix(
513 &mut self,
514 storage_key: &[u8],
515 prefix: &[u8],
516 maybe_limit: Option<u32>,
517 maybe_cursor: Option<Vec<u8>>,
518 ) -> MultiRemovalResults {
519 let child_info = ChildInfo::new_default(storage_key);
520 self.clear_child_prefix(
521 &child_info,
522 prefix,
523 maybe_limit,
524 maybe_cursor.as_ref().map(|x| &x[..]),
525 )
526 .into()
527 }
528
529 fn root(&mut self, storage_key: &[u8]) -> Vec<u8> {
536 let child_info = ChildInfo::new_default(storage_key);
537 self.child_storage_root(&child_info, StateVersion::V0)
538 }
539
540 #[version(2)]
547 fn root(&mut self, storage_key: &[u8], version: StateVersion) -> Vec<u8> {
548 let child_info = ChildInfo::new_default(storage_key);
549 self.child_storage_root(&child_info, version)
550 }
551
552 fn next_key(&mut self, storage_key: &[u8], key: &[u8]) -> Option<Vec<u8>> {
556 let child_info = ChildInfo::new_default(storage_key);
557 self.next_child_storage_key(&child_info, key)
558 }
559}
560
561#[runtime_interface]
563pub trait Trie {
564 fn blake2_256_root(input: Vec<(Vec<u8>, Vec<u8>)>) -> H256 {
566 LayoutV0::<sp_core::Blake2Hasher>::trie_root(input)
567 }
568
569 #[version(2)]
571 fn blake2_256_root(input: Vec<(Vec<u8>, Vec<u8>)>, version: StateVersion) -> H256 {
572 match version {
573 StateVersion::V0 => LayoutV0::<sp_core::Blake2Hasher>::trie_root(input),
574 StateVersion::V1 => LayoutV1::<sp_core::Blake2Hasher>::trie_root(input),
575 }
576 }
577
578 fn blake2_256_ordered_root(input: Vec<Vec<u8>>) -> H256 {
580 LayoutV0::<sp_core::Blake2Hasher>::ordered_trie_root(input)
581 }
582
583 #[version(2)]
585 fn blake2_256_ordered_root(input: Vec<Vec<u8>>, version: StateVersion) -> H256 {
586 match version {
587 StateVersion::V0 => LayoutV0::<sp_core::Blake2Hasher>::ordered_trie_root(input),
588 StateVersion::V1 => LayoutV1::<sp_core::Blake2Hasher>::ordered_trie_root(input),
589 }
590 }
591
592 fn keccak_256_root(input: Vec<(Vec<u8>, Vec<u8>)>) -> H256 {
594 LayoutV0::<sp_core::KeccakHasher>::trie_root(input)
595 }
596
597 #[version(2)]
599 fn keccak_256_root(input: Vec<(Vec<u8>, Vec<u8>)>, version: StateVersion) -> H256 {
600 match version {
601 StateVersion::V0 => LayoutV0::<sp_core::KeccakHasher>::trie_root(input),
602 StateVersion::V1 => LayoutV1::<sp_core::KeccakHasher>::trie_root(input),
603 }
604 }
605
606 fn keccak_256_ordered_root(input: Vec<Vec<u8>>) -> H256 {
608 LayoutV0::<sp_core::KeccakHasher>::ordered_trie_root(input)
609 }
610
611 #[version(2)]
613 fn keccak_256_ordered_root(input: Vec<Vec<u8>>, version: StateVersion) -> H256 {
614 match version {
615 StateVersion::V0 => LayoutV0::<sp_core::KeccakHasher>::ordered_trie_root(input),
616 StateVersion::V1 => LayoutV1::<sp_core::KeccakHasher>::ordered_trie_root(input),
617 }
618 }
619
620 fn blake2_256_verify_proof(root: H256, proof: &[Vec<u8>], key: &[u8], value: &[u8]) -> bool {
622 sp_trie::verify_trie_proof::<LayoutV0<sp_core::Blake2Hasher>, _, _, _>(
623 &root,
624 proof,
625 &[(key, Some(value))],
626 )
627 .is_ok()
628 }
629
630 #[version(2)]
632 fn blake2_256_verify_proof(
633 root: H256,
634 proof: &[Vec<u8>],
635 key: &[u8],
636 value: &[u8],
637 version: StateVersion,
638 ) -> bool {
639 match version {
640 StateVersion::V0 => sp_trie::verify_trie_proof::<
641 LayoutV0<sp_core::Blake2Hasher>,
642 _,
643 _,
644 _,
645 >(&root, proof, &[(key, Some(value))])
646 .is_ok(),
647 StateVersion::V1 => sp_trie::verify_trie_proof::<
648 LayoutV1<sp_core::Blake2Hasher>,
649 _,
650 _,
651 _,
652 >(&root, proof, &[(key, Some(value))])
653 .is_ok(),
654 }
655 }
656
657 fn keccak_256_verify_proof(root: H256, proof: &[Vec<u8>], key: &[u8], value: &[u8]) -> bool {
659 sp_trie::verify_trie_proof::<LayoutV0<sp_core::KeccakHasher>, _, _, _>(
660 &root,
661 proof,
662 &[(key, Some(value))],
663 )
664 .is_ok()
665 }
666
667 #[version(2)]
669 fn keccak_256_verify_proof(
670 root: H256,
671 proof: &[Vec<u8>],
672 key: &[u8],
673 value: &[u8],
674 version: StateVersion,
675 ) -> bool {
676 match version {
677 StateVersion::V0 => sp_trie::verify_trie_proof::<
678 LayoutV0<sp_core::KeccakHasher>,
679 _,
680 _,
681 _,
682 >(&root, proof, &[(key, Some(value))])
683 .is_ok(),
684 StateVersion::V1 => sp_trie::verify_trie_proof::<
685 LayoutV1<sp_core::KeccakHasher>,
686 _,
687 _,
688 _,
689 >(&root, proof, &[(key, Some(value))])
690 .is_ok(),
691 }
692 }
693}
694
695#[runtime_interface]
698pub trait Misc {
699 fn print_num(val: u64) {
704 log::debug!(target: "runtime", "{}", val);
705 }
706
707 fn print_utf8(utf8: &[u8]) {
709 if let Ok(data) = std::str::from_utf8(utf8) {
710 log::debug!(target: "runtime", "{}", data)
711 }
712 }
713
714 fn print_hex(data: &[u8]) {
716 log::debug!(target: "runtime", "{}", HexDisplay::from(&data));
717 }
718
719 fn runtime_version(&mut self, wasm: &[u8]) -> Option<Vec<u8>> {
735 use sp_core::traits::ReadRuntimeVersionExt;
736
737 let mut ext = sp_state_machine::BasicExternalities::default();
738
739 match self
740 .extension::<ReadRuntimeVersionExt>()
741 .expect("No `ReadRuntimeVersionExt` associated for the current context!")
742 .read_runtime_version(wasm, &mut ext)
743 {
744 Ok(v) => Some(v),
745 Err(err) => {
746 log::debug!(
747 target: LOG_TARGET,
748 "cannot read version from the given runtime: {}",
749 err,
750 );
751 None
752 },
753 }
754 }
755}
756
757#[cfg(feature = "std")]
758sp_externalities::decl_extension! {
759 pub struct UseDalekExt;
776}
777
778#[cfg(feature = "std")]
779impl Default for UseDalekExt {
780 fn default() -> Self {
781 Self
782 }
783}
784
785#[runtime_interface]
787pub trait Crypto {
788 fn ed25519_public_keys(&mut self, id: KeyTypeId) -> Vec<ed25519::Public> {
790 self.extension::<KeystoreExt>()
791 .expect("No `keystore` associated for the current context!")
792 .ed25519_public_keys(id)
793 }
794
795 fn ed25519_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> ed25519::Public {
802 let seed = seed.as_ref().map(|s| std::str::from_utf8(s).expect("Seed is valid utf8!"));
803 self.extension::<KeystoreExt>()
804 .expect("No `keystore` associated for the current context!")
805 .ed25519_generate_new(id, seed)
806 .expect("`ed25519_generate` failed")
807 }
808
809 fn ed25519_sign(
814 &mut self,
815 id: KeyTypeId,
816 pub_key: &ed25519::Public,
817 msg: &[u8],
818 ) -> Option<ed25519::Signature> {
819 self.extension::<KeystoreExt>()
820 .expect("No `keystore` associated for the current context!")
821 .ed25519_sign(id, pub_key, msg)
822 .ok()
823 .flatten()
824 }
825
826 fn ed25519_verify(sig: &ed25519::Signature, msg: &[u8], pub_key: &ed25519::Public) -> bool {
830 if sp_externalities::with_externalities(|mut e| e.extension::<UseDalekExt>().is_some())
834 .unwrap_or_default()
835 {
836 use ed25519_dalek::Verifier;
837
838 let Ok(public_key) = ed25519_dalek::VerifyingKey::from_bytes(&pub_key.0) else {
839 return false
840 };
841
842 let sig = ed25519_dalek::Signature::from_bytes(&sig.0);
843
844 public_key.verify(msg, &sig).is_ok()
845 } else {
846 ed25519::Pair::verify(sig, msg, pub_key)
847 }
848 }
849
850 #[version(1, register_only)]
864 fn ed25519_batch_verify(
865 &mut self,
866 sig: &ed25519::Signature,
867 msg: &[u8],
868 pub_key: &ed25519::Public,
869 ) -> bool {
870 let res = ed25519_verify(sig, msg, pub_key);
871
872 if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
873 ext.0 &= res;
874 }
875
876 res
877 }
878
879 #[version(2)]
883 fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pub_key: &sr25519::Public) -> bool {
884 sr25519::Pair::verify(sig, msg, pub_key)
885 }
886
887 #[version(1, register_only)]
901 fn sr25519_batch_verify(
902 &mut self,
903 sig: &sr25519::Signature,
904 msg: &[u8],
905 pub_key: &sr25519::Public,
906 ) -> bool {
907 let res = sr25519_verify(sig, msg, pub_key);
908
909 if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
910 ext.0 &= res;
911 }
912
913 res
914 }
915
916 #[version(1, register_only)]
923 fn start_batch_verify(&mut self) {
924 self.register_extension(VerificationExtDeprecated(true))
925 .expect("Failed to register required extension: `VerificationExt`");
926 }
927
928 #[version(1, register_only)]
940 fn finish_batch_verify(&mut self) -> bool {
941 let result = self
942 .extension::<VerificationExtDeprecated>()
943 .expect("`finish_batch_verify` should only be called after `start_batch_verify`")
944 .0;
945
946 self.deregister_extension::<VerificationExtDeprecated>()
947 .expect("No verification extension in current context!");
948
949 result
950 }
951
952 fn sr25519_public_keys(&mut self, id: KeyTypeId) -> Vec<sr25519::Public> {
954 self.extension::<KeystoreExt>()
955 .expect("No `keystore` associated for the current context!")
956 .sr25519_public_keys(id)
957 }
958
959 fn sr25519_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> sr25519::Public {
966 let seed = seed.as_ref().map(|s| std::str::from_utf8(s).expect("Seed is valid utf8!"));
967 self.extension::<KeystoreExt>()
968 .expect("No `keystore` associated for the current context!")
969 .sr25519_generate_new(id, seed)
970 .expect("`sr25519_generate` failed")
971 }
972
973 fn sr25519_sign(
978 &mut self,
979 id: KeyTypeId,
980 pub_key: &sr25519::Public,
981 msg: &[u8],
982 ) -> Option<sr25519::Signature> {
983 self.extension::<KeystoreExt>()
984 .expect("No `keystore` associated for the current context!")
985 .sr25519_sign(id, pub_key, msg)
986 .ok()
987 .flatten()
988 }
989
990 fn sr25519_verify(sig: &sr25519::Signature, msg: &[u8], pubkey: &sr25519::Public) -> bool {
995 sr25519::Pair::verify_deprecated(sig, msg, pubkey)
996 }
997
998 fn ecdsa_public_keys(&mut self, id: KeyTypeId) -> Vec<ecdsa::Public> {
1000 self.extension::<KeystoreExt>()
1001 .expect("No `keystore` associated for the current context!")
1002 .ecdsa_public_keys(id)
1003 }
1004
1005 fn ecdsa_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> ecdsa::Public {
1012 let seed = seed.as_ref().map(|s| std::str::from_utf8(s).expect("Seed is valid utf8!"));
1013 self.extension::<KeystoreExt>()
1014 .expect("No `keystore` associated for the current context!")
1015 .ecdsa_generate_new(id, seed)
1016 .expect("`ecdsa_generate` failed")
1017 }
1018
1019 fn ecdsa_sign(
1024 &mut self,
1025 id: KeyTypeId,
1026 pub_key: &ecdsa::Public,
1027 msg: &[u8],
1028 ) -> Option<ecdsa::Signature> {
1029 self.extension::<KeystoreExt>()
1030 .expect("No `keystore` associated for the current context!")
1031 .ecdsa_sign(id, pub_key, msg)
1032 .ok()
1033 .flatten()
1034 }
1035
1036 fn ecdsa_sign_prehashed(
1041 &mut self,
1042 id: KeyTypeId,
1043 pub_key: &ecdsa::Public,
1044 msg: &[u8; 32],
1045 ) -> Option<ecdsa::Signature> {
1046 self.extension::<KeystoreExt>()
1047 .expect("No `keystore` associated for the current context!")
1048 .ecdsa_sign_prehashed(id, pub_key, msg)
1049 .ok()
1050 .flatten()
1051 }
1052
1053 fn ecdsa_verify(sig: &ecdsa::Signature, msg: &[u8], pub_key: &ecdsa::Public) -> bool {
1058 #[allow(deprecated)]
1059 ecdsa::Pair::verify_deprecated(sig, msg, pub_key)
1060 }
1061
1062 #[version(2)]
1066 fn ecdsa_verify(sig: &ecdsa::Signature, msg: &[u8], pub_key: &ecdsa::Public) -> bool {
1067 ecdsa::Pair::verify(sig, msg, pub_key)
1068 }
1069
1070 fn ecdsa_verify_prehashed(
1074 sig: &ecdsa::Signature,
1075 msg: &[u8; 32],
1076 pub_key: &ecdsa::Public,
1077 ) -> bool {
1078 ecdsa::Pair::verify_prehashed(sig, msg, pub_key)
1079 }
1080
1081 #[version(1, register_only)]
1095 fn ecdsa_batch_verify(
1096 &mut self,
1097 sig: &ecdsa::Signature,
1098 msg: &[u8],
1099 pub_key: &ecdsa::Public,
1100 ) -> bool {
1101 let res = ecdsa_verify(sig, msg, pub_key);
1102
1103 if let Some(ext) = self.extension::<VerificationExtDeprecated>() {
1104 ext.0 &= res;
1105 }
1106
1107 res
1108 }
1109
1110 fn secp256k1_ecdsa_recover(
1119 sig: &[u8; 65],
1120 msg: &[u8; 32],
1121 ) -> Result<[u8; 64], EcdsaVerifyError> {
1122 let rid = libsecp256k1::RecoveryId::parse(
1123 if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8,
1124 )
1125 .map_err(|_| EcdsaVerifyError::BadV)?;
1126 let sig = libsecp256k1::Signature::parse_overflowing_slice(&sig[..64])
1127 .map_err(|_| EcdsaVerifyError::BadRS)?;
1128 let msg = libsecp256k1::Message::parse(msg);
1129 let pubkey =
1130 libsecp256k1::recover(&msg, &sig, &rid).map_err(|_| EcdsaVerifyError::BadSignature)?;
1131 let mut res = [0u8; 64];
1132 res.copy_from_slice(&pubkey.serialize()[1..65]);
1133 Ok(res)
1134 }
1135
1136 #[version(2)]
1144 fn secp256k1_ecdsa_recover(
1145 sig: &[u8; 65],
1146 msg: &[u8; 32],
1147 ) -> Result<[u8; 64], EcdsaVerifyError> {
1148 let rid = RecoveryId::from_i32(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as i32)
1149 .map_err(|_| EcdsaVerifyError::BadV)?;
1150 let sig = RecoverableSignature::from_compact(&sig[..64], rid)
1151 .map_err(|_| EcdsaVerifyError::BadRS)?;
1152 let msg = Message::from_digest_slice(msg).expect("Message is 32 bytes; qed");
1153 let pubkey = SECP256K1
1154 .recover_ecdsa(&msg, &sig)
1155 .map_err(|_| EcdsaVerifyError::BadSignature)?;
1156 let mut res = [0u8; 64];
1157 res.copy_from_slice(&pubkey.serialize_uncompressed()[1..]);
1158 Ok(res)
1159 }
1160
1161 fn secp256k1_ecdsa_recover_compressed(
1168 sig: &[u8; 65],
1169 msg: &[u8; 32],
1170 ) -> Result<[u8; 33], EcdsaVerifyError> {
1171 let rid = libsecp256k1::RecoveryId::parse(
1172 if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8,
1173 )
1174 .map_err(|_| EcdsaVerifyError::BadV)?;
1175 let sig = libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64])
1176 .map_err(|_| EcdsaVerifyError::BadRS)?;
1177 let msg = libsecp256k1::Message::parse(msg);
1178 let pubkey =
1179 libsecp256k1::recover(&msg, &sig, &rid).map_err(|_| EcdsaVerifyError::BadSignature)?;
1180 Ok(pubkey.serialize_compressed())
1181 }
1182
1183 #[version(2)]
1190 fn secp256k1_ecdsa_recover_compressed(
1191 sig: &[u8; 65],
1192 msg: &[u8; 32],
1193 ) -> Result<[u8; 33], EcdsaVerifyError> {
1194 let rid = RecoveryId::from_i32(if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as i32)
1195 .map_err(|_| EcdsaVerifyError::BadV)?;
1196 let sig = RecoverableSignature::from_compact(&sig[..64], rid)
1197 .map_err(|_| EcdsaVerifyError::BadRS)?;
1198 let msg = Message::from_digest_slice(msg).expect("Message is 32 bytes; qed");
1199 let pubkey = SECP256K1
1200 .recover_ecdsa(&msg, &sig)
1201 .map_err(|_| EcdsaVerifyError::BadSignature)?;
1202 Ok(pubkey.serialize())
1203 }
1204
1205 #[cfg(feature = "bls-experimental")]
1212 fn bls381_generate(&mut self, id: KeyTypeId, seed: Option<Vec<u8>>) -> bls381::Public {
1213 let seed = seed.as_ref().map(|s| std::str::from_utf8(s).expect("Seed is valid utf8!"));
1214 self.extension::<KeystoreExt>()
1215 .expect("No `keystore` associated for the current context!")
1216 .bls381_generate_new(id, seed)
1217 .expect("`bls381_generate` failed")
1218 }
1219
1220 #[cfg(feature = "bls-experimental")]
1227 fn ecdsa_bls381_generate(
1228 &mut self,
1229 id: KeyTypeId,
1230 seed: Option<Vec<u8>>,
1231 ) -> ecdsa_bls381::Public {
1232 let seed = seed.as_ref().map(|s| std::str::from_utf8(s).expect("Seed is valid utf8!"));
1233 self.extension::<KeystoreExt>()
1234 .expect("No `keystore` associated for the current context!")
1235 .ecdsa_bls381_generate_new(id, seed)
1236 .expect("`ecdsa_bls381_generate` failed")
1237 }
1238}
1239
1240#[runtime_interface]
1242pub trait Hashing {
1243 fn keccak_256(data: &[u8]) -> [u8; 32] {
1245 sp_crypto_hashing::keccak_256(data)
1246 }
1247
1248 fn keccak_512(data: &[u8]) -> [u8; 64] {
1250 sp_crypto_hashing::keccak_512(data)
1251 }
1252
1253 fn sha2_256(data: &[u8]) -> [u8; 32] {
1255 sp_crypto_hashing::sha2_256(data)
1256 }
1257
1258 fn blake2_128(data: &[u8]) -> [u8; 16] {
1260 sp_crypto_hashing::blake2_128(data)
1261 }
1262
1263 fn blake2_256(data: &[u8]) -> [u8; 32] {
1265 sp_crypto_hashing::blake2_256(data)
1266 }
1267
1268 fn twox_256(data: &[u8]) -> [u8; 32] {
1270 sp_crypto_hashing::twox_256(data)
1271 }
1272
1273 fn twox_128(data: &[u8]) -> [u8; 16] {
1275 sp_crypto_hashing::twox_128(data)
1276 }
1277
1278 fn twox_64(data: &[u8]) -> [u8; 8] {
1280 sp_crypto_hashing::twox_64(data)
1281 }
1282}
1283
1284#[runtime_interface]
1286pub trait TransactionIndex {
1287 fn index(&mut self, extrinsic: u32, size: u32, context_hash: [u8; 32]) {
1289 self.storage_index_transaction(extrinsic, &context_hash, size);
1290 }
1291
1292 fn renew(&mut self, extrinsic: u32, context_hash: [u8; 32]) {
1294 self.storage_renew_transaction_index(extrinsic, &context_hash);
1295 }
1296}
1297
1298#[runtime_interface]
1300pub trait OffchainIndex {
1301 fn set(&mut self, key: &[u8], value: &[u8]) {
1303 self.set_offchain_storage(key, Some(value));
1304 }
1305
1306 fn clear(&mut self, key: &[u8]) {
1308 self.set_offchain_storage(key, None);
1309 }
1310}
1311
1312#[cfg(feature = "std")]
1313sp_externalities::decl_extension! {
1314 struct VerificationExtDeprecated(bool);
1318}
1319
1320#[runtime_interface]
1324pub trait Offchain {
1325 fn is_validator(&mut self) -> bool {
1330 self.extension::<OffchainWorkerExt>()
1331 .expect("is_validator can be called only in the offchain worker context")
1332 .is_validator()
1333 }
1334
1335 fn submit_transaction(&mut self, data: Vec<u8>) -> Result<(), ()> {
1339 self.extension::<TransactionPoolExt>()
1340 .expect(
1341 "submit_transaction can be called only in the offchain call context with
1342 TransactionPool capabilities enabled",
1343 )
1344 .submit_transaction(data)
1345 }
1346
1347 fn network_state(&mut self) -> Result<OpaqueNetworkState, ()> {
1349 self.extension::<OffchainWorkerExt>()
1350 .expect("network_state can be called only in the offchain worker context")
1351 .network_state()
1352 }
1353
1354 fn timestamp(&mut self) -> Timestamp {
1356 self.extension::<OffchainWorkerExt>()
1357 .expect("timestamp can be called only in the offchain worker context")
1358 .timestamp()
1359 }
1360
1361 fn sleep_until(&mut self, deadline: Timestamp) {
1363 self.extension::<OffchainWorkerExt>()
1364 .expect("sleep_until can be called only in the offchain worker context")
1365 .sleep_until(deadline)
1366 }
1367
1368 fn random_seed(&mut self) -> [u8; 32] {
1373 self.extension::<OffchainWorkerExt>()
1374 .expect("random_seed can be called only in the offchain worker context")
1375 .random_seed()
1376 }
1377
1378 fn local_storage_set(&mut self, kind: StorageKind, key: &[u8], value: &[u8]) {
1383 self.extension::<OffchainDbExt>()
1384 .expect(
1385 "local_storage_set can be called only in the offchain call context with
1386 OffchainDb extension",
1387 )
1388 .local_storage_set(kind, key, value)
1389 }
1390
1391 fn local_storage_clear(&mut self, kind: StorageKind, key: &[u8]) {
1396 self.extension::<OffchainDbExt>()
1397 .expect(
1398 "local_storage_clear can be called only in the offchain call context with
1399 OffchainDb extension",
1400 )
1401 .local_storage_clear(kind, key)
1402 }
1403
1404 fn local_storage_compare_and_set(
1414 &mut self,
1415 kind: StorageKind,
1416 key: &[u8],
1417 old_value: Option<Vec<u8>>,
1418 new_value: &[u8],
1419 ) -> bool {
1420 self.extension::<OffchainDbExt>()
1421 .expect(
1422 "local_storage_compare_and_set can be called only in the offchain call context
1423 with OffchainDb extension",
1424 )
1425 .local_storage_compare_and_set(kind, key, old_value.as_deref(), new_value)
1426 }
1427
1428 fn local_storage_get(&mut self, kind: StorageKind, key: &[u8]) -> Option<Vec<u8>> {
1434 self.extension::<OffchainDbExt>()
1435 .expect(
1436 "local_storage_get can be called only in the offchain call context with
1437 OffchainDb extension",
1438 )
1439 .local_storage_get(kind, key)
1440 }
1441
1442 fn http_request_start(
1447 &mut self,
1448 method: &str,
1449 uri: &str,
1450 meta: &[u8],
1451 ) -> Result<HttpRequestId, ()> {
1452 self.extension::<OffchainWorkerExt>()
1453 .expect("http_request_start can be called only in the offchain worker context")
1454 .http_request_start(method, uri, meta)
1455 }
1456
1457 fn http_request_add_header(
1459 &mut self,
1460 request_id: HttpRequestId,
1461 name: &str,
1462 value: &str,
1463 ) -> Result<(), ()> {
1464 self.extension::<OffchainWorkerExt>()
1465 .expect("http_request_add_header can be called only in the offchain worker context")
1466 .http_request_add_header(request_id, name, value)
1467 }
1468
1469 fn http_request_write_body(
1476 &mut self,
1477 request_id: HttpRequestId,
1478 chunk: &[u8],
1479 deadline: Option<Timestamp>,
1480 ) -> Result<(), HttpError> {
1481 self.extension::<OffchainWorkerExt>()
1482 .expect("http_request_write_body can be called only in the offchain worker context")
1483 .http_request_write_body(request_id, chunk, deadline)
1484 }
1485
1486 fn http_response_wait(
1494 &mut self,
1495 ids: &[HttpRequestId],
1496 deadline: Option<Timestamp>,
1497 ) -> Vec<HttpRequestStatus> {
1498 self.extension::<OffchainWorkerExt>()
1499 .expect("http_response_wait can be called only in the offchain worker context")
1500 .http_response_wait(ids, deadline)
1501 }
1502
1503 fn http_response_headers(&mut self, request_id: HttpRequestId) -> Vec<(Vec<u8>, Vec<u8>)> {
1508 self.extension::<OffchainWorkerExt>()
1509 .expect("http_response_headers can be called only in the offchain worker context")
1510 .http_response_headers(request_id)
1511 }
1512
1513 fn http_response_read_body(
1522 &mut self,
1523 request_id: HttpRequestId,
1524 buffer: &mut [u8],
1525 deadline: Option<Timestamp>,
1526 ) -> Result<u32, HttpError> {
1527 self.extension::<OffchainWorkerExt>()
1528 .expect("http_response_read_body can be called only in the offchain worker context")
1529 .http_response_read_body(request_id, buffer, deadline)
1530 .map(|r| r as u32)
1531 }
1532
1533 fn set_authorized_nodes(&mut self, nodes: Vec<OpaquePeerId>, authorized_only: bool) {
1535 self.extension::<OffchainWorkerExt>()
1536 .expect("set_authorized_nodes can be called only in the offchain worker context")
1537 .set_authorized_nodes(nodes, authorized_only)
1538 }
1539}
1540
1541#[runtime_interface(wasm_only)]
1543pub trait Allocator {
1544 fn malloc(&mut self, size: u32) -> Pointer<u8> {
1546 self.allocate_memory(size).expect("Failed to allocate memory")
1547 }
1548
1549 fn free(&mut self, ptr: Pointer<u8>) {
1551 self.deallocate_memory(ptr).expect("Failed to deallocate memory")
1552 }
1553}
1554
1555#[runtime_interface(wasm_only)]
1558pub trait PanicHandler {
1559 #[trap_on_return]
1561 fn abort_on_panic(&mut self, message: &str) {
1562 self.register_panic_error_message(message);
1563 }
1564}
1565
1566#[runtime_interface]
1568pub trait Logging {
1569 fn log(level: LogLevel, target: &str, message: &[u8]) {
1576 if let Ok(message) = std::str::from_utf8(message) {
1577 log::log!(target: target, log::Level::from(level), "{}", message)
1578 }
1579 }
1580
1581 fn max_level() -> LogLevelFilter {
1583 log::max_level().into()
1584 }
1585}
1586
1587#[derive(Encode, Decode)]
1588pub struct Crossing<T: Encode + Decode>(T);
1591
1592impl<T: Encode + Decode> PassBy for Crossing<T> {
1593 type PassBy = sp_runtime_interface::pass_by::Codec<Self>;
1594}
1595
1596impl<T: Encode + Decode> Crossing<T> {
1597 pub fn into_inner(self) -> T {
1599 self.0
1600 }
1601}
1602
1603impl<T> core::default::Default for Crossing<T>
1605where
1606 T: core::default::Default + Encode + Decode,
1607{
1608 fn default() -> Self {
1609 Self(Default::default())
1610 }
1611}
1612
1613#[runtime_interface(wasm_only, no_tracing)]
1616pub trait WasmTracing {
1617 fn enabled(&mut self, metadata: Crossing<sp_tracing::WasmMetadata>) -> bool {
1627 let metadata: &tracing_core::metadata::Metadata<'static> = (&metadata.into_inner()).into();
1628 tracing::dispatcher::get_default(|d| d.enabled(metadata))
1629 }
1630
1631 fn enter_span(&mut self, span: Crossing<sp_tracing::WasmEntryAttributes>) -> u64 {
1638 let span: tracing::Span = span.into_inner().into();
1639 match span.id() {
1640 Some(id) => tracing::dispatcher::get_default(|d| {
1641 let final_id = d.clone_span(&id);
1644 d.enter(&final_id);
1645 final_id.into_u64()
1646 }),
1647 _ => 0,
1648 }
1649 }
1650
1651 fn event(&mut self, event: Crossing<sp_tracing::WasmEntryAttributes>) {
1653 event.into_inner().emit();
1654 }
1655
1656 fn exit(&mut self, span: u64) {
1659 tracing::dispatcher::get_default(|d| {
1660 let id = tracing_core::span::Id::from_u64(span);
1661 d.exit(&id);
1662 });
1663 }
1664}
1665
1666#[cfg(all(not(feature = "std"), feature = "with-tracing"))]
1667mod tracing_setup {
1668 use super::{wasm_tracing, Crossing};
1669 use core::sync::atomic::{AtomicBool, Ordering};
1670 use tracing_core::{
1671 dispatcher::{set_global_default, Dispatch},
1672 span::{Attributes, Id, Record},
1673 Event, Metadata,
1674 };
1675
1676 static TRACING_SET: AtomicBool = AtomicBool::new(false);
1677
1678 struct PassingTracingSubscriber;
1681
1682 impl tracing_core::Subscriber for PassingTracingSubscriber {
1683 fn enabled(&self, metadata: &Metadata<'_>) -> bool {
1684 wasm_tracing::enabled(Crossing(metadata.into()))
1685 }
1686 fn new_span(&self, attrs: &Attributes<'_>) -> Id {
1687 Id::from_u64(wasm_tracing::enter_span(Crossing(attrs.into())))
1688 }
1689 fn enter(&self, _: &Id) {
1690 }
1692 fn record(&self, _: &Id, _: &Record<'_>) {
1695 unimplemented! {} }
1697 fn record_follows_from(&self, _: &Id, _: &Id) {
1700 unimplemented! {} }
1702 fn event(&self, event: &Event<'_>) {
1703 wasm_tracing::event(Crossing(event.into()))
1704 }
1705 fn exit(&self, span: &Id) {
1706 wasm_tracing::exit(span.into_u64())
1707 }
1708 }
1709
1710 pub fn init_tracing() {
1714 if TRACING_SET.load(Ordering::Relaxed) == false {
1715 set_global_default(Dispatch::new(PassingTracingSubscriber {}))
1716 .expect("We only ever call this once");
1717 TRACING_SET.store(true, Ordering::Relaxed);
1718 }
1719 }
1720}
1721
1722#[cfg(not(all(not(feature = "std"), feature = "with-tracing")))]
1723mod tracing_setup {
1724 pub fn init_tracing() {}
1727}
1728
1729pub use tracing_setup::init_tracing;
1730
1731pub fn unreachable() -> ! {
1736 #[cfg(target_family = "wasm")]
1737 {
1738 core::arch::wasm32::unreachable();
1739 }
1740
1741 #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
1742 unsafe {
1743 core::arch::asm!("unimp", options(noreturn));
1744 }
1745
1746 #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64", target_family = "wasm")))]
1747 unreachable!();
1748}
1749
1750#[cfg(all(not(feature = "disable_panic_handler"), substrate_runtime))]
1752#[panic_handler]
1753pub fn panic(info: &core::panic::PanicInfo) -> ! {
1754 let message = alloc::format!("{}", info);
1755 #[cfg(feature = "improved_panic_error_reporting")]
1756 {
1757 panic_handler::abort_on_panic(&message);
1758 }
1759 #[cfg(not(feature = "improved_panic_error_reporting"))]
1760 {
1761 logging::log(LogLevel::Error, "runtime", message.as_bytes());
1762 unreachable();
1763 }
1764}
1765
1766#[cfg(all(not(feature = "disable_oom"), enable_alloc_error_handler))]
1768#[alloc_error_handler]
1769pub fn oom(_: core::alloc::Layout) -> ! {
1770 #[cfg(feature = "improved_panic_error_reporting")]
1771 {
1772 panic_handler::abort_on_panic("Runtime memory exhausted.");
1773 }
1774 #[cfg(not(feature = "improved_panic_error_reporting"))]
1775 {
1776 logging::log(LogLevel::Error, "runtime", b"Runtime memory exhausted. Aborting");
1777 unreachable();
1778 }
1779}
1780
1781#[cfg(feature = "std")]
1783pub type TestExternalities = sp_state_machine::TestExternalities<sp_core::Blake2Hasher>;
1784
1785#[docify::export]
1789#[cfg(feature = "std")]
1790pub type SubstrateHostFunctions = (
1791 storage::HostFunctions,
1792 default_child_storage::HostFunctions,
1793 misc::HostFunctions,
1794 wasm_tracing::HostFunctions,
1795 offchain::HostFunctions,
1796 crypto::HostFunctions,
1797 hashing::HostFunctions,
1798 allocator::HostFunctions,
1799 panic_handler::HostFunctions,
1800 logging::HostFunctions,
1801 crate::trie::HostFunctions,
1802 offchain_index::HostFunctions,
1803 transaction_index::HostFunctions,
1804);
1805
1806#[cfg(test)]
1807mod tests {
1808 use super::*;
1809 use sp_core::{crypto::UncheckedInto, map, storage::Storage};
1810 use sp_state_machine::BasicExternalities;
1811
1812 #[test]
1813 fn storage_works() {
1814 let mut t = BasicExternalities::default();
1815 t.execute_with(|| {
1816 assert_eq!(storage::get(b"hello"), None);
1817 storage::set(b"hello", b"world");
1818 assert_eq!(storage::get(b"hello"), Some(b"world".to_vec().into()));
1819 assert_eq!(storage::get(b"foo"), None);
1820 storage::set(b"foo", &[1, 2, 3][..]);
1821 });
1822
1823 t = BasicExternalities::new(Storage {
1824 top: map![b"foo".to_vec() => b"bar".to_vec()],
1825 children_default: map![],
1826 });
1827
1828 t.execute_with(|| {
1829 assert_eq!(storage::get(b"hello"), None);
1830 assert_eq!(storage::get(b"foo"), Some(b"bar".to_vec().into()));
1831 });
1832
1833 let value = vec![7u8; 35];
1834 let storage =
1835 Storage { top: map![b"foo00".to_vec() => value.clone()], children_default: map![] };
1836 t = BasicExternalities::new(storage);
1837
1838 t.execute_with(|| {
1839 assert_eq!(storage::get(b"hello"), None);
1840 assert_eq!(storage::get(b"foo00"), Some(value.clone().into()));
1841 });
1842 }
1843
1844 #[test]
1845 fn read_storage_works() {
1846 let value = b"\x0b\0\0\0Hello world".to_vec();
1847 let mut t = BasicExternalities::new(Storage {
1848 top: map![b":test".to_vec() => value.clone()],
1849 children_default: map![],
1850 });
1851
1852 t.execute_with(|| {
1853 let mut v = [0u8; 4];
1854 assert_eq!(storage::read(b":test", &mut v[..], 0).unwrap(), value.len() as u32);
1855 assert_eq!(v, [11u8, 0, 0, 0]);
1856 let mut w = [0u8; 11];
1857 assert_eq!(storage::read(b":test", &mut w[..], 4).unwrap(), value.len() as u32 - 4);
1858 assert_eq!(&w, b"Hello world");
1859 });
1860 }
1861
1862 #[test]
1863 fn clear_prefix_works() {
1864 let mut t = BasicExternalities::new(Storage {
1865 top: map![
1866 b":a".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1867 b":abcd".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1868 b":abc".to_vec() => b"\x0b\0\0\0Hello world".to_vec(),
1869 b":abdd".to_vec() => b"\x0b\0\0\0Hello world".to_vec()
1870 ],
1871 children_default: map![],
1872 });
1873
1874 t.execute_with(|| {
1875 assert!(matches!(
1881 storage::clear_prefix(b":abc", None),
1882 KillStorageResult::AllRemoved(2),
1883 ));
1884
1885 assert!(storage::get(b":a").is_some());
1886 assert!(storage::get(b":abdd").is_some());
1887 assert!(storage::get(b":abcd").is_none());
1888 assert!(storage::get(b":abc").is_none());
1889
1890 assert!(matches!(
1896 storage::clear_prefix(b":abc", None),
1897 KillStorageResult::AllRemoved(0),
1898 ));
1899 });
1900 }
1901
1902 fn zero_ed_pub() -> ed25519::Public {
1903 [0u8; 32].unchecked_into()
1904 }
1905
1906 fn zero_ed_sig() -> ed25519::Signature {
1907 ed25519::Signature::from_raw([0u8; 64])
1908 }
1909
1910 #[test]
1911 fn use_dalek_ext_works() {
1912 let mut ext = BasicExternalities::default();
1913 ext.register_extension(UseDalekExt::default());
1914
1915 ext.execute_with(|| {
1917 assert!(!crypto::ed25519_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()));
1918 });
1919
1920 BasicExternalities::default().execute_with(|| {
1922 assert!(crypto::ed25519_verify(&zero_ed_sig(), &Vec::new(), &zero_ed_pub()));
1923 })
1924 }
1925
1926 #[test]
1927 fn dalek_should_not_panic_on_invalid_signature() {
1928 let mut ext = BasicExternalities::default();
1929 ext.register_extension(UseDalekExt::default());
1930
1931 ext.execute_with(|| {
1932 let mut bytes = [0u8; 64];
1933 bytes[63] = 0b1110_0000;
1935
1936 assert!(!crypto::ed25519_verify(
1937 &ed25519::Signature::from_raw(bytes),
1938 &Vec::new(),
1939 &zero_ed_pub()
1940 ));
1941 });
1942 }
1943}