// Copyright 2017-2019 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 rstd::prelude::*;
use rstd::{self, result, marker::PhantomData};
use runtime_io;
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
#[cfg(feature = "std")] use serde::{Serialize, Deserialize, de::DeserializeOwned};
use substrate_primitives::{self, Hasher, Blake2Hasher};
use crate::codec::{Codec, Encode, HasCompact};
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
CheckedShl, CheckedShr, Saturating
};
use rstd::ops::{
Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign,
RemAssign, Shl, Shr
};
/// 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 }
}
/// Means of signature verification.
pub trait Verify {
/// Type of the signer.
type Signer;
/// Verify a signature. Return `true` if signature is valid for the value.
fn verify>(&self, msg: L, signer: &Self::Signer) -> bool;
}
impl Verify for substrate_primitives::ed25519::Signature {
type Signer = substrate_primitives::ed25519::Public;
fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool {
runtime_io::ed25519_verify(self.as_ref(), msg.get(), signer)
}
}
impl Verify for substrate_primitives::sr25519::Signature {
type Signer = substrate_primitives::sr25519::Public;
fn verify>(&self, mut msg: L, signer: &Self::Signer) -> bool {
runtime_io::sr25519_verify(self.as_ref(), msg.get(), signer)
}
}
/// 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;
}
/// 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::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 + MaybeDebug;
/// Type to lookup into.
type Target;
/// Attempt a lookup.
fn lookup(s: Self::Source) -> result::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::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::Result { Ok(x) }
}
/// Get the "current" block number.
pub trait CurrentHeight {
/// The type of the block number.
type BlockNumber;
/// Return the current block number. Not allowed to fail.
fn current_height(&self) -> Self::BlockNumber;
}
/// Translate a block number into a hash.
pub trait BlockNumberToHash {
/// The type of the block number.
type BlockNumber: Zero;
/// The type of the hash.
type Hash: Encode;
/// Get the hash for a given block number, or `None` if unknown.
fn block_number_to_hash(&self, n: Self::BlockNumber) -> Option;
/// Get the genesis block hash; this should always be known.
fn genesis_hash(&self) -> Self::Hash {
self.block_number_to_hash(Zero::zero()).expect("All blockchains must know their genesis block hash; qed")
}
}
/// 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 }
}
/// Simple trait similar to `Into`, except that it can be used to convert numerics between each
/// other.
pub trait As {
/// Convert forward (ala `Into::into`).
fn as_(self) -> T;
/// Convert backward (ala `From::from`).
fn sa(_: T) -> Self;
}
macro_rules! impl_numerics {
( $( $t:ty ),* ) => {
$(
impl_numerics!($t: u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize,);
)*
};
( $f:ty : $t:ty, $( $rest:ty, )* ) => {
impl As<$t> for $f {
fn as_(self) -> $t { self as $t }
fn sa(t: $t) -> Self { t as Self }
}
impl_numerics!($f: $( $rest, )*);
};
( $f:ty : ) => {}
}
impl_numerics!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize);
/// A meta trait for arithmetic.
pub trait SimpleArithmetic:
Zero + One + IntegerSquareRoot + As +
Add + AddAssign +
Sub + SubAssign +
Mul + MulAssign +
Div + DivAssign +
Rem + RemAssign +
Shl + Shr +
CheckedShl +
CheckedShr +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
Saturating +
PartialOrd + Ord + Bounded +
HasCompact
{}
impl +
Add + AddAssign +
Sub + SubAssign +
Mul + MulAssign +
Div + DivAssign +
Rem + RemAssign +
Shl + Shr +
CheckedShl +
CheckedShr +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
Saturating +
PartialOrd + Ord + Bounded +
HasCompact
> SimpleArithmetic for T {}
/// 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 +
rstd::ops::BitOr +
rstd::ops::BitXor +
rstd::ops::BitAnd
{}
impl +
rstd::ops::BitXor +
rstd::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.
pub trait OnFinalize {
/// The block is being finalized. Implement to have something happen.
fn on_finalize(_n: BlockNumber) {}
}
impl OnFinalize for () {}
/// 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).
pub trait OnInitialize {
/// The block is being initialized. Implement to have something happen.
fn on_initialize(_n: BlockNumber) {}
}
impl OnInitialize for () {}
/// Off-chain computation trait.
///
/// Implementing this trait on a module allows you to perform long-running tasks
/// that make validators generate extrinsics (either transactions or inherents)
/// with the results of those long-running computations.
///
/// NOTE: This function runs off-chain, so it can access the block state,
/// but cannot preform any alterations.
pub trait OffchainWorker {
/// This function is being called on every block.
///
/// Implement this and use special `extern`s to generate transactions or inherents.
/// Any state alterations are lost and are not persisted.
fn generate_extrinsics(_n: BlockNumber) {}
}
impl OffchainWorker for () {}
macro_rules! tuple_impl {
($one:ident,) => {
impl> OnFinalize for ($one,) {
fn on_finalize(n: Number) {
$one::on_finalize(n);
}
}
impl> OnInitialize for ($one,) {
fn on_initialize(n: Number) {
$one::on_initialize(n);
}
}
impl> OffchainWorker for ($one,) {
fn generate_extrinsics(n: Number) {
$one::generate_extrinsics(n);
}
}
};
($first:ident, $($rest:ident,)+) => {
impl<
Number: Copy,
$first: OnFinalize,
$($rest: OnFinalize),+
> OnFinalize for ($first, $($rest),+) {
fn on_finalize(n: Number) {
$first::on_finalize(n);
$($rest::on_finalize(n);)+
}
}
impl<
Number: Copy,
$first: OnInitialize,
$($rest: OnInitialize),+
> OnInitialize for ($first, $($rest),+) {
fn on_initialize(n: Number) {
$first::on_initialize(n);
$($rest::on_initialize(n);)+
}
}
impl<
Number: Copy,
$first: OffchainWorker,
$($rest: OffchainWorker),+
> OffchainWorker for ($first, $($rest),+) {
fn generate_extrinsics(n: Number) {
$first::generate_extrinsics(n);
$($rest::generate_extrinsics(n);)+
}
}
tuple_impl!($($rest,)+);
}
}
#[allow(non_snake_case)]
tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,);
/// Abstraction around hashing
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived
// traits must be fulfilled by all type parameters.
/// The hash type produced.
type Output: Member + MaybeSerializeDebug + rstd::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default;
/// The associated hash_db Hasher type.
type Hasher: Hasher;
/// Produce the hash of some byte-slice.
fn hash(s: &[u8]) -> Self::Output;
/// Produce the hash of some codec-encodable value.
fn hash_of(s: &S) -> Self::Output {
Encode::using_encoded(s, Self::hash)
}
/// Produce the trie-db root of a mapping from indices to byte slices.
fn enumerated_trie_root(items: &[&[u8]]) -> Self::Output;
/// Iterator-based version of `enumerated_trie_root`.
fn ordered_trie_root<
I: IntoIterator- + Iterator
- ,
A: AsRef<[u8]>
>(input: I) -> Self::Output;
/// The Patricia tree root of the given mapping as an iterator.
fn trie_root<
I: IntoIterator
- ,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>
>(input: I) -> Self::Output;
/// Acquire the global storage root.
fn storage_root() -> Self::Output;
/// Acquire the global storage changes root.
fn storage_changes_root(parent_hash: Self::Output, parent_number: u64) -> Option;
}
/// Blake2-256 Hash implementation.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct BlakeTwo256;
impl Hash for BlakeTwo256 {
type Output = substrate_primitives::H256;
type Hasher = Blake2Hasher;
fn hash(s: &[u8]) -> Self::Output {
runtime_io::blake2_256(s).into()
}
fn enumerated_trie_root(items: &[&[u8]]) -> Self::Output {
runtime_io::enumerated_trie_root::(items).into()
}
fn trie_root<
I: IntoIterator
- ,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::trie_root::(input).into()
}
fn ordered_trie_root<
I: IntoIterator
- + Iterator
- ,
A: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::ordered_trie_root::(input).into()
}
fn storage_root() -> Self::Output {
runtime_io::storage_root().into()
}
fn storage_changes_root(parent_hash: Self::Output, parent_number: u64) -> Option {
runtime_io::storage_changes_root(parent_hash.into(), parent_number).map(Into::into)
}
}
/// 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 substrate_primitives::H256 {
#[cfg(feature = "std")]
fn check_equal(&self, other: &Self) {
use substrate_primitives::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 {
runtime_io::print("Hash not equal");
runtime_io::print(self.as_bytes());
runtime_io::print(other.as_bytes());
}
}
}
impl CheckEqual for I where I: DigestItem {
#[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 {
runtime_io::print("DigestItem not equal");
runtime_io::print(&Encode::encode(self)[..]);
runtime_io::print(&Encode::encode(other)[..]);
}
}
}
/// A type that implements Serialize and Debug when in std environment.
#[cfg(feature = "std")]
pub trait MaybeSerializeDebugButNotDeserialize: Serialize + Debug {}
#[cfg(feature = "std")]
impl MaybeSerializeDebugButNotDeserialize for T {}
/// A type that implements Serialize and Debug when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebugButNotDeserialize {}
#[cfg(not(feature = "std"))]
impl MaybeSerializeDebugButNotDeserialize for T {}
/// A type that implements Serialize when in std environment.
#[cfg(feature = "std")]
pub trait MaybeSerialize: Serialize {}
#[cfg(feature = "std")]
impl MaybeSerialize for T {}
/// A type that implements Serialize when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeSerialize {}
#[cfg(not(feature = "std"))]
impl MaybeSerialize for T {}
/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
#[cfg(feature = "std")]
pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {}
#[cfg(feature = "std")]
impl MaybeSerializeDebug for T {}
/// A type that implements Serialize, DeserializeOwned and Debug when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebug {}
#[cfg(not(feature = "std"))]
impl MaybeSerializeDebug for T {}
/// A type that implements Debug when in std environment.
#[cfg(feature = "std")]
pub trait MaybeDebug: Debug {}
#[cfg(feature = "std")]
impl MaybeDebug for T {}
/// A type that implements Debug when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeDebug {}
#[cfg(not(feature = "std"))]
impl MaybeDebug for T {}
/// A type that implements Display when in std environment.
#[cfg(feature = "std")]
pub trait MaybeDisplay: Display {}
#[cfg(feature = "std")]
impl MaybeDisplay for T {}
/// A type that implements Display when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeDisplay {}
#[cfg(not(feature = "std"))]
impl MaybeDisplay for T {}
/// A type that implements Hash when in std environment.
#[cfg(feature = "std")]
pub trait MaybeHash: ::rstd::hash::Hash {}
#[cfg(feature = "std")]
impl MaybeHash for T {}
/// A type that implements Hash when in std environment.
#[cfg(not(feature = "std"))]
pub trait MaybeHash {}
#[cfg(not(feature = "std"))]
impl MaybeHash for T {}
/// A type that can be used in runtime structures.
pub trait Member: Send + Sync + Sized + MaybeDebug + Eq + PartialEq + Clone + 'static {}
impl Member for T {}
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Digest`. 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 + MaybeSerializeDebugButNotDeserialize + 'static {
/// Header number.
type Number: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
/// Header hash type
type Hash: Member + MaybeSerializeDebug + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]> + AsMut<[u8]>;
/// Hashing algorithm
type Hashing: Hash