Skip to content
Snippets Groups Projects
misc.rs 42.8 KiB
Newer Older
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Smaller traits used in FRAME which don't need their own file.

use crate::dispatch::{DispatchResult, Parameter};
use alloc::{vec, vec::Vec};
use codec::{CompactLen, Decode, DecodeLimit, Encode, EncodeLike, Input, MaxEncodedLen};
use impl_trait_for_tuples::impl_for_tuples;
use scale_info::{build::Fields, meta_type, Path, Type, TypeInfo, TypeParameter};
use sp_arithmetic::traits::{CheckedAdd, CheckedMul, CheckedSub, One, Saturating};
use sp_core::bounded::bounded_vec::TruncateFrom;
use core::cmp::Ordering;
#[doc(hidden)]
pub use sp_runtime::traits::{
	ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, ConstU32,
	ConstU64, ConstU8, Get, GetDefault, TryCollect, TypedGet,
use sp_runtime::{traits::Block as BlockT, DispatchError};
pub const DEFENSIVE_OP_PUBLIC_ERROR: &str = "a defensive failure has been triggered; please report the block number at https://github.com/paritytech/substrate/issues";
pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been triggered!";
/// Trait to get the number of variants in any enum.
pub trait VariantCount {
	/// Get the number of variants.
	const VARIANT_COUNT: u32;
}

impl VariantCount for () {
	const VARIANT_COUNT: u32 = 0;
}

impl VariantCount for u8 {
	const VARIANT_COUNT: u32 = 256;
}

/// Adapter for `Get<u32>` to access `VARIANT_COUNT` from `trait pub trait VariantCount {`.
pub struct VariantCountOf<T: VariantCount>(core::marker::PhantomData<T>);
impl<T: VariantCount> Get<u32> for VariantCountOf<T> {
	fn get() -> u32 {
		T::VARIANT_COUNT
	}
}

/// Generic function to mark an execution path as ONLY defensive.
///
/// Similar to mark a match arm or `if/else` branch as `unreachable!`.
#[macro_export]
macro_rules! defensive {
	() => {
		frame_support::__private::log::error!(
			target: "runtime::defensive",
			$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR
		debug_assert!(false, "{}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR);
	($error:expr $(,)?) => {
		frame_support::__private::log::error!(
			target: "runtime::defensive",
			$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
		debug_assert!(false, "{}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error);
	($error:expr, $proof:expr $(,)?) => {
		frame_support::__private::log::error!(
			target: "runtime::defensive",
			"{}: {:?}: {:?}",
			$crate::traits::DEFENSIVE_OP_PUBLIC_ERROR,
			$error,
			$proof,
		);
		debug_assert!(false, "{}: {:?}: {:?}", $crate::traits::DEFENSIVE_OP_INTERNAL_ERROR, $error, $proof);
/// Trigger a defensive failure if a condition is not met.
///
/// Similar to [`assert!`] but will print an error without `debug_assertions` instead of silently
/// ignoring it. Only accepts one instead of variable formatting arguments.
///
/// # Example
///
/// ```should_panic
/// frame_support::defensive_assert!(1 == 0, "Must fail")
/// ```
#[macro_export]
macro_rules! defensive_assert {
	($cond:expr $(, $proof:expr )? $(,)?) => {
		if !($cond) {
			$crate::defensive!(::core::stringify!($cond) $(, $proof )?);
		}
	};
}

/// Prelude module for all defensive traits to be imported at once.
pub mod defensive_prelude {
	pub use super::{Defensive, DefensiveOption, DefensiveResult};
}

/// A trait to handle errors and options when you are really sure that a condition must hold, but
/// not brave enough to `expect` on it, or a default fallback value makes more sense.
///
/// This trait mostly focuses on methods that eventually unwrap the inner value. See
/// [`DefensiveResult`] and [`DefensiveOption`] for methods that specifically apply to the
/// respective types.
///
/// Each function in this trait will have two side effects, aside from behaving exactly as the name
/// would suggest:
///
/// 1. It panics on `#[debug_assertions]`, so if the infallible code is reached in any of the tests,
///    you realize.
/// 2. It will log an error using the runtime logging system. This might help you detect such bugs
///    in production as well. Note that the log message, as of now, are not super expressive. Your
///    best shot of fully diagnosing the error would be to infer the block number of which the log
///    message was emitted, then re-execute that block using `check-block` or `try-runtime`
///    subcommands in substrate client.
pub trait Defensive<T> {
	/// Exactly the same as `unwrap_or`, but it does the defensive warnings explained in the trait
	/// docs.
	fn defensive_unwrap_or(self, other: T) -> T;

	/// Exactly the same as `unwrap_or_else`, but it does the defensive warnings explained in the
	/// trait docs.
	fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T;

	/// Exactly the same as `unwrap_or_default`, but it does the defensive warnings explained in the
	/// trait docs.
	fn defensive_unwrap_or_default(self) -> T
	where
		T: Default;

	/// Does not alter the inner value at all, but it will log warnings if the inner value is `None`
	/// or `Err`.
	///
	/// In some ways, this is like  `.defensive_map(|x| x)`.
	///
	/// This is useful as:
	/// ```nocompile
	/// if let Some(inner) = maybe_value().defensive() {
	/// 	 	..
	/// }
	/// ```
	fn defensive(self) -> Self;

	/// Same as [`Defensive::defensive`], but it takes a proof as input, and displays it if the
	/// defensive operation has been triggered.
	fn defensive_proof(self, proof: &'static str) -> Self;
}

/// Subset of methods similar to [`Defensive`] that can only work for a `Result`.
pub trait DefensiveResult<T, E> {
	/// Defensively map the error into another return type, but you are really sure that this
	/// conversion should never be needed.
	fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F>;

	/// Defensively map and unpack the value to something else (`U`), or call the default callback
	/// if `Err`, which should never happen.
	fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;

	/// Defensively transform this result into an option, discarding the `Err` variant if it
	/// happens, which should never happen.
	fn defensive_ok(self) -> Option<T>;

	/// Exactly the same as `map`, but it prints the appropriate warnings if the value being mapped
	/// is `Err`.
	fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E>;
}

/// Subset of methods similar to [`Defensive`] that can only work for a `Option`.
pub trait DefensiveOption<T> {
	/// Potentially map and unpack the value to something else (`U`), or call the default callback
	/// if `None`, which should never happen.
	fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U;

Zeke Mostov's avatar
Zeke Mostov committed
	/// Defensively transform this option to a result, mapping `None` to the return value of an
	/// error closure.
	fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E>;
Zeke Mostov's avatar
Zeke Mostov committed
	/// Defensively transform this option to a result, mapping `None` to a default value.
	fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E>;
	/// Exactly the same as `map`, but it prints the appropriate warnings if the value being mapped
	/// is `None`.
	fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U>;
}

impl<T> Defensive<T> for Option<T> {
	fn defensive_unwrap_or(self, or: T) -> T {
		match self {
			Some(inner) => inner,
			None => {
				or
			},
		}
	}

	fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
		match self {
			Some(inner) => inner,
			None => {
				f()
			},
		}
	}

	fn defensive_unwrap_or_default(self) -> T
	where
		T: Default,
	{
		match self {
			Some(inner) => inner,
			None => {
				Default::default()
			},
		}
	}

	fn defensive(self) -> Self {
		match self {
			Some(inner) => Some(inner),
			None => {

	fn defensive_proof(self, proof: &'static str) -> Self {
		if self.is_none() {
			defensive!(proof);
		}
		self
	}
impl<T, E: core::fmt::Debug> Defensive<T> for Result<T, E> {
	fn defensive_unwrap_or(self, or: T) -> T {
		match self {
			Ok(inner) => inner,
			Err(e) => {
				or
			},
		}
	}

	fn defensive_unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
		match self {
			Ok(inner) => inner,
			Err(e) => {
				f()
			},
		}
	}

	fn defensive_unwrap_or_default(self) -> T
	where
		T: Default,
	{
		match self {
			Ok(inner) => inner,
			Err(e) => {
				Default::default()
			},
		}
	}

	fn defensive(self) -> Self {
		match self {
			Ok(inner) => Ok(inner),
			Err(e) => {

	fn defensive_proof(self, proof: &'static str) -> Self {
		match self {
			Ok(inner) => Ok(inner),
			Err(e) => {
				defensive!(e, proof);
				Err(e)
			},
		}
	}
impl<T, E: core::fmt::Debug> DefensiveResult<T, E> for Result<T, E> {
	fn defensive_map_err<F, O: FnOnce(E) -> F>(self, o: O) -> Result<T, F> {
		self.map_err(|e| {
			o(e)
		})
	}

	fn defensive_map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
		self.map_or_else(
			|e| {
				default(e)
			},
			f,
		)
	}

	fn defensive_ok(self) -> Option<T> {
		match self {
			Ok(inner) => Some(inner),
			Err(e) => {
				None
			},
		}
	}

	fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Result<U, E> {
		match self {
			Ok(inner) => Ok(f(inner)),
			Err(e) => {
				Err(e)
			},
		}
	}
}

impl<T> DefensiveOption<T> for Option<T> {
	fn defensive_map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
		self.map_or_else(
			|| {
	fn defensive_ok_or_else<E: core::fmt::Debug, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
			let err_value = err();
			defensive!(err_value);
			err_value
	fn defensive_ok_or<E: core::fmt::Debug>(self, err: E) -> Result<T, E> {
Zeke Mostov's avatar
Zeke Mostov committed
		self.ok_or_else(|| {
			defensive!(err);
	fn defensive_map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
		match self {
			Some(inner) => Some(f(inner)),
			None => {
				None
			},
		}
	}
}

/// A variant of [`Defensive`] with the same rationale, for the arithmetic operations where in
/// case an infallible operation fails, it saturates.
pub trait DefensiveSaturating {
	/// Return `self` plus `other` defensively.
	fn defensive_saturating_add(self, other: Self) -> Self;
	/// Return `self` minus `other` defensively.
	fn defensive_saturating_sub(self, other: Self) -> Self;
	/// Return the product of `self` and `other` defensively.
	fn defensive_saturating_mul(self, other: Self) -> Self;
	/// Increase `self` by `other` defensively.
	fn defensive_saturating_accrue(&mut self, other: Self);
	/// Reduce `self` by `other` defensively.
	fn defensive_saturating_reduce(&mut self, other: Self);
	/// Increment `self` by one defensively.
	fn defensive_saturating_inc(&mut self);
	/// Decrement `self` by one defensively.
	fn defensive_saturating_dec(&mut self);
}

// NOTE: A bit unfortunate, since T has to be bound by all the traits needed. Could make it
// `DefensiveSaturating<T>` to mitigate.
impl<T: Saturating + CheckedAdd + CheckedMul + CheckedSub + One> DefensiveSaturating for T {
	fn defensive_saturating_add(self, other: Self) -> Self {
		self.checked_add(&other).defensive_unwrap_or_else(|| self.saturating_add(other))
	}
	fn defensive_saturating_sub(self, other: Self) -> Self {
		self.checked_sub(&other).defensive_unwrap_or_else(|| self.saturating_sub(other))
	}
	fn defensive_saturating_mul(self, other: Self) -> Self {
		self.checked_mul(&other).defensive_unwrap_or_else(|| self.saturating_mul(other))
	}
	fn defensive_saturating_accrue(&mut self, other: Self) {
		// Use `replace` here since `take` would require `T: Default`.
		*self = core::mem::replace(self, One::one()).defensive_saturating_add(other);
	}
	fn defensive_saturating_reduce(&mut self, other: Self) {
		// Use `replace` here since `take` would require `T: Default`.
		*self = core::mem::replace(self, One::one()).defensive_saturating_sub(other);
	}
	fn defensive_saturating_inc(&mut self) {
		self.defensive_saturating_accrue(One::one());
	}
	fn defensive_saturating_dec(&mut self) {
		self.defensive_saturating_reduce(One::one());
	}
/// Construct an object by defensively truncating an input if the `TryFrom` conversion fails.
pub trait DefensiveTruncateFrom<T> {
	/// Use `TryFrom` first and defensively fall back to truncating otherwise.
	///
	/// # Example
	///
	/// ```
	/// use frame_support::{BoundedVec, traits::DefensiveTruncateFrom};
	/// use sp_runtime::traits::ConstU32;
	///
	/// let unbound = vec![1, 2];
	/// let bound = BoundedVec::<u8, ConstU32<2>>::defensive_truncate_from(unbound);
	///
	/// assert_eq!(bound, vec![1, 2]);
	/// ```
	fn defensive_truncate_from(unbound: T) -> Self;
}

impl<T, U> DefensiveTruncateFrom<U> for T
where
	// NOTE: We use the fact that `BoundedVec` and
	// `BoundedSlice` use `Self` as error type. We could also
	// require a `Clone` bound and use `unbound.clone()` in the
	// error case.
	T: TruncateFrom<U> + TryFrom<U, Error = U>,
{
	fn defensive_truncate_from(unbound: U) -> Self {
		unbound.try_into().map_or_else(
			|err| {
				defensive!("DefensiveTruncateFrom truncating");
				T::truncate_from(err)
			},
			|bound| bound,
		)
	}
}

/// Defensively calculates the minimum of two values.
///
/// Can be used in contexts where we assume the receiver value to be (strictly) smaller.
pub trait DefensiveMin<T> {
	/// Returns the minimum and defensively checks that `self` is not larger than `other`.
	///
	/// # Example
	///
	/// ```
	/// use frame_support::traits::DefensiveMin;
	/// // min(3, 4) is 3.
	/// assert_eq!(3, 3_u32.defensive_min(4_u32));
	/// // min(4, 4) is 4.
	/// assert_eq!(4, 4_u32.defensive_min(4_u32));
	/// ```
	///
	/// ```#[cfg_attr(debug_assertions, should_panic)]
	/// use frame_support::traits::DefensiveMin;
	/// // min(4, 3) panics.
	/// 4_u32.defensive_min(3_u32);
	/// ```
	fn defensive_min(self, other: T) -> Self;

	/// Returns the minimum and defensively checks that `self` is smaller than `other`.
	///
	/// # Example
	///
	/// ```
	/// use frame_support::traits::DefensiveMin;
	/// // min(3, 4) is 3.
	/// assert_eq!(3, 3_u32.defensive_strict_min(4_u32));
	/// ```
	///
	/// ```#[cfg_attr(debug_assertions, should_panic)]
	/// use frame_support::traits::DefensiveMin;
	/// // min(4, 4) panics.
	/// 4_u32.defensive_strict_min(4_u32);
	/// ```
	fn defensive_strict_min(self, other: T) -> Self;
}

impl<T> DefensiveMin<T> for T
where
	T: PartialOrd<T>,
{
	fn defensive_min(self, other: T) -> Self {
		if self <= other {
			self
		} else {
			defensive!("DefensiveMin");
			other
		}
	}

	fn defensive_strict_min(self, other: T) -> Self {
		if self < other {
			self
		} else {
			defensive!("DefensiveMin strict");
			other
		}
	}
}

/// Defensively calculates the maximum of two values.
///
/// Can be used in contexts where we assume the receiver value to be (strictly) larger.
pub trait DefensiveMax<T> {
	/// Returns the maximum and defensively asserts that `other` is not larger than `self`.
	///
	/// # Example
	///
	/// ```
	/// use frame_support::traits::DefensiveMax;
	/// // max(4, 3) is 4.
	/// assert_eq!(4, 4_u32.defensive_max(3_u32));
	/// // max(4, 4) is 4.
	/// assert_eq!(4, 4_u32.defensive_max(4_u32));
	/// ```
	///
	/// ```#[cfg_attr(debug_assertions, should_panic)]
	/// use frame_support::traits::DefensiveMax;
	/// // max(4, 5) panics.
	/// 4_u32.defensive_max(5_u32);
	/// ```
	fn defensive_max(self, other: T) -> Self;

	/// Returns the maximum and defensively asserts that `other` is smaller than `self`.
	///
	/// # Example
	///
	/// ```
	/// use frame_support::traits::DefensiveMax;
	/// // y(4, 3) is 4.
	/// assert_eq!(4, 4_u32.defensive_strict_max(3_u32));
	/// ```
	///
	/// ```#[cfg_attr(debug_assertions, should_panic)]
	/// use frame_support::traits::DefensiveMax;
	/// // max(4, 4) panics.
	/// 4_u32.defensive_strict_max(4_u32);
	/// ```
	fn defensive_strict_max(self, other: T) -> Self;
}

impl<T> DefensiveMax<T> for T
where
	T: PartialOrd<T>,
{
	fn defensive_max(self, other: T) -> Self {
		if self >= other {
			self
		} else {
			defensive!("DefensiveMax");
			other
		}
	}

	fn defensive_strict_max(self, other: T) -> Self {
		if self > other {
			self
		} else {
			defensive!("DefensiveMax strict");
			other
		}
	}
}

/// Anything that can have a `::len()` method.
pub trait Len {
	/// Return the length of data type.
	fn len(&self) -> usize;
}

impl<T: IntoIterator + Clone> Len for T
where
	<T as IntoIterator>::IntoIter: ExactSizeIterator,
{
	fn len(&self) -> usize {
		self.clone().into_iter().len()
	}
}

/// A type for which some values make sense to be able to drop without further consideration.
pub trait TryDrop: Sized {
	/// Drop an instance cleanly. Only works if its value represents "no-operation".
	fn try_drop(self) -> Result<(), Self>;
}

impl TryDrop for () {
	fn try_drop(self) -> Result<(), Self> {
		Ok(())
	}
}

/// Return type used when we need to return one of two items, each of the opposite direction or
/// sign, with one (`Same`) being of the same type as the `self` or primary argument of the function
/// that returned it.
pub enum SameOrOther<A, B> {
	/// No item.
	None,
	/// An item of the same type as the `Self` on which the return function was called.
	Same(A),
	/// An item of the opposite type to the `Self` on which the return function was called.
	Other(B),
}

impl<A, B> TryDrop for SameOrOther<A, B> {
	fn try_drop(self) -> Result<(), Self> {
		if let SameOrOther::None = self {
			Ok(())
		} else {
			Err(self)
		}
	}
}

impl<A, B> SameOrOther<A, B> {
	/// Returns `Ok` with the inner value of `Same` if `self` is that, otherwise returns `Err` with
	/// `self`.
	pub fn try_same(self) -> Result<A, Self> {
		match self {
			SameOrOther::Same(a) => Ok(a),
			x => Err(x),
		}
	}

	/// Returns `Ok` with the inner value of `Other` if `self` is that, otherwise returns `Err` with
	/// `self`.
	pub fn try_other(self) -> Result<B, Self> {
		match self {
			SameOrOther::Other(b) => Ok(b),
			x => Err(x),
		}
	}

	/// Returns `Ok` if `self` is `None`, otherwise returns `Err` with `self`.
	pub fn try_none(self) -> Result<(), Self> {
		match self {
			SameOrOther::None => Ok(()),
			x => Err(x),
		}
	}

	pub fn same(self) -> Result<A, B>
	where
		A: Default,
	{
		match self {
			SameOrOther::Same(a) => Ok(a),
			SameOrOther::None => Ok(A::default()),
			SameOrOther::Other(b) => Err(b),
		}
	}

	pub fn other(self) -> Result<B, A>
	where
		B: Default,
	{
		match self {
			SameOrOther::Same(a) => Err(a),
			SameOrOther::None => Ok(B::default()),
			SameOrOther::Other(b) => Ok(b),
		}
	}
}

/// Handler for when a new account has been created.
#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
pub trait OnNewAccount<AccountId> {
	/// A new account `who` has been registered.
	fn on_new_account(who: &AccountId);
}

/// The account with the given id was reaped.
#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
pub trait OnKilledAccount<AccountId> {
	/// The account with the given id was reaped.
	fn on_killed_account(who: &AccountId);
}

/// A simple, generic one-parameter event notifier/handler.
pub trait HandleLifetime<T> {
	/// An account was created.
	fn created(_t: &T) -> Result<(), DispatchError> {
		Ok(())
	}
	fn killed(_t: &T) -> Result<(), DispatchError> {
		Ok(())
	}
}

impl<T> HandleLifetime<T> for () {}

pub trait Time {
	type Moment: sp_arithmetic::traits::AtLeast32Bit + Parameter + Default + Copy + MaxEncodedLen;

	fn now() -> Self::Moment;
}

/// Trait to deal with unix time.
pub trait UnixTime {
	/// Return duration since `SystemTime::UNIX_EPOCH`.
	fn now() -> core::time::Duration;
}

/// Trait to be used when types are exactly same.
///
/// This allow to convert back and forth from type, a reference and a mutable reference.
pub trait IsType<T>: Into<T> + From<T> {
	/// Cast reference.
	fn from_ref(t: &T) -> &Self;

	/// Cast reference.
	fn into_ref(&self) -> &T;

	/// Cast mutable reference.
	fn from_mut(t: &mut T) -> &mut Self;

	/// Cast mutable reference.
	fn into_mut(&mut self) -> &mut T;
}

impl<T> IsType<T> for T {
	fn from_ref(t: &T) -> &Self {
		t
	}
	fn into_ref(&self) -> &T {
		self
	}
	fn from_mut(t: &mut T) -> &mut Self {
		t
	}
	fn into_mut(&mut self) -> &mut T {
		self
	}
}

/// Something that can be checked to be a of sub type `T`.
///
/// This is useful for enums where each variant encapsulates a different sub type, and
/// you need access to these sub types.
///
/// For example, in FRAME, this trait is implemented for the runtime `Call` enum. Pallets use this
/// to check if a certain call is an instance of the local pallet's `Call` enum.
///
/// # Example
///
/// ```
/// # use frame_support::traits::IsSubType;
///
/// enum Test {
///     String(String),
///     U32(u32),
/// }
///
/// impl IsSubType<String> for Test {
///     fn is_sub_type(&self) -> Option<&String> {
///         match self {
///             Self::String(ref r) => Some(r),
///             _ => None,
///         }
///     }
/// }
///
/// impl IsSubType<u32> for Test {
///     fn is_sub_type(&self) -> Option<&u32> {
///         match self {
///             Self::U32(ref r) => Some(r),
///             _ => None,
///         }
///     }
/// }
///
/// fn main() {
///     let data = Test::String("test".into());
///
///     assert_eq!("test", IsSubType::<String>::is_sub_type(&data).unwrap().as_str());
/// }
/// ```
pub trait IsSubType<T> {
	/// Returns `Some(_)` if `self` is an instance of sub type `T`.
	fn is_sub_type(&self) -> Option<&T>;
}

/// Something that can execute a given block.
///
/// Executing a block means that all extrinsics in a given block will be executed and the resulting
/// header will be checked against the header of the given block.
pub trait ExecuteBlock<Block: BlockT> {
	/// Execute the given `block`.
	///
	/// This will execute all extrinsics in the block and check that the resulting header is
	/// correct.
	///
	/// # Panic
	///
	/// Panics when an extrinsics panics or the resulting header doesn't match the expected header.
	fn execute_block(block: Block);
}

/// Something that can compare privileges of two origins.
pub trait PrivilegeCmp<Origin> {
	/// Compare the `left` to the `right` origin.
	///
	/// The returned ordering should be from the pov of the `left` origin.
	///
	/// Should return `None` when it can not compare the given origins.
	fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering>;
}

/// Implementation of [`PrivilegeCmp`] that only checks for equal origins.
///
thiolliere's avatar
thiolliere committed
/// This means it will either return [`Ordering::Equal`] or `None`.
pub struct EqualPrivilegeOnly;
impl<Origin: PartialEq> PrivilegeCmp<Origin> for EqualPrivilegeOnly {
	fn cmp_privilege(left: &Origin, right: &Origin) -> Option<Ordering> {
		(left == right).then(|| Ordering::Equal)
	}
}

/// Off-chain computation trait.
///
/// Implementing this trait on a module allows you to perform long-running tasks
/// that make (by default) validators generate transactions that feed results
/// of those long-running computations back on chain.
///
/// NOTE: This function runs off-chain, so it can access the block state,
/// but cannot preform any alterations. More specifically alterations are
/// not forbidden, but they are not persisted in any way after the worker
/// has finished.
#[cfg_attr(all(not(feature = "tuples-96"), not(feature = "tuples-128")), impl_for_tuples(64))]
#[cfg_attr(all(feature = "tuples-96", not(feature = "tuples-128")), impl_for_tuples(96))]
#[cfg_attr(feature = "tuples-128", impl_for_tuples(128))]
pub trait OffchainWorker<BlockNumber> {
	/// This function is being called after every block import (when fully synced).
	///
	/// Implement this and use any of the `Offchain` `sp_io` set of APIs
	/// to perform off-chain computations, calls and submit transactions
	/// with results to trigger any on-chain changes.
	/// Any state alterations are lost and are not persisted.
	fn offchain_worker(_n: BlockNumber) {}
}

Kian Paimani's avatar
Kian Paimani committed
/// Some amount of backing from a group. The precise definition of what it means to "back" something
/// is left flexible.
pub struct Backing {
	/// The number of members of the group that back some motion.
	pub approvals: u32,
	/// The total count of group members.
	pub eligible: u32,
}

/// Retrieve the backing from an object's ref.
pub trait GetBacking {
	/// Returns `Some` `Backing` if `self` represents a fractional/groupwise backing of some
	/// implicit motion. `None` if it does not.
	fn get_backing(&self) -> Option<Backing>;
}

/// A trait to ensure the inherent are before non-inherent in a block.
///
/// This is typically implemented on runtime, through `construct_runtime!`.
pub trait EnsureInherentsAreFirst<Block: sp_runtime::traits::Block>:
	IsInherent<<Block as sp_runtime::traits::Block>::Extrinsic>
{
	/// Ensure the position of inherent is correct, i.e. they are before non-inherents.
	///
	/// On error return the index of the inherent with invalid position (counting from 0). On
	/// success it returns the index of the last inherent. `0` therefore means that there are no
	/// inherents.
	fn ensure_inherents_are_first(block: &Block) -> Result<u32, u32>;
}

/// A trait to check if an extrinsic is an inherent.
pub trait IsInherent<Extrinsic> {
	/// Whether this extrinsic is an inherent.
	fn is_inherent(ext: &Extrinsic) -> bool;
}

/// An extrinsic on which we can get access to call.
pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic {
	/// Get the call of the extrinsic.
	fn call(&self) -> &Self::Call;
}

#[cfg(feature = "std")]
impl<Call, Extra> ExtrinsicCall for sp_runtime::testing::TestXt<Call, Extra>
where
	Call: codec::Codec + Sync + Send + TypeInfo,
	Extra: TypeInfo,
{
	fn call(&self) -> &Self::Call {
		&self.call
	}
}

impl<Address, Call, Signature, Extra> ExtrinsicCall
	for sp_runtime::generic::UncheckedExtrinsic<Address, Call, Signature, Extra>
	Address: TypeInfo,
	Call: TypeInfo,
	Signature: TypeInfo,
	Extra: sp_runtime::traits::SignedExtension + TypeInfo,
{
	fn call(&self) -> &Self::Call {
		&self.function
	}
}
Kian Paimani's avatar
Kian Paimani committed

/// Something that can estimate the fee of a (frame-based) call.
///
/// Typically, the same pallet that will charge transaction fees will implement this.
pub trait EstimateCallFee<Call, Balance> {
	/// Estimate the fee of this call.
	///
	/// The dispatch info and the length is deduced from the call. The post info can optionally be
	/// provided.
	fn estimate_call_fee(call: &Call, post_info: crate::dispatch::PostDispatchInfo) -> Balance;
Kian Paimani's avatar
Kian Paimani committed
}

// Useful for building mocks.
#[cfg(feature = "std")]
impl<Call, Balance: From<u32>, const T: u32> EstimateCallFee<Call, Balance> for ConstU32<T> {
	fn estimate_call_fee(_: &Call, _: crate::dispatch::PostDispatchInfo) -> Balance {
Kian Paimani's avatar
Kian Paimani committed
		T.into()
	}
}

/// A wrapper for any type `T` which implement encode/decode in a way compatible with `Vec<u8>`.
///
/// The encoding is the encoding of `T` prepended with the compact encoding of its size in bytes.
/// Thus the encoded value can be decoded as a `Vec<u8>`.
#[derive(Debug, Eq, PartialEq, Default, Clone)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct WrapperOpaque<T>(pub T);

impl<T: Encode> EncodeLike for WrapperOpaque<T> {}
impl<T: Encode> EncodeLike<WrapperKeepOpaque<T>> for WrapperOpaque<T> {}

impl<T: Encode> Encode for WrapperOpaque<T> {
	fn size_hint(&self) -> usize {
		self.0.size_hint().saturating_add(<codec::Compact<u32>>::max_encoded_len())
	}

	fn encode_to<O: codec::Output + ?Sized>(&self, dest: &mut O) {
		self.0.encode().encode_to(dest);
	}

	fn encode(&self) -> Vec<u8> {
		self.0.encode().encode()
	}

	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
		self.0.encode().using_encoded(f)
	}
}

impl<T: Decode> Decode for WrapperOpaque<T> {
	fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {