// Copyright 2017-2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
//! Primitives for the runtime modules.
use sp_std::prelude::*;
use sp_std::{self, result, marker::PhantomData, convert::{TryFrom, TryInto}, fmt::Debug};
use sp_io;
#[cfg(feature = "std")]
use std::fmt::Display;
#[cfg(feature = "std")]
use std::str::FromStr;
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize, de::DeserializeOwned};
use sp_core::{self, Hasher, TypeId, RuntimeDebug};
use crate::codec::{Codec, Encode, Decode};
use crate::transaction_validity::{
ValidTransaction, TransactionValidity, TransactionValidityError, UnknownTransaction,
};
use crate::generic::{Digest, DigestItem};
pub use sp_arithmetic::traits::{
AtLeast32Bit, UniqueSaturatedInto, UniqueSaturatedFrom, Saturating, SaturatedConversion,
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
CheckedShl, CheckedShr, IntegerSquareRoot
};
use sp_application_crypto::AppKey;
use impl_trait_for_tuples::impl_for_tuples;
/// A lazy value.
pub trait Lazy {
/// Get a reference to the underlying value.
///
/// This will compute the value if the function is invoked for the first time.
fn get(&mut self) -> &T;
}
impl<'a> Lazy<[u8]> for &'a [u8] {
fn get(&mut self) -> &[u8] { &**self }
}
/// Some type that is able to be collapsed into an account ID. It is not possible to recreate the
/// original value from the account ID.
pub trait IdentifyAccount {
/// The account ID that this can be transformed into.
type AccountId;
/// Transform into an account.
fn into_account(self) -> Self::AccountId;
}
impl IdentifyAccount for sp_core::ed25519::Public {
type AccountId = Self;
fn into_account(self) -> Self { self }
}
impl IdentifyAccount for sp_core::sr25519::Public {
type AccountId = Self;
fn into_account(self) -> Self { self }
}
impl IdentifyAccount for sp_core::ecdsa::Public {
type AccountId = Self;
fn into_account(self) -> Self { self }
}
/// Means of signature verification.
pub trait Verify {
/// Type of the signer.
type Signer: IdentifyAccount;
/// Verify a signature. Return `true` if signature is valid for the value.
fn verify>(&self, msg: L, signer: &::AccountId) -> bool;
}
impl Verify for sp_core::ed25519::Signature {
type Signer = sp_core::ed25519::Public;
fn verify>(&self, mut msg: L, signer: &sp_core::ed25519::Public) -> bool {
sp_io::crypto::ed25519_verify(self, msg.get(), signer)
}
}
impl Verify for sp_core::sr25519::Signature {
type Signer = sp_core::sr25519::Public;
fn verify>(&self, mut msg: L, signer: &sp_core::sr25519::Public) -> bool {
sp_io::crypto::sr25519_verify(self, msg.get(), signer)
}
}
impl Verify for sp_core::ecdsa::Signature {
type Signer = sp_core::ecdsa::Public;
fn verify>(&self, mut msg: L, signer: &sp_core::ecdsa::Public) -> bool {
match sp_io::crypto::secp256k1_ecdsa_recover_compressed(
self.as_ref(),
&sp_io::hashing::blake2_256(msg.get()),
) {
Ok(pubkey) => &signer.as_ref()[..] == &pubkey[..],
_ => false,
}
}
}
/// Means of signature verification of an application key.
pub trait AppVerify {
/// Type of the signer.
type AccountId;
/// Verify a signature. Return `true` if signature is valid for the value.
fn verify>(&self, msg: L, signer: &Self::AccountId) -> bool;
}
impl<
S: Verify::Public as sp_application_crypto::AppPublic>::Generic> + From,
T: sp_application_crypto::Wraps + sp_application_crypto::AppKey + sp_application_crypto::AppSignature +
AsRef + AsMut + From,
> AppVerify for T where
::Signer: IdentifyAccount::Signer>,
<::Public as sp_application_crypto::AppPublic>::Generic:
IdentifyAccount::Public as sp_application_crypto::AppPublic>::Generic>,
{
type AccountId = ::Public;
fn verify>(&self, msg: L, signer: &::Public) -> bool {
use sp_application_crypto::IsWrappedBy;
let inner: &S = self.as_ref();
let inner_pubkey = <::Public as sp_application_crypto::AppPublic>::Generic::from_ref(&signer);
Verify::verify(inner, msg, inner_pubkey)
}
}
/// An error type that indicates that the origin is invalid.
#[derive(Encode, Decode)]
pub struct BadOrigin;
impl From for &'static str {
fn from(_: BadOrigin) -> &'static str {
"Bad origin"
}
}
/// Some sort of check on the origin is performed by this object.
pub trait EnsureOrigin {
/// A return type.
type Success;
/// Perform the origin check.
fn ensure_origin(o: OuterOrigin) -> result::Result {
Self::try_origin(o).map_err(|_| BadOrigin)
}
/// Perform the origin check.
fn try_origin(o: OuterOrigin) -> result::Result;
}
/// An error that indicates that a lookup failed.
#[derive(Encode, Decode, RuntimeDebug)]
pub struct LookupError;
impl From for &'static str {
fn from(_: LookupError) -> &'static str {
"Can not lookup"
}
}
impl From for TransactionValidityError {
fn from(_: LookupError) -> Self {
UnknownTransaction::CannotLookup.into()
}
}
/// Means of changing one type into another in a manner dependent on the source type.
pub trait Lookup {
/// Type to lookup from.
type Source;
/// Type to lookup into.
type Target;
/// Attempt a lookup.
fn lookup(&self, s: Self::Source) -> Result;
}
/// Means of changing one type into another in a manner dependent on the source type.
/// This variant is different to `Lookup` in that it doesn't (can cannot) require any
/// context.
pub trait StaticLookup {
/// Type to lookup from.
type Source: Codec + Clone + PartialEq + Debug;
/// Type to lookup into.
type Target;
/// Attempt a lookup.
fn lookup(s: Self::Source) -> Result;
/// Convert from Target back to Source.
fn unlookup(t: Self::Target) -> Self::Source;
}
/// A lookup implementation returning the input value.
#[derive(Default)]
pub struct IdentityLookup(PhantomData);
impl StaticLookup for IdentityLookup {
type Source = T;
type Target = T;
fn lookup(x: T) -> Result { Ok(x) }
fn unlookup(x: T) -> T { x }
}
impl Lookup for IdentityLookup {
type Source = T;
type Target = T;
fn lookup(&self, x: T) -> Result { Ok(x) }
}
/// Extensible conversion trait. Generic over both source and destination types.
pub trait Convert {
/// Make conversion.
fn convert(a: A) -> B;
}
impl Convert for () {
fn convert(_: A) -> B { Default::default() }
}
/// A structure that performs identity conversion.
pub struct Identity;
impl Convert for Identity {
fn convert(a: T) -> T { a }
}
/// A structure that performs standard conversion using the standard Rust conversion traits.
pub struct ConvertInto;
impl> Convert for ConvertInto {
fn convert(a: A) -> B { a.into() }
}
/// Convenience type to work around the highly unergonomic syntax needed
/// to invoke the functions of overloaded generic traits, in this case
/// `TryFrom` and `TryInto`.
pub trait CheckedConversion {
/// Convert from a value of `T` into an equivalent instance of `Option`.
///
/// This just uses `TryFrom` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn checked_from(t: T) -> Option where Self: TryFrom {
>::try_from(t).ok()
}
/// Consume self to return `Some` equivalent value of `Option`.
///
/// This just uses `TryInto` internally but with this
/// variant you can provide the destination type using turbofish syntax
/// in case Rust happens not to assume the correct type.
fn checked_into(self) -> Option where Self: TryInto {
>::try_into(self).ok()
}
}
impl CheckedConversion for T {}
/// Multiply and divide by a number that isn't necessarily the same type. Basically just the same
/// as `Mul` and `Div` except it can be used for all basic numeric types.
pub trait Scale {
/// The output type of the product of `self` and `Other`.
type Output;
/// @return the product of `self` and `other`.
fn mul(self, other: Other) -> Self::Output;
/// @return the integer division of `self` and `other`.
fn div(self, other: Other) -> Self::Output;
/// @return the modulo remainder of `self` and `other`.
fn rem(self, other: Other) -> Self::Output;
}
macro_rules! impl_scale {
($self:ty, $other:ty) => {
impl Scale<$other> for $self {
type Output = Self;
fn mul(self, other: $other) -> Self::Output { self * (other as Self) }
fn div(self, other: $other) -> Self::Output { self / (other as Self) }
fn rem(self, other: $other) -> Self::Output { self % (other as Self) }
}
}
}
impl_scale!(u128, u128);
impl_scale!(u128, u64);
impl_scale!(u128, u32);
impl_scale!(u128, u16);
impl_scale!(u128, u8);
impl_scale!(u64, u64);
impl_scale!(u64, u32);
impl_scale!(u64, u16);
impl_scale!(u64, u8);
impl_scale!(u32, u32);
impl_scale!(u32, u16);
impl_scale!(u32, u8);
impl_scale!(u16, u16);
impl_scale!(u16, u8);
impl_scale!(u8, u8);
/// Trait for things that can be clear (have no bits set). For numeric types, essentially the same
/// as `Zero`.
pub trait Clear {
/// True iff no bits are set.
fn is_clear(&self) -> bool;
/// Return the value of Self that is clear.
fn clear() -> Self;
}
impl Clear for T {
fn is_clear(&self) -> bool { *self == Self::clear() }
fn clear() -> Self { Default::default() }
}
/// A meta trait for all bit ops.
pub trait SimpleBitOps:
Sized + Clear +
sp_std::ops::BitOr +
sp_std::ops::BitXor +
sp_std::ops::BitAnd
{}
impl +
sp_std::ops::BitXor +
sp_std::ops::BitAnd
> SimpleBitOps for T {}
/// The block finalization trait. Implementing this lets you express what should happen
/// for your module when the block is ending.
#[impl_for_tuples(30)]
pub trait OnFinalize {
/// The block is being finalized. Implement to have something happen.
fn on_finalize(_n: BlockNumber) {}
}
/// The block initialization trait. Implementing this lets you express what should happen
/// for your module when the block is beginning (right before the first extrinsic is executed).
#[impl_for_tuples(30)]
pub trait OnInitialize {
/// The block is being initialized. Implement to have something happen.
fn on_initialize(_n: BlockNumber) {}
}
/// The runtime upgrade trait. Implementing this lets you express what should happen
/// when the runtime upgrades, and changes may need to occur to your module.
#[impl_for_tuples(30)]
pub trait OnRuntimeUpgrade {
/// Perform a module upgrade.
fn on_runtime_upgrade() {}
}
/// 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.
#[impl_for_tuples(30)]
pub trait OffchainWorker {
/// 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) {}
}
/// Abstraction around hashing
// Stupid bug in the Rust compiler believes derived
// traits must be fulfilled by all type parameters.
pub trait Hash: 'static + MaybeSerializeDeserialize + Debug + Clone + Eq + PartialEq + Hasher::Output> {
/// The hash type produced.
type Output: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
+ AsRef<[u8]> + AsMut<[u8]> + Copy + Default + Encode + Decode;
/// Produce the hash of some byte-slice.
fn hash(s: &[u8]) -> Self::Output {
::hash(s)
}
/// Produce the hash of some codec-encodable value.
fn hash_of(s: &S) -> Self::Output {
Encode::using_encoded(s, ::hash)
}
/// The ordered Patricia tree root of the given `input`.
fn ordered_trie_root(input: Vec>) -> Self::Output;
/// The Patricia tree root of the given mapping.
fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output;
}
/// Blake2-256 Hash implementation.
#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BlakeTwo256;
impl Hasher for BlakeTwo256 {
type Out = sp_core::H256;
type StdHasher = hash256_std_hasher::Hash256StdHasher;
const LENGTH: usize = 32;
fn hash(s: &[u8]) -> Self::Out {
sp_io::hashing::blake2_256(s).into()
}
}
impl Hash for BlakeTwo256 {
type Output = sp_core::H256;
fn trie_root(input: Vec<(Vec, Vec)>) -> Self::Output {
sp_io::trie::blake2_256_root(input)
}
fn ordered_trie_root(input: Vec>) -> Self::Output {
sp_io::trie::blake2_256_ordered_root(input)
}
}
/// Something that can be checked for equality and printed out to a debug channel if bad.
pub trait CheckEqual {
/// Perform the equality check.
fn check_equal(&self, other: &Self);
}
impl CheckEqual for sp_core::H256 {
#[cfg(feature = "std")]
fn check_equal(&self, other: &Self) {
use sp_core::hexdisplay::HexDisplay;
if self != other {
println!(
"Hash: given={}, expected={}",
HexDisplay::from(self.as_fixed_bytes()),
HexDisplay::from(other.as_fixed_bytes()),
);
}
}
#[cfg(not(feature = "std"))]
fn check_equal(&self, other: &Self) {
if self != other {
"Hash not equal".print();
self.as_bytes().print();
other.as_bytes().print();
}
}
}
impl CheckEqual for super::generic::DigestItem where H: Encode {
#[cfg(feature = "std")]
fn check_equal(&self, other: &Self) {
if self != other {
println!("DigestItem: given={:?}, expected={:?}", self, other);
}
}
#[cfg(not(feature = "std"))]
fn check_equal(&self, other: &Self) {
if self != other {
"DigestItem not equal".print();
(&Encode::encode(self)[..]).print();
(&Encode::encode(other)[..]).print();
}
}
}
sp_core::impl_maybe_marker!(
/// A type that implements Display when in std environment.
trait MaybeDisplay: Display;
/// A type that implements FromStr when in std environment.
trait MaybeFromStr: FromStr;
/// A type that implements Hash when in std environment.
trait MaybeHash: sp_std::hash::Hash;
/// A type that implements Serialize when in std environment.
trait MaybeSerialize: Serialize;
/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
trait MaybeSerializeDeserialize: DeserializeOwned, Serialize;
/// A type that implements MallocSizeOf.
trait MaybeMallocSizeOf: parity_util_mem::MallocSizeOf;
);
/// A type that can be used in runtime structures.
pub trait Member: Send + Sync + Sized + Debug + Eq + PartialEq + Clone + 'static {}
impl Member for T {}
/// Determine if a `MemberId` is a valid member.
pub trait IsMember {
/// Is the given `MemberId` a valid member?
fn is_member(member_id: &MemberId) -> bool;
}
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Hashing`. It provides access to an `extrinsics_root`, `state_root` and
/// `parent_hash`, as well as a `digest` and a block `number`.
///
/// You can also create a `new` one from those fields.
pub trait Header:
Clone + Send + Sync + Codec + Eq + MaybeSerialize + Debug +
MaybeMallocSizeOf + 'static
{
/// Header number.
type Number: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash
+ Copy + MaybeDisplay + AtLeast32Bit + Codec + sp_std::str::FromStr
+ MaybeMallocSizeOf;
/// Header hash type
type Hash: Member + MaybeSerializeDeserialize + Debug + sp_std::hash::Hash + Ord
+ Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>
+ AsMut<[u8]> + MaybeMallocSizeOf;
/// Hashing algorithm
type Hashing: Hash