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