referrerpolicy=no-referrer-when-downgrade

sp_runtime/
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//! # Substrate Runtime Primitives.
19//!
20//! This crate, among other things, contains a large library of types and utilities that are used in
21//! the Substrate runtime, but are not particularly `FRAME`-oriented.
22//!
23//! ## Block, Header and Extrinsics
24//!
25//! Most notable, this crate contains some of the types and trait that enable important
26//! communication between the client and the runtime. This includes:
27//!
28//! - A set of traits to declare what any block/header/extrinsic type should provide.
29//! 	- [`traits::Block`], [`traits::Header`], [`traits::ExtrinsicLike`]
30//! - A set of types that implement these traits, whilst still providing a high degree of
31//!   configurability via generics.
32//! 	- [`generic::Block`], [`generic::Header`], [`generic::UncheckedExtrinsic`] and
33//!    [`generic::CheckedExtrinsic`]
34//!
35//! ## Runtime API Types
36//!
37//! This crate also contains some types that are often used in conjuncture with Runtime APIs. Most
38//! notable:
39//!
40//! - [`ApplyExtrinsicResult`], and [`DispatchOutcome`], which dictate how the client and runtime
41//!   communicate about the success or failure of an extrinsic.
42//! - [`transaction_validity`], which dictates how the client and runtime communicate about the
43//!  validity of an extrinsic while still in the transaction-queue.
44
45#![warn(missing_docs)]
46#![cfg_attr(not(feature = "std"), no_std)]
47
48#[doc(hidden)]
49extern crate alloc;
50
51#[doc(hidden)]
52pub use alloc::vec::Vec;
53#[doc(hidden)]
54pub use codec;
55#[doc(hidden)]
56pub use scale_info;
57#[cfg(feature = "serde")]
58#[doc(hidden)]
59pub use serde;
60#[doc(hidden)]
61pub use sp_std;
62
63#[doc(hidden)]
64pub use paste;
65#[doc(hidden)]
66pub use sp_arithmetic::traits::Saturating;
67
68#[doc(hidden)]
69pub use sp_application_crypto as app_crypto;
70
71pub use sp_core::storage::StateVersion;
72#[cfg(feature = "std")]
73pub use sp_core::storage::{Storage, StorageChild};
74
75use sp_core::{
76	crypto::{self, ByteArray, FromEntropy},
77	ecdsa, ed25519,
78	hash::{H256, H512},
79	sr25519,
80};
81
82use alloc::vec;
83use codec::{Decode, DecodeWithMemTracking, Encode, MaxEncodedLen};
84use scale_info::TypeInfo;
85
86pub mod curve;
87pub mod generic;
88pub mod legacy;
89mod multiaddress;
90pub mod offchain;
91pub mod proving_trie;
92pub mod runtime_logger;
93#[cfg(feature = "std")]
94pub mod testing;
95pub mod traits;
96pub mod transaction_validity;
97pub mod type_with_default;
98
99// Re-export Multiaddress
100pub use multiaddress::MultiAddress;
101
102use proving_trie::TrieError;
103
104/// Re-export these since they're only "kind of" generic.
105pub use generic::{Digest, DigestItem};
106
107pub use sp_application_crypto::{BoundToRuntimeAppPublic, RuntimeAppPublic};
108/// Re-export this since it's part of the API of this crate.
109pub use sp_core::{
110	bounded::{BoundedBTreeMap, BoundedBTreeSet, BoundedSlice, BoundedVec, WeakBoundedVec},
111	crypto::{key_types, AccountId32, CryptoType, CryptoTypeId, KeyTypeId},
112	TypeId,
113};
114/// Re-export bounded_vec and bounded_btree_map macros only when std is enabled.
115#[cfg(feature = "std")]
116pub use sp_core::{bounded_btree_map, bounded_vec};
117
118/// Re-export `Debug`, to avoid dependency clutter.
119pub use core::fmt::Debug;
120
121/// Re-export big_uint stuff.
122pub use sp_arithmetic::biguint;
123/// Re-export 128 bit helpers.
124pub use sp_arithmetic::helpers_128bit;
125/// Re-export top-level arithmetic stuff.
126pub use sp_arithmetic::{
127	traits::SaturatedConversion, ArithmeticError, FixedI128, FixedI64, FixedPointNumber,
128	FixedPointOperand, FixedU128, FixedU64, InnerOf, PerThing, PerU16, Perbill, Percent, Permill,
129	Perquintill, Rational128, Rounding, UpperOf,
130};
131/// Re-export this since it's part of the API of this crate.
132pub use sp_weights::Weight;
133
134pub use either::Either;
135
136/// The number of bytes of the module-specific `error` field defined in [`ModuleError`].
137/// In FRAME, this is the maximum encoded size of a pallet error type.
138pub const MAX_MODULE_ERROR_ENCODED_SIZE: usize = 4;
139
140/// An abstraction over justification for a block's validity under a consensus algorithm.
141///
142/// Essentially a finality proof. The exact formulation will vary between consensus
143/// algorithms. In the case where there are multiple valid proofs, inclusion within
144/// the block itself would allow swapping justifications to change the block's hash
145/// (and thus fork the chain). Sending a `Justification` alongside a block instead
146/// bypasses this problem.
147///
148/// Each justification is provided as an encoded blob, and is tagged with an ID
149/// to identify the consensus engine that generated the proof (we might have
150/// multiple justifications from different engines for the same block).
151pub type Justification = (ConsensusEngineId, EncodedJustification);
152
153/// The encoded justification specific to a consensus engine.
154pub type EncodedJustification = Vec<u8>;
155
156/// Collection of justifications for a given block, multiple justifications may
157/// be provided by different consensus engines for the same block.
158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
159#[derive(Default, Debug, Clone, PartialEq, Eq, Encode, Decode)]
160pub struct Justifications(Vec<Justification>);
161
162impl Justifications {
163	/// Create a new `Justifications` instance with the given justifications.
164	pub fn new(justifications: Vec<Justification>) -> Self {
165		Self(justifications)
166	}
167
168	/// Return an iterator over the justifications.
169	pub fn iter(&self) -> impl Iterator<Item = &Justification> {
170		self.0.iter()
171	}
172
173	/// Append a justification. Returns false if a justification with the same
174	/// `ConsensusEngineId` already exists, in which case the justification is
175	/// not inserted.
176	pub fn append(&mut self, justification: Justification) -> bool {
177		if self.get(justification.0).is_some() {
178			return false;
179		}
180		self.0.push(justification);
181		true
182	}
183
184	/// Return the encoded justification for the given consensus engine, if it
185	/// exists.
186	pub fn get(&self, engine_id: ConsensusEngineId) -> Option<&EncodedJustification> {
187		self.iter().find(|j| j.0 == engine_id).map(|j| &j.1)
188	}
189
190	/// Remove the encoded justification for the given consensus engine, if it exists.
191	pub fn remove(&mut self, engine_id: ConsensusEngineId) {
192		self.0.retain(|j| j.0 != engine_id)
193	}
194
195	/// Return a copy of the encoded justification for the given consensus
196	/// engine, if it exists.
197	pub fn into_justification(self, engine_id: ConsensusEngineId) -> Option<EncodedJustification> {
198		self.into_iter().find(|j| j.0 == engine_id).map(|j| j.1)
199	}
200}
201
202impl IntoIterator for Justifications {
203	type Item = Justification;
204	type IntoIter = alloc::vec::IntoIter<Self::Item>;
205
206	fn into_iter(self) -> Self::IntoIter {
207		self.0.into_iter()
208	}
209}
210
211impl From<Justification> for Justifications {
212	fn from(justification: Justification) -> Self {
213		Self(vec![justification])
214	}
215}
216
217use traits::{Lazy, Verify};
218
219use crate::traits::{IdentifyAccount, LazyExtrinsic};
220#[cfg(feature = "serde")]
221pub use serde::{de::DeserializeOwned, Deserialize, Serialize};
222
223/// Complex storage builder stuff.
224#[cfg(feature = "std")]
225pub trait BuildStorage {
226	/// Build the storage out of this builder.
227	fn build_storage(&self) -> Result<sp_core::storage::Storage, String> {
228		let mut storage = Default::default();
229		self.assimilate_storage(&mut storage)?;
230		Ok(storage)
231	}
232	/// Assimilate the storage for this module into pre-existing overlays.
233	fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String>;
234}
235
236#[cfg(feature = "std")]
237impl BuildStorage for sp_core::storage::Storage {
238	fn assimilate_storage(&self, storage: &mut sp_core::storage::Storage) -> Result<(), String> {
239		storage.top.extend(self.top.iter().map(|(k, v)| (k.clone(), v.clone())));
240		for (k, other_map) in self.children_default.iter() {
241			let k = k.clone();
242			if let Some(map) = storage.children_default.get_mut(&k) {
243				map.data.extend(other_map.data.iter().map(|(k, v)| (k.clone(), v.clone())));
244				if !map.child_info.try_update(&other_map.child_info) {
245					return Err("Incompatible child info update".to_string());
246				}
247			} else {
248				storage.children_default.insert(k, other_map.clone());
249			}
250		}
251		Ok(())
252	}
253}
254
255#[cfg(feature = "std")]
256impl BuildStorage for () {
257	fn assimilate_storage(&self, _: &mut sp_core::storage::Storage) -> Result<(), String> {
258		Err("`assimilate_storage` not implemented for `()`".into())
259	}
260}
261
262/// Consensus engine unique ID.
263pub type ConsensusEngineId = [u8; 4];
264
265/// Signature verify that can work with any known signature types.
266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
267#[derive(
268	Eq, PartialEq, Clone, Encode, Decode, DecodeWithMemTracking, MaxEncodedLen, Debug, TypeInfo,
269)]
270pub enum MultiSignature {
271	/// An Ed25519 signature.
272	Ed25519(ed25519::Signature),
273	/// An Sr25519 signature.
274	Sr25519(sr25519::Signature),
275	/// An ECDSA/SECP256k1 signature.
276	Ecdsa(ecdsa::Signature),
277	/// An ECDSA/SECP256k1 signature but with a different address derivation.
278	Eth(ecdsa::KeccakSignature),
279}
280
281impl From<ed25519::Signature> for MultiSignature {
282	fn from(x: ed25519::Signature) -> Self {
283		Self::Ed25519(x)
284	}
285}
286
287impl TryFrom<MultiSignature> for ed25519::Signature {
288	type Error = ();
289	fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
290		if let MultiSignature::Ed25519(x) = m {
291			Ok(x)
292		} else {
293			Err(())
294		}
295	}
296}
297
298impl From<sr25519::Signature> for MultiSignature {
299	fn from(x: sr25519::Signature) -> Self {
300		Self::Sr25519(x)
301	}
302}
303
304impl TryFrom<MultiSignature> for sr25519::Signature {
305	type Error = ();
306	fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
307		if let MultiSignature::Sr25519(x) = m {
308			Ok(x)
309		} else {
310			Err(())
311		}
312	}
313}
314
315impl From<ecdsa::Signature> for MultiSignature {
316	fn from(x: ecdsa::Signature) -> Self {
317		Self::Ecdsa(x)
318	}
319}
320
321impl TryFrom<MultiSignature> for ecdsa::Signature {
322	type Error = ();
323	fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
324		if let MultiSignature::Ecdsa(x) = m {
325			Ok(x)
326		} else {
327			Err(())
328		}
329	}
330}
331
332/// Public key for any known crypto algorithm.
333#[derive(
334	Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo,
335)]
336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
337pub enum MultiSigner {
338	/// An Ed25519 identity.
339	Ed25519(ed25519::Public),
340	/// An Sr25519 identity.
341	Sr25519(sr25519::Public),
342	/// An SECP256k1/ECDSA identity (actually, the Blake2 hash of the compressed pub key).
343	Ecdsa(ecdsa::Public),
344	/// Same as `Ecdsa` but its account id is derived based off its eth address instead of its
345	/// pubkey.
346	///
347	/// This is important so that the address matches the address to address mapping in
348	/// `pallet_revive`. This means that the same public key controls two accounts. But
349	/// this is already the case due to `pallet_revive`'s address mapping.
350	Eth(ecdsa::KeccakPublic),
351}
352
353impl FromEntropy for MultiSigner {
354	fn from_entropy(input: &mut impl codec::Input) -> Result<Self, codec::Error> {
355		Ok(match input.read_byte()? % 4 {
356			0 => Self::Ed25519(FromEntropy::from_entropy(input)?),
357			1 => Self::Sr25519(FromEntropy::from_entropy(input)?),
358			2 => Self::Ecdsa(FromEntropy::from_entropy(input)?),
359			3.. => Self::Eth(FromEntropy::from_entropy(input)?),
360		})
361	}
362}
363
364/// NOTE: This implementations is required by `SimpleAddressDeterminer`,
365/// we convert the hash into some AccountId, it's fine to use any scheme.
366impl<T: Into<H256>> crypto::UncheckedFrom<T> for MultiSigner {
367	fn unchecked_from(x: T) -> Self {
368		ed25519::Public::unchecked_from(x.into()).into()
369	}
370}
371
372impl AsRef<[u8]> for MultiSigner {
373	fn as_ref(&self) -> &[u8] {
374		match *self {
375			Self::Ed25519(ref who) => who.as_ref(),
376			Self::Sr25519(ref who) => who.as_ref(),
377			Self::Ecdsa(ref who) => who.as_ref(),
378			Self::Eth(ref who) => who.as_ref(),
379		}
380	}
381}
382
383impl traits::IdentifyAccount for MultiSigner {
384	type AccountId = AccountId32;
385	fn into_account(self) -> AccountId32 {
386		match self {
387			Self::Ed25519(who) => <[u8; 32]>::from(who).into(),
388			Self::Sr25519(who) => <[u8; 32]>::from(who).into(),
389			Self::Ecdsa(who) => sp_io::hashing::blake2_256(who.as_ref()).into(),
390			Self::Eth(who) => {
391				// It is important that the account id is based off the eth address rather
392				// than its pubkey. This is because in many cases we don't know the pubkey
393				// of an eth account.
394				let eth_address = &sp_io::hashing::keccak_256(who.as_ref())[12..];
395				// This is by convention: `pallet_revive` maps eth addresses to account ids
396				// by filling up the additional 12 bytes with 0xEE.
397				let mut address = [0xEE; 32];
398				address[..20].copy_from_slice(eth_address);
399				address.into()
400			},
401		}
402	}
403}
404
405impl From<ed25519::Public> for MultiSigner {
406	fn from(x: ed25519::Public) -> Self {
407		Self::Ed25519(x)
408	}
409}
410
411impl TryFrom<MultiSigner> for ed25519::Public {
412	type Error = ();
413	fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
414		if let MultiSigner::Ed25519(x) = m {
415			Ok(x)
416		} else {
417			Err(())
418		}
419	}
420}
421
422impl From<sr25519::Public> for MultiSigner {
423	fn from(x: sr25519::Public) -> Self {
424		Self::Sr25519(x)
425	}
426}
427
428impl TryFrom<MultiSigner> for sr25519::Public {
429	type Error = ();
430	fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
431		if let MultiSigner::Sr25519(x) = m {
432			Ok(x)
433		} else {
434			Err(())
435		}
436	}
437}
438
439impl From<ecdsa::Public> for MultiSigner {
440	fn from(x: ecdsa::Public) -> Self {
441		Self::Ecdsa(x)
442	}
443}
444
445impl TryFrom<MultiSigner> for ecdsa::Public {
446	type Error = ();
447	fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
448		if let MultiSigner::Ecdsa(x) = m {
449			Ok(x)
450		} else {
451			Err(())
452		}
453	}
454}
455
456#[cfg(feature = "std")]
457impl std::fmt::Display for MultiSigner {
458	fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
459		match self {
460			Self::Ed25519(who) => write!(fmt, "ed25519: {}", who),
461			Self::Sr25519(who) => write!(fmt, "sr25519: {}", who),
462			Self::Ecdsa(who) => write!(fmt, "ecdsa: {}", who),
463			Self::Eth(who) => write!(fmt, "eth: {}", who),
464		}
465	}
466}
467
468impl Verify for MultiSignature {
469	type Signer = MultiSigner;
470	fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &AccountId32) -> bool {
471		let who: [u8; 32] = *signer.as_ref();
472		match self {
473			Self::Ed25519(sig) => sig.verify(msg, &who.into()),
474			Self::Sr25519(sig) => sig.verify(msg, &who.into()),
475			Self::Ecdsa(sig) => {
476				let sig_ref: &[u8; 65] = sig.as_ref();
477				// Reject high-S signatures (BIP-62 malleability protection)
478				if !ecdsa::is_signature_normalized(sig_ref) {
479					return false;
480				}
481				let m = sp_io::hashing::blake2_256(msg.get());
482				sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig_ref, &m)
483					.map_or(false, |pubkey| sp_io::hashing::blake2_256(&pubkey) == who)
484			},
485			Self::Eth(sig) => {
486				let sig_ref: &[u8; 65] = sig.as_ref();
487				// Reject high-S signatures (EIP-2 / BIP-62 malleability protection)
488				if !ecdsa::is_signature_normalized(sig_ref) {
489					return false;
490				}
491				let m = sp_io::hashing::keccak_256(msg.get());
492				sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig_ref, &m)
493					.map_or(false, |pubkey| {
494						&MultiSigner::Eth(pubkey.into()).into_account() == signer
495					})
496			},
497		}
498	}
499}
500
501/// Signature verify that can work with any known signature types..
502#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, Debug, TypeInfo)]
503#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
504pub struct AnySignature(H512);
505
506impl Verify for AnySignature {
507	type Signer = sr25519::Public;
508	fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &sr25519::Public) -> bool {
509		let msg = msg.get();
510		sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
511			.map(|s| s.verify(msg, signer))
512			.unwrap_or(false) ||
513			ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
514				.map(|s| match ed25519::Public::from_slice(signer.as_ref()) {
515					Err(()) => false,
516					Ok(signer) => s.verify(msg, &signer),
517				})
518				.unwrap_or(false)
519	}
520}
521
522impl From<sr25519::Signature> for AnySignature {
523	fn from(s: sr25519::Signature) -> Self {
524		Self(s.into())
525	}
526}
527
528impl From<ed25519::Signature> for AnySignature {
529	fn from(s: ed25519::Signature) -> Self {
530		Self(s.into())
531	}
532}
533
534impl From<DispatchError> for DispatchOutcome {
535	fn from(err: DispatchError) -> Self {
536		Err(err)
537	}
538}
539
540/// This is the legacy return type of `Dispatchable`. It is still exposed for compatibility reasons.
541/// The new return type is `DispatchResultWithInfo`. FRAME runtimes should use
542/// `frame_support::dispatch::DispatchResult`.
543pub type DispatchResult = core::result::Result<(), DispatchError>;
544
545/// Return type of a `Dispatchable` which contains the `DispatchResult` and additional information
546/// about the `Dispatchable` that is only known post dispatch.
547pub type DispatchResultWithInfo<T> = core::result::Result<T, DispatchErrorWithPostInfo<T>>;
548
549/// Reason why a pallet call failed.
550#[derive(
551	Eq, Clone, Copy, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo, MaxEncodedLen,
552)]
553#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
554pub struct ModuleError {
555	/// Module index, matching the metadata module index.
556	pub index: u8,
557	/// Module specific error value.
558	pub error: [u8; MAX_MODULE_ERROR_ENCODED_SIZE],
559	/// Optional error message.
560	#[codec(skip)]
561	#[cfg_attr(feature = "serde", serde(skip_deserializing))]
562	pub message: Option<&'static str>,
563}
564
565impl PartialEq for ModuleError {
566	fn eq(&self, other: &Self) -> bool {
567		(self.index == other.index) && (self.error == other.error)
568	}
569}
570
571/// Reason why a transaction was invalid due to a module-specific reason.
572///
573/// Semantically different from [`ModuleError`] (dispatch error). Carries a per-module error
574/// number when validation fails.
575#[derive(
576	Eq,
577	PartialEq,
578	Clone,
579	Copy,
580	Encode,
581	Decode,
582	DecodeWithMemTracking,
583	Debug,
584	TypeInfo,
585	MaxEncodedLen,
586)]
587#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
588pub struct ModuleInvalidity {
589	/// Module index, matching the metadata module index.
590	pub index: u8,
591	/// Module-specific error number.
592	pub error: u16,
593}
594
595/// Errors related to transactional storage layers.
596#[derive(
597	Eq,
598	PartialEq,
599	Clone,
600	Copy,
601	Encode,
602	Decode,
603	DecodeWithMemTracking,
604	Debug,
605	TypeInfo,
606	MaxEncodedLen,
607)]
608#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
609pub enum TransactionalError {
610	/// Too many transactional layers have been spawned.
611	LimitReached,
612	/// A transactional layer was expected, but does not exist.
613	NoLayer,
614}
615
616impl From<TransactionalError> for &'static str {
617	fn from(e: TransactionalError) -> &'static str {
618		match e {
619			TransactionalError::LimitReached => "Too many transactional layers have been spawned",
620			TransactionalError::NoLayer => "A transactional layer was expected, but does not exist",
621		}
622	}
623}
624
625impl From<TransactionalError> for DispatchError {
626	fn from(e: TransactionalError) -> DispatchError {
627		Self::Transactional(e)
628	}
629}
630
631/// Reason why a dispatch call failed.
632#[derive(
633	Eq,
634	Clone,
635	Copy,
636	Encode,
637	Decode,
638	DecodeWithMemTracking,
639	Debug,
640	TypeInfo,
641	PartialEq,
642	MaxEncodedLen,
643)]
644#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
645pub enum DispatchError {
646	/// Some error occurred.
647	Other(
648		#[codec(skip)]
649		#[cfg_attr(feature = "serde", serde(skip_deserializing))]
650		&'static str,
651	),
652	/// Failed to lookup some data.
653	CannotLookup,
654	/// A bad origin.
655	BadOrigin,
656	/// A custom error in a module.
657	Module(ModuleError),
658	/// At least one consumer is remaining so the account cannot be destroyed.
659	ConsumerRemaining,
660	/// There are no providers so the account cannot be created.
661	NoProviders,
662	/// There are too many consumers so the account cannot be created.
663	TooManyConsumers,
664	/// An error to do with tokens.
665	Token(TokenError),
666	/// An arithmetic error.
667	Arithmetic(ArithmeticError),
668	/// The number of transactional layers has been reached, or we are not in a transactional
669	/// layer.
670	Transactional(TransactionalError),
671	/// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate.
672	Exhausted,
673	/// The state is corrupt; this is generally not going to fix itself.
674	Corruption,
675	/// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later.
676	Unavailable,
677	/// Root origin is not allowed.
678	RootNotAllowed,
679	/// An error with tries.
680	Trie(TrieError),
681}
682
683/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information about
684/// the `Dispatchable` that is only known post dispatch.
685#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, DecodeWithMemTracking, Debug, TypeInfo)]
686pub struct DispatchErrorWithPostInfo<Info>
687where
688	Info: Eq + PartialEq + Clone + Copy + Encode + Decode,
689{
690	/// Additional information about the `Dispatchable` which is only known post dispatch.
691	pub post_info: Info,
692	/// The actual `DispatchResult` indicating whether the dispatch was successful.
693	pub error: DispatchError,
694}
695
696impl DispatchError {
697	/// Return the same error but without the attached message.
698	pub fn stripped(self) -> Self {
699		match self {
700			DispatchError::Module(ModuleError { index, error, message: Some(_) }) => {
701				DispatchError::Module(ModuleError { index, error, message: None })
702			},
703			m => m,
704		}
705	}
706}
707
708impl<T, E> From<E> for DispatchErrorWithPostInfo<T>
709where
710	T: Eq + PartialEq + Clone + Copy + Encode + Decode + Default,
711	E: Into<DispatchError>,
712{
713	fn from(error: E) -> Self {
714		Self { post_info: Default::default(), error: error.into() }
715	}
716}
717
718impl From<crate::traits::LookupError> for DispatchError {
719	fn from(_: crate::traits::LookupError) -> Self {
720		Self::CannotLookup
721	}
722}
723
724impl From<crate::traits::BadOrigin> for DispatchError {
725	fn from(_: crate::traits::BadOrigin) -> Self {
726		Self::BadOrigin
727	}
728}
729
730/// Description of what went wrong when trying to complete an operation on a token.
731#[derive(
732	Eq,
733	PartialEq,
734	Clone,
735	Copy,
736	Encode,
737	Decode,
738	DecodeWithMemTracking,
739	Debug,
740	TypeInfo,
741	MaxEncodedLen,
742)]
743#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
744pub enum TokenError {
745	/// Funds are unavailable.
746	FundsUnavailable,
747	/// Some part of the balance gives the only provider reference to the account and thus cannot
748	/// be (re)moved.
749	OnlyProvider,
750	/// Account cannot exist with the funds that would be given.
751	BelowMinimum,
752	/// Account cannot be created.
753	CannotCreate,
754	/// The asset in question is unknown.
755	UnknownAsset,
756	/// Funds exist but are frozen.
757	Frozen,
758	/// Operation is not supported by the asset.
759	Unsupported,
760	/// Account cannot be created for a held balance.
761	CannotCreateHold,
762	/// Withdrawal would cause unwanted loss of account.
763	NotExpendable,
764	/// Account cannot receive the assets.
765	Blocked,
766}
767
768impl From<TokenError> for &'static str {
769	fn from(e: TokenError) -> &'static str {
770		match e {
771			TokenError::FundsUnavailable => "Funds are unavailable",
772			TokenError::OnlyProvider => "Account that must exist would die",
773			TokenError::BelowMinimum => "Account cannot exist with the funds that would be given",
774			TokenError::CannotCreate => "Account cannot be created",
775			TokenError::UnknownAsset => "The asset in question is unknown",
776			TokenError::Frozen => "Funds exist but are frozen",
777			TokenError::Unsupported => "Operation is not supported by the asset",
778			TokenError::CannotCreateHold => {
779				"Account cannot be created for recording amount on hold"
780			},
781			TokenError::NotExpendable => "Account that is desired to remain would die",
782			TokenError::Blocked => "Account cannot receive the assets",
783		}
784	}
785}
786
787impl From<TokenError> for DispatchError {
788	fn from(e: TokenError) -> DispatchError {
789		Self::Token(e)
790	}
791}
792
793impl From<ArithmeticError> for DispatchError {
794	fn from(e: ArithmeticError) -> DispatchError {
795		Self::Arithmetic(e)
796	}
797}
798
799impl From<TrieError> for DispatchError {
800	fn from(e: TrieError) -> DispatchError {
801		Self::Trie(e)
802	}
803}
804
805impl From<&'static str> for DispatchError {
806	fn from(err: &'static str) -> DispatchError {
807		Self::Other(err)
808	}
809}
810
811impl From<DispatchError> for &'static str {
812	fn from(err: DispatchError) -> &'static str {
813		use DispatchError::*;
814		match err {
815			Other(msg) => msg,
816			CannotLookup => "Cannot lookup",
817			BadOrigin => "Bad origin",
818			Module(ModuleError { message, .. }) => message.unwrap_or("Unknown module error"),
819			ConsumerRemaining => "Consumer remaining",
820			NoProviders => "No providers",
821			TooManyConsumers => "Too many consumers",
822			Token(e) => e.into(),
823			Arithmetic(e) => e.into(),
824			Transactional(e) => e.into(),
825			Exhausted => "Resources exhausted",
826			Corruption => "State corrupt",
827			Unavailable => "Resource unavailable",
828			RootNotAllowed => "Root not allowed",
829			Trie(e) => e.into(),
830		}
831	}
832}
833
834impl<T> From<DispatchErrorWithPostInfo<T>> for &'static str
835where
836	T: Eq + PartialEq + Clone + Copy + Encode + Decode,
837{
838	fn from(err: DispatchErrorWithPostInfo<T>) -> &'static str {
839		err.error.into()
840	}
841}
842
843/// This type specifies the outcome of dispatching a call to a module.
844///
845/// In case of failure an error specific to the module is returned.
846///
847/// Failure of the module call dispatching doesn't invalidate the extrinsic and it is still included
848/// in the block, therefore all state changes performed by the dispatched call are still persisted.
849///
850/// For example, if the dispatching of an extrinsic involves inclusion fee payment then these
851/// changes are going to be preserved even if the call dispatched failed.
852pub type DispatchOutcome = Result<(), DispatchError>;
853
854/// The result of applying of an extrinsic.
855///
856/// This type is typically used in the context of `BlockBuilder` to signal that the extrinsic
857/// in question cannot be included.
858///
859/// A block containing extrinsics that have a negative inclusion outcome is invalid. A negative
860/// result can only occur during the block production, where such extrinsics are detected and
861/// removed from the block that is being created and the transaction pool.
862///
863/// To rehash: every extrinsic in a valid block must return a positive `ApplyExtrinsicResult`.
864///
865/// Examples of reasons preventing inclusion in a block:
866/// - More block weight is required to process the extrinsic than is left in the block being built.
867///   This doesn't necessarily mean that the extrinsic is invalid, since it can still be included in
868///   the next block if it has enough spare weight available.
869/// - The sender doesn't have enough funds to pay the transaction inclusion fee. Including such a
870///   transaction in the block doesn't make sense.
871/// - The extrinsic supplied a bad signature. This transaction won't become valid ever.
872pub type ApplyExtrinsicResult =
873	Result<DispatchOutcome, transaction_validity::TransactionValidityError>;
874
875/// Same as `ApplyExtrinsicResult` but augmented with `PostDispatchInfo` on success.
876pub type ApplyExtrinsicResultWithInfo<T> =
877	Result<DispatchResultWithInfo<T>, transaction_validity::TransactionValidityError>;
878
879/// The error type used as return type in try runtime hooks.
880pub type TryRuntimeError = DispatchError;
881
882/// Verify a signature on an encoded value in a lazy manner. This can be
883/// an optimization if the signature scheme has an "unsigned" escape hash.
884pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(
885	sig: &V,
886	item: &T,
887	signer: &<V::Signer as IdentifyAccount>::AccountId,
888) -> bool {
889	// The `Lazy<T>` trait expresses something like `X: FnMut<Output = for<'a> &'a T>`.
890	// unfortunately this is a lifetime relationship that can't
891	// be expressed without generic associated types, better unification of HRTBs in type position,
892	// and some kind of integration into the Fn* traits.
893	struct LazyEncode<F> {
894		inner: F,
895		encoded: Option<Vec<u8>>,
896	}
897
898	impl<F: Fn() -> Vec<u8>> traits::Lazy<[u8]> for LazyEncode<F> {
899		fn get(&mut self) -> &[u8] {
900			self.encoded.get_or_insert_with(&self.inner).as_slice()
901		}
902	}
903
904	sig.verify(LazyEncode { inner: || item.encode(), encoded: None }, signer)
905}
906
907/// Checks that `$x` is equal to `$y` with an error rate of `$error`.
908///
909/// # Example
910///
911/// ```rust
912/// # fn main() {
913/// sp_runtime::assert_eq_error_rate!(10, 10, 0);
914/// sp_runtime::assert_eq_error_rate!(10, 11, 1);
915/// sp_runtime::assert_eq_error_rate!(12, 10, 2);
916/// # }
917/// ```
918///
919/// ```rust,should_panic
920/// # fn main() {
921/// sp_runtime::assert_eq_error_rate!(12, 10, 1);
922/// # }
923/// ```
924#[macro_export]
925#[cfg(feature = "std")]
926macro_rules! assert_eq_error_rate {
927	($x:expr, $y:expr, $error:expr $(,)?) => {
928		assert!(
929			($x >= $crate::Saturating::saturating_sub($y, $error)) &&
930				($x <= $crate::Saturating::saturating_add($y, $error)),
931			"{:?} != {:?} (with error rate {:?})",
932			$x,
933			$y,
934			$error,
935		);
936	};
937}
938
939/// Same as [`assert_eq_error_rate`], but intended to be used with floating point number, or
940/// generally those who do not have over/underflow potentials.
941#[macro_export]
942#[cfg(feature = "std")]
943macro_rules! assert_eq_error_rate_float {
944	($x:expr, $y:expr, $error:expr $(,)?) => {
945		assert!(
946			($x >= $y - $error) && ($x <= $y + $error),
947			"{:?} != {:?} (with error rate {:?})",
948			$x,
949			$y,
950			$error,
951		);
952	};
953}
954
955/// Simple blob to hold an extrinsic without committing to its format and ensure it is serialized
956/// correctly.
957#[derive(PartialEq, Eq, Clone, Default, Encode, Decode, DecodeWithMemTracking)]
958pub struct OpaqueExtrinsic(bytes::Bytes);
959
960impl TypeInfo for OpaqueExtrinsic {
961	type Identity = Self;
962	fn type_info() -> scale_info::Type {
963		scale_info::Type::builder()
964			.path(scale_info::Path::new("OpaqueExtrinsic", module_path!()))
965			.composite(
966				scale_info::build::Fields::unnamed()
967					.field(|f| f.ty::<Vec<u8>>().type_name("Vec<u8>")),
968			)
969	}
970}
971
972impl OpaqueExtrinsic {
973	/// Convert an encoded extrinsic to an `OpaqueExtrinsic`.
974	pub fn try_from_encoded_extrinsic(mut bytes: &[u8]) -> Result<Self, codec::Error> {
975		Self::decode(&mut bytes)
976	}
977
978	/// Convert an encoded extrinsic to an `OpaqueExtrinsic`.
979	#[deprecated = "Use `try_from_encoded_extrinsic()` instead"]
980	pub fn from_bytes(bytes: &[u8]) -> Result<Self, codec::Error> {
981		Self::try_from_encoded_extrinsic(bytes)
982	}
983
984	/// Create a new instance of `OpaqueExtrinsic` from a `Vec<u8>`.
985	pub fn from_blob(bytes: Vec<u8>) -> Self {
986		Self(bytes.into())
987	}
988
989	/// Get the actual blob.
990	pub fn inner(&self) -> &[u8] {
991		&self.0
992	}
993}
994
995impl LazyExtrinsic for OpaqueExtrinsic {
996	fn decode_unprefixed(data: &[u8]) -> Result<Self, codec::Error> {
997		Ok(Self(data.to_vec().into()))
998	}
999}
1000
1001impl core::fmt::Debug for OpaqueExtrinsic {
1002	#[cfg(feature = "std")]
1003	fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
1004		write!(fmt, "{}", sp_core::hexdisplay::HexDisplay::from(&self.0.as_ref()))
1005	}
1006
1007	#[cfg(not(feature = "std"))]
1008	fn fmt(&self, _fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
1009		Ok(())
1010	}
1011}
1012
1013#[cfg(feature = "serde")]
1014impl ::serde::Serialize for OpaqueExtrinsic {
1015	fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
1016	where
1017		S: ::serde::Serializer,
1018	{
1019		codec::Encode::using_encoded(&self.0, |bytes| ::sp_core::bytes::serialize(bytes, seq))
1020	}
1021}
1022
1023#[cfg(feature = "serde")]
1024impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic {
1025	fn deserialize<D>(de: D) -> Result<Self, D::Error>
1026	where
1027		D: ::serde::Deserializer<'a>,
1028	{
1029		let r = ::sp_core::bytes::deserialize(de)?;
1030		Decode::decode(&mut &r[..])
1031			.map_err(|e| ::serde::de::Error::custom(alloc::format!("Decode error: {}", e)))
1032	}
1033}
1034
1035impl traits::ExtrinsicLike for OpaqueExtrinsic {
1036	fn is_bare(&self) -> bool {
1037		false
1038	}
1039}
1040
1041/// Utility function to declare string literals backed by an array of length N.
1042///
1043/// The input can be shorter than N, in that case the end of the array is padded with zeros.
1044///
1045/// [`str_array`] is useful when converting strings that end up in the storage as fixed size arrays
1046/// or in const contexts where static data types have strings that could also end up in the storage.
1047///
1048/// # Example
1049///
1050/// ```rust
1051/// # use sp_runtime::str_array;
1052/// const MY_STR: [u8; 6] = str_array("data");
1053/// assert_eq!(MY_STR, *b"data\0\0");
1054/// ```
1055pub const fn str_array<const N: usize>(s: &str) -> [u8; N] {
1056	debug_assert!(s.len() <= N, "String literal doesn't fit in array");
1057	let mut i = 0;
1058	let mut arr = [0; N];
1059	let s = s.as_bytes();
1060	while i < s.len() {
1061		arr[i] = s[i];
1062		i += 1;
1063	}
1064	arr
1065}
1066
1067/// Describes on what should happen with a storage transaction.
1068pub enum TransactionOutcome<R> {
1069	/// Commit the transaction.
1070	Commit(R),
1071	/// Rollback the transaction.
1072	Rollback(R),
1073}
1074
1075impl<R> TransactionOutcome<R> {
1076	/// Convert into the inner type.
1077	pub fn into_inner(self) -> R {
1078		match self {
1079			Self::Commit(r) => r,
1080			Self::Rollback(r) => r,
1081		}
1082	}
1083}
1084
1085/// Confines the kind of extrinsics that can be included in a block.
1086#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, Encode, Decode, TypeInfo)]
1087pub enum ExtrinsicInclusionMode {
1088	/// All extrinsics are allowed to be included in this block.
1089	#[default]
1090	AllExtrinsics,
1091	/// Inherents are allowed to be included.
1092	OnlyInherents,
1093}
1094
1095/// Simple blob that hold a value in an encoded form without committing to its type.
1096#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
1097pub struct OpaqueValue(Vec<u8>);
1098impl OpaqueValue {
1099	/// Create a new `OpaqueValue` using the given encoded representation.
1100	pub fn new(inner: Vec<u8>) -> OpaqueValue {
1101		OpaqueValue(inner)
1102	}
1103
1104	/// Try to decode this `OpaqueValue` into the given concrete type.
1105	pub fn decode<T: Decode>(&self) -> Option<T> {
1106		Decode::decode(&mut &self.0[..]).ok()
1107	}
1108}
1109
1110// TODO: Remove in future versions and clean up `parse_str_literal` in `sp-version-proc-macro`
1111/// Deprecated `Cow::Borrowed()` wrapper.
1112#[macro_export]
1113#[deprecated = "Use Cow::Borrowed() instead of create_runtime_str!()"]
1114macro_rules! create_runtime_str {
1115	( $y:expr ) => {{
1116		$crate::Cow::Borrowed($y)
1117	}};
1118}
1119// TODO: Re-export for ^ macro `create_runtime_str`, should be removed once macro is gone
1120#[doc(hidden)]
1121pub use alloc::borrow::Cow;
1122
1123// TODO: Remove in future versions
1124/// Deprecated alias to improve upgrade experience
1125#[deprecated = "Use String or Cow<'static, str> instead"]
1126pub type RuntimeString = alloc::string::String;
1127
1128#[cfg(test)]
1129mod tests {
1130	use crate::traits::BlakeTwo256;
1131
1132	use super::*;
1133	use codec::{Decode, Encode};
1134	use sp_core::{crypto::Pair, hex2array};
1135	use sp_io::TestExternalities;
1136	use sp_state_machine::create_proof_check_backend;
1137
1138	#[test]
1139	fn opaque_extrinsic_serialization() {
1140		let ex = OpaqueExtrinsic::from_blob(vec![1, 2, 3, 4]);
1141		assert_eq!(serde_json::to_string(&ex).unwrap(), "\"0x1001020304\"".to_owned());
1142	}
1143
1144	#[test]
1145	fn dispatch_error_encoding() {
1146		let error = DispatchError::Module(ModuleError {
1147			index: 1,
1148			error: [2, 0, 0, 0],
1149			message: Some("error message"),
1150		});
1151		let encoded = error.encode();
1152		let decoded = DispatchError::decode(&mut &encoded[..]).unwrap();
1153		assert_eq!(encoded, vec![3, 1, 2, 0, 0, 0]);
1154		assert_eq!(
1155			decoded,
1156			DispatchError::Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: None })
1157		);
1158	}
1159
1160	#[test]
1161	fn module_invalidity_should_encode_and_decode() {
1162		let invalidity = ModuleInvalidity { index: 7, error: 3 };
1163		let encoded = invalidity.encode();
1164		let decoded = ModuleInvalidity::decode(&mut &encoded[..]).unwrap();
1165		assert_eq!(encoded, vec![7, 3, 0]);
1166		assert_eq!(decoded, invalidity);
1167	}
1168
1169	#[test]
1170	fn dispatch_error_equality() {
1171		use DispatchError::*;
1172
1173		let variants = vec![
1174			Other("foo"),
1175			Other("bar"),
1176			CannotLookup,
1177			BadOrigin,
1178			Module(ModuleError { index: 1, error: [1, 0, 0, 0], message: None }),
1179			Module(ModuleError { index: 1, error: [2, 0, 0, 0], message: None }),
1180			Module(ModuleError { index: 2, error: [1, 0, 0, 0], message: None }),
1181			ConsumerRemaining,
1182			NoProviders,
1183			Token(TokenError::FundsUnavailable),
1184			Token(TokenError::OnlyProvider),
1185			Token(TokenError::BelowMinimum),
1186			Token(TokenError::CannotCreate),
1187			Token(TokenError::UnknownAsset),
1188			Token(TokenError::Frozen),
1189			Arithmetic(ArithmeticError::Overflow),
1190			Arithmetic(ArithmeticError::Underflow),
1191			Arithmetic(ArithmeticError::DivisionByZero),
1192		];
1193		for (i, variant) in variants.iter().enumerate() {
1194			for (j, other_variant) in variants.iter().enumerate() {
1195				if i == j {
1196					assert_eq!(variant, other_variant);
1197				} else {
1198					assert_ne!(variant, other_variant);
1199				}
1200			}
1201		}
1202
1203		// Ignores `message` field in `Module` variant.
1204		assert_eq!(
1205			Module(ModuleError { index: 1, error: [1, 0, 0, 0], message: Some("foo") }),
1206			Module(ModuleError { index: 1, error: [1, 0, 0, 0], message: None }),
1207		);
1208	}
1209
1210	#[test]
1211	fn multi_signature_ecdsa_verify_works() {
1212		let msg = &b"test-message"[..];
1213		let (pair, _) = ecdsa::Pair::generate();
1214
1215		let signature = pair.sign(&msg);
1216		assert!(ecdsa::Pair::verify(&signature, msg, &pair.public()));
1217
1218		let multi_sig = MultiSignature::from(signature);
1219		let multi_signer = MultiSigner::from(pair.public());
1220		assert!(multi_sig.verify(msg, &multi_signer.into_account()));
1221	}
1222
1223	#[test]
1224	fn multi_signature_eth_verify_works() {
1225		let msg = &b"test-message"[..];
1226		let (pair, _) = ecdsa::KeccakPair::generate();
1227
1228		let signature = pair.sign(&msg);
1229		assert!(ecdsa::KeccakPair::verify(&signature, msg, &pair.public()));
1230
1231		let multi_sig = MultiSignature::Eth(signature);
1232		let multi_signer = MultiSigner::Eth(pair.public());
1233		assert!(multi_sig.verify(msg, &multi_signer.into_account()));
1234	}
1235
1236	/// Helper: compute high-S malleable variant of a 65-byte ECDSA signature.
1237	/// Returns `s' = order - s` with `v' = v ^ 1`.
1238	pub(crate) fn make_high_s_signature(sig: &[u8; 65]) -> [u8; 65] {
1239		// secp256k1 curve order N
1240		let order: [u8; 32] = [
1241			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1242			0xff, 0xfe, 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c,
1243			0xd0, 0x36, 0x41, 0x41,
1244		];
1245		let s_bytes: [u8; 32] = sig[32..64].try_into().unwrap();
1246		let mut s_prime = [0u8; 32];
1247		let mut borrow = 0i16;
1248		for i in (0..32).rev() {
1249			let diff = order[i] as i16 - s_bytes[i] as i16 - borrow;
1250			if diff < 0 {
1251				s_prime[i] = (diff + 256) as u8;
1252				borrow = 1;
1253			} else {
1254				s_prime[i] = diff as u8;
1255				borrow = 0;
1256			}
1257		}
1258		let mut out = [0u8; 65];
1259		out[0..32].copy_from_slice(&sig[0..32]);
1260		out[32..64].copy_from_slice(&s_prime);
1261		out[64] = sig[64] ^ 1;
1262		out
1263	}
1264
1265	#[test]
1266	fn multi_signature_ecdsa_rejects_high_s() {
1267		let msg = &b"test-message"[..];
1268		let (pair, _) = ecdsa::Pair::generate();
1269
1270		let signature = pair.sign(&msg);
1271		let multi_signer = MultiSigner::from(pair.public());
1272		let account = multi_signer.into_account();
1273
1274		// Low-S signature verifies
1275		let multi_sig = MultiSignature::from(signature);
1276		assert!(multi_sig.verify(msg, &account));
1277
1278		// Construct high-S malleable variant
1279		let sig_bytes: &[u8; 65] = signature.as_ref();
1280		let malleable = make_high_s_signature(sig_bytes);
1281		let malleable_sig = MultiSignature::Ecdsa(ecdsa::Signature::from_raw(malleable));
1282		assert!(
1283			!malleable_sig.verify(msg, &account),
1284			"high-S ECDSA signature should be rejected by MultiSignature"
1285		);
1286	}
1287
1288	#[test]
1289	fn multi_signature_eth_rejects_high_s() {
1290		let msg = &b"test-message"[..];
1291		let (pair, _) = ecdsa::KeccakPair::generate();
1292
1293		let signature = pair.sign(&msg);
1294		let multi_signer = MultiSigner::Eth(pair.public());
1295		let account = multi_signer.into_account();
1296
1297		// Low-S signature verifies
1298		let multi_sig = MultiSignature::Eth(signature);
1299		assert!(multi_sig.verify(msg, &account));
1300
1301		// Construct high-S malleable variant
1302		let sig_bytes: &[u8; 65] = signature.as_ref();
1303		let malleable = make_high_s_signature(sig_bytes);
1304		let malleable_sig = MultiSignature::Eth(ecdsa::KeccakSignature::from_raw(malleable));
1305		assert!(
1306			!malleable_sig.verify(msg, &account),
1307			"high-S Eth signature should be rejected by MultiSignature"
1308		);
1309	}
1310
1311	#[test]
1312	fn multi_signer_eth_address_works() {
1313		let ecdsa_pair = ecdsa::Pair::from_seed(&[0x42; 32]);
1314		let eth_pair = ecdsa::KeccakPair::from_seed(&[0x42; 32]);
1315		let ecdsa = MultiSigner::Ecdsa(ecdsa_pair.public()).into_account();
1316		let eth = MultiSigner::Eth(eth_pair.public()).into_account();
1317
1318		assert_eq!(&<AccountId32 as AsRef<[u8; 32]>>::as_ref(&eth)[20..], &[0xEE; 12]);
1319		assert_eq!(
1320			ecdsa,
1321			hex2array!("ff241710529476ac87c67b66ccdc42f95a14b49a896164839fe675dc6f579614").into(),
1322		);
1323		assert_eq!(
1324			eth,
1325			hex2array!("2714c48edc39bc2714729e6530760d62344d6698eeeeeeeeeeeeeeeeeeeeeeee").into(),
1326		);
1327	}
1328
1329	#[test]
1330	fn execute_and_generate_proof_works() {
1331		use codec::Encode;
1332		use sp_state_machine::Backend;
1333		let mut ext = TestExternalities::default();
1334
1335		ext.insert(b"a".to_vec(), vec![1u8; 33]);
1336		ext.insert(b"b".to_vec(), vec![2u8; 33]);
1337		ext.insert(b"c".to_vec(), vec![3u8; 33]);
1338		ext.insert(b"d".to_vec(), vec![4u8; 33]);
1339
1340		let pre_root = *ext.backend.root();
1341		let (_, proof) = ext.execute_and_prove(|| {
1342			sp_io::storage::get(b"a");
1343			sp_io::storage::get(b"b");
1344			sp_io::storage::get(b"v");
1345			sp_io::storage::get(b"d");
1346		});
1347
1348		let compact_proof = proof.clone().into_compact_proof::<BlakeTwo256>(pre_root).unwrap();
1349		let compressed_proof = zstd::stream::encode_all(&compact_proof.encode()[..], 0).unwrap();
1350
1351		// just an example of how you'd inspect the size of the proof.
1352		println!("proof size: {:?}", proof.encoded_size());
1353		println!("compact proof size: {:?}", compact_proof.encoded_size());
1354		println!("zstd-compressed compact proof size: {:?}", &compressed_proof.len());
1355
1356		// create a new trie-backed from the proof and make sure it contains everything
1357		let proof_check = create_proof_check_backend::<BlakeTwo256>(pre_root, proof).unwrap();
1358		assert_eq!(proof_check.storage(b"a",).unwrap().unwrap(), vec![1u8; 33]);
1359
1360		let _ = ext.execute_and_prove(|| {
1361			sp_io::storage::set(b"a", &vec![1u8; 44]);
1362		});
1363
1364		// ensure that these changes are propagated to the backend.
1365
1366		ext.execute_with(|| {
1367			assert_eq!(sp_io::storage::get(b"a").unwrap(), vec![1u8; 44]);
1368			assert_eq!(sp_io::storage::get(b"b").unwrap(), vec![2u8; 33]);
1369		});
1370	}
1371}
1372
1373// NOTE: we have to test the sp_core stuff also from a different crate to check that the macro
1374// can access the sp_core crate.
1375#[cfg(test)]
1376mod sp_core_tests {
1377	sp_core::generate_feature_enabled_macro!(if_test, test, $);
1378	sp_core::generate_feature_enabled_macro!(if_not_test, not(test), $);
1379
1380	#[test]
1381	#[should_panic]
1382	fn generate_feature_enabled_macro_panics() {
1383		if_test!(panic!("This should panic"));
1384	}
1385
1386	#[test]
1387	fn generate_feature_enabled_macro_works() {
1388		if_not_test!(panic!("This should not panic"));
1389	}
1390}