referrerpolicy=no-referrer-when-downgrade

sp_core/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Shareable Substrate types.
19
20#![warn(missing_docs)]
21#![cfg_attr(not(feature = "std"), no_std)]
22
23extern crate alloc;
24
25/// Initialize a key-value collection from array.
26///
27/// Creates a vector of given pairs and calls `collect` on the iterator from it.
28/// Can be used to create a `HashMap`.
29#[macro_export]
30macro_rules! map {
31	($( $name:expr => $value:expr ),* $(,)? ) => (
32		vec![ $( ( $name, $value ) ),* ].into_iter().collect()
33	);
34}
35
36use alloc::vec::Vec;
37#[doc(hidden)]
38pub use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
39use core::ops::Deref;
40use scale_info::TypeInfo;
41#[cfg(feature = "serde")]
42pub use serde;
43#[cfg(feature = "serde")]
44use serde::{Deserialize, Serialize};
45
46pub use sp_debug_derive::RuntimeDebug;
47
48#[cfg(feature = "serde")]
49pub use impl_serde::serialize as bytes;
50
51#[deprecated(
52	since = "27.0.0",
53	note = "`sp-crypto-hashing` re-exports will be removed after June 2024. Use `sp-crypto-hashing` instead."
54)]
55pub use sp_crypto_hashing::{self as hashing, *};
56
57pub mod const_hex2array;
58pub mod crypto;
59pub mod hexdisplay;
60pub use paste;
61mod address_uri;
62pub mod defer;
63pub mod hash;
64#[cfg(not(substrate_runtime))]
65mod hasher;
66pub mod offchain;
67pub mod proof_of_possession;
68pub mod testing;
69#[cfg(not(substrate_runtime))]
70pub mod traits;
71pub mod uint;
72
73#[cfg(feature = "bandersnatch-experimental")]
74pub mod bandersnatch;
75#[cfg(feature = "bls-experimental")]
76pub mod bls;
77pub mod crypto_bytes;
78pub mod ecdsa;
79pub mod ed25519;
80pub mod paired_crypto;
81pub mod sr25519;
82
83#[cfg(feature = "bls-experimental")]
84pub use bls::{bls377, bls381};
85#[cfg(feature = "bls-experimental")]
86pub use paired_crypto::{ecdsa_bls377, ecdsa_bls381};
87
88pub use self::{
89	hash::{convert_hash, H160, H256, H512},
90	uint::{U256, U512},
91};
92pub use crypto::{ByteArray, DeriveJunction, Pair, Public};
93
94#[cfg(not(substrate_runtime))]
95pub use self::hasher::blake2::Blake2Hasher;
96#[cfg(not(substrate_runtime))]
97pub use self::hasher::keccak::KeccakHasher;
98pub use hash_db::Hasher;
99
100pub use bounded_collections as bounded;
101#[cfg(feature = "std")]
102pub use bounded_collections::{bounded_btree_map, bounded_vec};
103pub use bounded_collections::{
104	parameter_types, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstInt,
105	ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, ConstUint, Get, GetDefault, TryCollect,
106	TypedGet,
107};
108pub use sp_storage as storage;
109
110#[doc(hidden)]
111pub use sp_std;
112
113/// Hex-serialized shim for `Vec<u8>`.
114#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
115#[cfg_attr(feature = "serde", derive(Serialize, Deserialize, Hash, PartialOrd, Ord))]
116pub struct Bytes(#[cfg_attr(feature = "serde", serde(with = "bytes"))] pub Vec<u8>);
117
118impl From<Vec<u8>> for Bytes {
119	fn from(s: Vec<u8>) -> Self {
120		Bytes(s)
121	}
122}
123
124impl From<OpaqueMetadata> for Bytes {
125	fn from(s: OpaqueMetadata) -> Self {
126		Bytes(s.0)
127	}
128}
129
130impl Deref for Bytes {
131	type Target = [u8];
132	fn deref(&self) -> &[u8] {
133		&self.0[..]
134	}
135}
136
137impl codec::WrapperTypeEncode for Bytes {}
138
139impl codec::WrapperTypeDecode for Bytes {
140	type Wrapped = Vec<u8>;
141}
142
143#[cfg(feature = "std")]
144impl alloc::str::FromStr for Bytes {
145	type Err = bytes::FromHexError;
146
147	fn from_str(s: &str) -> Result<Self, Self::Err> {
148		bytes::from_hex(s).map(Bytes)
149	}
150}
151
152/// Stores the encoded `RuntimeMetadata` for the native side as opaque type.
153#[derive(Encode, Decode, PartialEq, TypeInfo)]
154pub struct OpaqueMetadata(Vec<u8>);
155
156impl OpaqueMetadata {
157	/// Creates a new instance with the given metadata blob.
158	pub fn new(metadata: Vec<u8>) -> Self {
159		OpaqueMetadata(metadata)
160	}
161}
162
163impl Deref for OpaqueMetadata {
164	type Target = Vec<u8>;
165
166	fn deref(&self) -> &Self::Target {
167		&self.0
168	}
169}
170
171/// Simple blob to hold a `PeerId` without committing to its format.
172#[derive(
173	Default,
174	Clone,
175	Eq,
176	PartialEq,
177	Ord,
178	PartialOrd,
179	Encode,
180	Decode,
181	DecodeWithMemTracking,
182	RuntimeDebug,
183	TypeInfo,
184)]
185#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
186pub struct OpaquePeerId(pub Vec<u8>);
187
188impl OpaquePeerId {
189	/// Create new `OpaquePeerId`
190	pub fn new(vec: Vec<u8>) -> Self {
191		OpaquePeerId(vec)
192	}
193}
194
195/// Provide a simple 4 byte identifier for a type.
196pub trait TypeId {
197	/// Simple 4 byte identifier.
198	const TYPE_ID: [u8; 4];
199}
200
201/// A log level matching the one from `log` crate.
202///
203/// Used internally by `sp_io::logging::log` method.
204#[derive(Copy, Clone)]
205pub enum RuntimeInterfaceLogLevel {
206	/// `Error` log level.
207	Error = 0_isize,
208	/// `Warn` log level.
209	Warn = 1_isize,
210	/// `Info` log level.
211	Info = 2_isize,
212	/// `Debug` log level.
213	Debug = 3_isize,
214	/// `Trace` log level.
215	Trace = 4_isize,
216}
217
218impl TryFrom<u8> for RuntimeInterfaceLogLevel {
219	type Error = ();
220	fn try_from(value: u8) -> Result<Self, ()> {
221		match value {
222			0 => Ok(Self::Error),
223			1 => Ok(Self::Warn),
224			2 => Ok(Self::Info),
225			3 => Ok(Self::Debug),
226			4 => Ok(Self::Trace),
227			_ => Err(()),
228		}
229	}
230}
231
232impl From<RuntimeInterfaceLogLevel> for u8 {
233	fn from(value: RuntimeInterfaceLogLevel) -> Self {
234		value as Self
235	}
236}
237
238impl From<u32> for RuntimeInterfaceLogLevel {
239	fn from(val: u32) -> Self {
240		match val {
241			x if x == RuntimeInterfaceLogLevel::Warn as u32 => RuntimeInterfaceLogLevel::Warn,
242			x if x == RuntimeInterfaceLogLevel::Info as u32 => RuntimeInterfaceLogLevel::Info,
243			x if x == RuntimeInterfaceLogLevel::Debug as u32 => RuntimeInterfaceLogLevel::Debug,
244			x if x == RuntimeInterfaceLogLevel::Trace as u32 => RuntimeInterfaceLogLevel::Trace,
245			_ => RuntimeInterfaceLogLevel::Error,
246		}
247	}
248}
249
250impl From<log::Level> for RuntimeInterfaceLogLevel {
251	fn from(l: log::Level) -> Self {
252		use log::Level::*;
253		match l {
254			Error => Self::Error,
255			Warn => Self::Warn,
256			Info => Self::Info,
257			Debug => Self::Debug,
258			Trace => Self::Trace,
259		}
260	}
261}
262
263impl From<RuntimeInterfaceLogLevel> for log::Level {
264	fn from(l: RuntimeInterfaceLogLevel) -> Self {
265		use self::RuntimeInterfaceLogLevel::*;
266		match l {
267			Error => Self::Error,
268			Warn => Self::Warn,
269			Info => Self::Info,
270			Debug => Self::Debug,
271			Trace => Self::Trace,
272		}
273	}
274}
275
276/// Log level filter that expresses which log levels should be filtered.
277///
278/// This enum matches the [`log::LevelFilter`] enum.
279#[derive(Encode, Decode, Copy, Clone)]
280pub enum LogLevelFilter {
281	/// `Off` log level filter.
282	Off = 0_isize,
283	/// `Error` log level filter.
284	Error = 1_isize,
285	/// `Warn` log level filter.
286	Warn = 2_isize,
287	/// `Info` log level filter.
288	Info = 3_isize,
289	/// `Debug` log level filter.
290	Debug = 4_isize,
291	/// `Trace` log level filter.
292	Trace = 5_isize,
293}
294
295impl TryFrom<u8> for LogLevelFilter {
296	type Error = ();
297	fn try_from(value: u8) -> Result<Self, ()> {
298		match value {
299			0 => Ok(Self::Off),
300			1 => Ok(Self::Error),
301			2 => Ok(Self::Warn),
302			3 => Ok(Self::Info),
303			4 => Ok(Self::Debug),
304			5 => Ok(Self::Trace),
305			_ => Err(()),
306		}
307	}
308}
309
310impl From<LogLevelFilter> for u8 {
311	fn from(value: LogLevelFilter) -> Self {
312		value as Self
313	}
314}
315
316impl From<LogLevelFilter> for log::LevelFilter {
317	fn from(l: LogLevelFilter) -> Self {
318		use self::LogLevelFilter::*;
319		match l {
320			Off => Self::Off,
321			Error => Self::Error,
322			Warn => Self::Warn,
323			Info => Self::Info,
324			Debug => Self::Debug,
325			Trace => Self::Trace,
326		}
327	}
328}
329
330impl From<log::LevelFilter> for LogLevelFilter {
331	fn from(l: log::LevelFilter) -> Self {
332		use log::LevelFilter::*;
333		match l {
334			Off => Self::Off,
335			Error => Self::Error,
336			Warn => Self::Warn,
337			Info => Self::Info,
338			Debug => Self::Debug,
339			Trace => Self::Trace,
340		}
341	}
342}
343
344/// Encodes the given value into a buffer and returns the pointer and the length as a single `u64`.
345///
346/// When Substrate calls into Wasm it expects a fixed signature for functions exported
347/// from the Wasm blob. The return value of this signature is always a `u64`.
348/// This `u64` stores the pointer to the encoded return value and the length of this encoded value.
349/// The low `32bits` are reserved for the pointer, followed by `32bit` for the length.
350#[cfg(not(feature = "std"))]
351pub fn to_substrate_wasm_fn_return_value(value: &impl Encode) -> u64 {
352	let encoded = value.encode();
353
354	let ptr = encoded.as_ptr() as u64;
355	let length = encoded.len() as u64;
356	let res = ptr | (length << 32);
357
358	// Leak the output vector to avoid it being freed.
359	// This is fine in a WASM context since the heap
360	// will be discarded after the call.
361	core::mem::forget(encoded);
362
363	res
364}
365
366/// The void type - it cannot exist.
367// Oh rust, you crack me up...
368#[derive(
369	Clone,
370	Decode,
371	DecodeWithMemTracking,
372	Encode,
373	Eq,
374	PartialEq,
375	RuntimeDebug,
376	TypeInfo,
377	MaxEncodedLen,
378)]
379pub enum Void {}
380
381/// Macro for creating `Maybe*` marker traits.
382///
383/// Such a maybe-marker trait requires the given bound when `feature = std` and doesn't require
384/// the bound on `no_std`. This is useful for situations where you require that a type implements
385/// a certain trait with `feature = std`, but not on `no_std`.
386///
387/// # Example
388///
389/// ```
390/// sp_core::impl_maybe_marker! {
391///     /// A marker for a type that implements `Debug` when `feature = std`.
392///     trait MaybeDebug: std::fmt::Debug;
393///     /// A marker for a type that implements `Debug + Display` when `feature = std`.
394///     trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display;
395/// }
396/// ```
397#[macro_export]
398macro_rules! impl_maybe_marker {
399	(
400		$(
401			$(#[$doc:meta] )+
402			trait $trait_name:ident: $( $trait_bound:path ),+;
403		)+
404	) => {
405		$(
406			$(#[$doc])+
407			#[cfg(feature = "std")]
408			pub trait $trait_name: $( $trait_bound + )+ {}
409			#[cfg(feature = "std")]
410			impl<T: $( $trait_bound + )+> $trait_name for T {}
411
412			$(#[$doc])+
413			#[cfg(not(feature = "std"))]
414			pub trait $trait_name {}
415			#[cfg(not(feature = "std"))]
416			impl<T> $trait_name for T {}
417		)+
418	}
419}
420
421/// Macro for creating `Maybe*` marker traits.
422///
423/// Such a maybe-marker trait requires the given bound when either `feature = std` or `feature =
424/// serde` is activated.
425///
426/// # Example
427///
428/// ```
429/// sp_core::impl_maybe_marker_std_or_serde! {
430///     /// A marker for a type that implements `Debug` when `feature = serde` or `feature = std`.
431///     trait MaybeDebug: std::fmt::Debug;
432///     /// A marker for a type that implements `Debug + Display` when `feature = serde` or `feature = std`.
433///     trait MaybeDebugDisplay: std::fmt::Debug, std::fmt::Display;
434/// }
435/// ```
436#[macro_export]
437macro_rules! impl_maybe_marker_std_or_serde {
438	(
439		$(
440			$(#[$doc:meta] )+
441			trait $trait_name:ident: $( $trait_bound:path ),+;
442		)+
443	) => {
444		$(
445			$(#[$doc])+
446			#[cfg(any(feature = "serde", feature = "std"))]
447			pub trait $trait_name: $( $trait_bound + )+ {}
448			#[cfg(any(feature = "serde", feature = "std"))]
449			impl<T: $( $trait_bound + )+> $trait_name for T {}
450
451			$(#[$doc])+
452			#[cfg(not(any(feature = "serde", feature = "std")))]
453			pub trait $trait_name {}
454			#[cfg(not(any(feature = "serde", feature = "std")))]
455			impl<T> $trait_name for T {}
456		)+
457	}
458}
459
460/// The maximum number of bytes that can be allocated at one time.
461// The maximum possible allocation size was chosen rather arbitrary, 32 MiB should be enough for
462// everybody.
463pub const MAX_POSSIBLE_ALLOCATION: u32 = 33554432; // 2^25 bytes, 32 MiB
464
465/// Generates a macro for checking if a certain feature is enabled.
466///
467/// These feature checking macros can be used to conditionally enable/disable code in a dependent
468/// crate based on a feature in the crate where the macro is called.
469///
470/// # Example
471///```
472/// sp_core::generate_feature_enabled_macro!(check_std_is_enabled, feature = "std", $);
473/// sp_core::generate_feature_enabled_macro!(check_std_or_serde_is_enabled, any(feature = "std", feature = "serde"), $);
474///
475/// // All the code passed to the macro will then conditionally compiled based on the features
476/// // activated for the crate where the macro was generated.
477/// check_std_is_enabled! {
478///     struct StdEnabled;
479/// }
480///```
481#[macro_export]
482// We need to skip formatting this macro because of this bug:
483// https://github.com/rust-lang/rustfmt/issues/5283
484#[rustfmt::skip]
485macro_rules! generate_feature_enabled_macro {
486	( $macro_name:ident, $feature_name:meta, $d:tt ) => {
487		$crate::paste::paste!{
488			///
489			#[cfg($feature_name)]
490			#[macro_export]
491			macro_rules! [<_ $macro_name>] {
492				( $d ( $d input:tt )* ) => {
493					$d ( $d input )*
494				}
495			}
496
497			///
498 			#[cfg(not($feature_name))]
499			#[macro_export]
500			macro_rules! [<_ $macro_name>] {
501				( $d ( $d input:tt )* ) => {};
502			}
503
504			/// Enable/disable the given code depending on
505			#[doc = concat!("`", stringify!($feature_name), "`")]
506			/// being enabled for the crate or not.
507			///
508			/// # Example
509			///
510			/// ```nocompile
511			/// // Will add the code depending on the feature being enabled or not.
512			#[doc = concat!(stringify!($macro_name), "!( println!(\"Hello\") )")]
513			/// ```
514			// https://github.com/rust-lang/rust/pull/52234
515 			pub use [<_ $macro_name>] as $macro_name;
516		}
517	};
518}
519
520#[cfg(test)]
521mod tests {
522	use super::*;
523
524	generate_feature_enabled_macro!(if_test, test, $);
525	generate_feature_enabled_macro!(if_not_test, not(test), $);
526
527	#[test]
528	#[should_panic]
529	fn generate_feature_enabled_macro_panics() {
530		if_test!(panic!("This should panic"));
531	}
532
533	#[test]
534	fn generate_feature_enabled_macro_works() {
535		if_not_test!(panic!("This should not panic"));
536	}
537}