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