Traitify Runtime (#104)

* Factor out safe-mix and dispatch

* Refactor dispatch into something more modular.

* Fix wasm build.

* Fix up timestamp

* fix warnings.

* Borked timestamp example

* Fix build

* Timestamp as skeleton for traity runtime.

* New storage macro.

* Dispatch module has traity API.

* Move consensus module to new API

* Refactoring and outer dispatch

* Avoid unnecessary derives.

* Abstract the low-level half of system.

* nicer outer dispatch syntax.

* Make runtime compile again (albeit in a heavily simplified state)

* Reworking runtime and the upper levels of system.

* Initial reworking of runtime:

- Introduced executive module;
- Introduced trait primitives module;
- Provided an API endpoint.

* Expose an additional function in system

* Another couple of functions traitified in executive.

* another function in executive traitified.

* One more function traitified.

* Finish traitifying executive!

* Traitify session module.

* Cleanups and ensure session gets run.

* First part of traitification of staking module.

* Bit more of staking traitified.

* Additional stuff in staking. Fix up session.

* Penultimate part of staking module.

* Final part of staking (code)

* Update demo runtime to include staking.

* Final tweaks for staking integration.

* Remove old runtime files.

* Schedule staking.

* Minor fixes

* First bits of democracy.

* Democracy module integrated.

* Fix warning.

* Traitify and integrate council module

* Council voting.

* Runtime binary and tweaks.

* Binary update.

* Fix `*Type` grumble.

* Fix up genesis_map

* Remove NonTrivialSlicable

* Staking "test externalities" stuff along with refactor.

* Add session test externalities constructor

* Fixed executor tests.

* Make one test in executive module work.

* Remove test framework stuff into common module.

* Enable other tests in executive

* Session tests reinstated, minor refactoring of keyring.

* Fix staking tests.

* Fix up democracy tests.

* First few tests in council.

* Council tests reinstated :)

* Avoid hardcoding blake2 into Header.

* Fix last few tests.

* Make all primitives generic.

* Fix tests.

* Refactor runtime to remove genesismap.

* Streamline runtime more with macrofied config.

* Clean paths

* Fix warning.

* Consolidate demo runtime crate.

* Remove stale code.

* Refactor away dodgy trait.

* Add corresponding Aux type.

* Fixes

* Rename Digesty -> Digest

* Rename Headery -> Header

* Blocky -> Block

* Fix wasm build.

* kill warnings

* more docs

* minor cleanups
This commit is contained in:
Gav Wood
2018-04-04 12:06:39 +02:00
committed by GitHub
parent 3ec6d2dde6
commit bd066e27a6
92 changed files with 7890 additions and 5243 deletions
@@ -0,0 +1,28 @@
[package]
name = "substrate-runtime-primitives"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
num-traits = { version = "0.2", default_features = false }
integer-sqrt = "0.1.0"
serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
substrate-codec = { path = "../../codec", default_features = false }
substrate-primitives = { path = "../../primitives", default_features = false }
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
[features]
default = ["std"]
std = [
"num-traits/std",
"serde",
"serde_derive",
"substrate-runtime-std/std",
"substrate-runtime-io/std",
"substrate-runtime-support/std",
"substrate-codec/std",
"substrate-primitives/std",
]
@@ -0,0 +1,398 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo 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 Demo 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 Demo. If not, see <http://www.gnu.org/licenses/>.
//! Generic implementations of Extrinsic/Header/Block.
#[cfg(feature = "std")] use serde::Serialize;
use rstd::prelude::*;
use codec::{Slicable, Input};
use runtime_support::AuxDispatchable;
use traits;
use rstd::ops;
#[cfg(feature = "std")]
use std::fmt::{self, Debug};
#[cfg(feature = "std")]
pub trait MaybeSerializeDebug: Serialize + Debug {}
#[cfg(feature = "std")]
impl<T: Serialize + Debug> MaybeSerializeDebug for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebug {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebug for T {}
pub trait Member: MaybeSerializeDebug + Eq + PartialEq + Clone {}
impl<T: MaybeSerializeDebug + Eq + PartialEq + Clone> Member for T {}
/// A vetted and verified extrinsic from the external world.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
pub struct Extrinsic<AccountId, Index, Call> where
AccountId: Member,
Index: Member,
Call: Member,
{
/// Who signed it (note this is not a signature).
pub signed: AccountId,
/// The number of extrinsics have come before from the same signer.
pub index: Index,
/// The function that should be called.
pub function: Call,
}
impl<AccountId, Index, Call> Slicable for Extrinsic<AccountId, Index, Call> where
AccountId: Member + Slicable,
Index: Member + Slicable,
Call: Member + Slicable
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Extrinsic {
signed: Slicable::decode(input)?,
index: Slicable::decode(input)?,
function: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
self.signed.using_encoded(|s| v.extend(s));
self.index.using_encoded(|s| v.extend(s));
self.function.using_encoded(|s| v.extend(s));
v
}
}
/// A extrinsics right from the external world. Unchecked.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize))]
pub struct UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
/// The actual extrinsic information.
pub extrinsic: Extrinsic<AccountId, Index, Call>,
/// The signature; should be an Ed25519 signature applied to the serialised `extrinsic` field.
pub signature: Signature,
}
impl<AccountId, Index, Call, Signature> Slicable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member + Slicable,
Index: Member + Slicable,
Call: Member + Slicable,
Signature: Member + Slicable
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
// This is a little more complicated than usual since the binary format must be compatible
// with substrate's generic `Vec<u8>` type. Basically this just means accepting that there
// will be a prefix of u32, which has the total number of bytes following (we don't need
// to use this).
let _length_do_not_remove_me_see_above: u32 = Slicable::decode(input)?;
Some(UncheckedExtrinsic {
extrinsic: Slicable::decode(input)?,
signature: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
// need to prefix with the total length as u32 to ensure it's binary comptible with
// Vec<u8>. we'll make room for it here, then overwrite once we know the length.
v.extend(&[0u8; 4]);
self.extrinsic.signed.using_encoded(|s| v.extend(s));
self.extrinsic.index.using_encoded(|s| v.extend(s));
self.extrinsic.function.using_encoded(|s| v.extend(s));
self.signature.using_encoded(|s| v.extend(s));
let length = (v.len() - 4) as u32;
length.using_encoded(|s| v[0..4].copy_from_slice(s));
v
}
}
#[cfg(feature = "std")]
impl<AccountId, Index, Call, Signature> fmt::Debug for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UncheckedExtrinsic({:?})", self.extrinsic)
}
}
impl<AccountId, Index, Call, Signature> traits::Checkable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member + traits::Verify<Signer = AccountId>,
Extrinsic<AccountId, Index, Call>: Slicable
{
type Checked = CheckedExtrinsic<AccountId, Index, Call, Signature>;
fn check(self) -> Result<Self::Checked, Self> {
if ::codec::Slicable::using_encoded(&self.extrinsic, |msg|
self.signature.verify(msg, &self.extrinsic.signed)
) {
Ok(CheckedExtrinsic(self))
} else {
Err(self)
}
}
}
/// A type-safe indicator that a extrinsic has been checked.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct CheckedExtrinsic<AccountId, Index, Call, Signature>
(UncheckedExtrinsic<AccountId, Index, Call, Signature>)
where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member;
impl<AccountId, Index, Call, Signature> CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
/// Get a reference to the checked signature.
pub fn signature(&self) -> &Signature {
&self.0.signature
}
}
impl<AccountId, Index, Call, Signature> ops::Deref
for CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
type Target = Extrinsic<AccountId, Index, Call>;
fn deref(&self) -> &Self::Target {
&self.0.extrinsic
}
}
impl<AccountId, Index, Call, Signature> traits::Applyable
for CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
Call: Member + AuxDispatchable<Aux = AccountId>,
Signature: Member
{
type Index = Index;
type AccountId = AccountId;
fn index(&self) -> &Self::Index {
&self.0.extrinsic.index
}
fn sender(&self) -> &Self::AccountId {
&self.0.extrinsic.signed
}
fn apply(self) {
let xt = self.0.extrinsic;
xt.function.dispatch(&xt.signed);
}
}
#[derive(Default, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub struct Digest<Item: Member> {
pub logs: Vec<Item>,
}
impl<Item> Slicable for Digest<Item> where
Item: Member + Slicable
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Digest { logs: Slicable::decode(input)? })
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.logs.using_encoded(f)
}
}
impl<Item> traits::Digest for Digest<Item> where
Item: Member + Slicable
{
type Item = Item;
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
}
}
/// Abstraction over a block header for a substrate chain.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Header<Number, Hash, DigestItem> where
Number: Member,
Hash: Member,
DigestItem: Member,
{
/// The parent hash.
pub parent_hash: Hash,
/// The block number.
pub number: Number,
/// The state trie merkle root
pub state_root: Hash,
/// The merkle root of the extrinsics.
pub extrinsics_root: Hash,
/// A chain-specific digest of data useful for light clients or referencing auxiliary data.
pub digest: Digest<DigestItem>,
}
impl<Number, Hash, DigestItem> Slicable for Header<Number, Hash, DigestItem> where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Header {
parent_hash: Slicable::decode(input)?,
number: Slicable::decode(input)?,
state_root: Slicable::decode(input)?,
extrinsics_root: Slicable::decode(input)?,
digest: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
self.parent_hash.using_encoded(|s| v.extend(s));
self.number.using_encoded(|s| v.extend(s));
self.state_root.using_encoded(|s| v.extend(s));
self.extrinsics_root.using_encoded(|s| v.extend(s));
self.digest.using_encoded(|s| v.extend(s));
v
}
}
impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestItem> where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
{
type Number = Number;
type Hash = Hash;
type Digest = Digest<DigestItem>;
fn number(&self) -> &Self::Number { &self.number }
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self {
Header {
number, extrinsics_root: extrinsics_root, state_root, parent_hash, digest
}
}
}
/// Abstraction over a substrate block.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature> where
Number: Member,
Hash: Member,
DigestItem: Member,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
/// The block header.
pub header: Header<Number, Hash, DigestItem>,
/// The accompanying extrinsics.
pub extrinsics: Vec<UncheckedExtrinsic<AccountId, Index, Call, Signature>>,
}
impl<Number, Hash, DigestItem, AccountId, Index, Call, Signature> Slicable
for Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature>
where
Number: Member,
Hash: Member,
DigestItem: Member,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member,
Header<Number, Hash, DigestItem>: Slicable,
UncheckedExtrinsic<AccountId, Index, Call, Signature>: Slicable,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Block {
header: Slicable::decode(input)?,
extrinsics: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v: Vec<u8> = Vec::new();
v.extend(self.header.encode());
v.extend(self.extrinsics.encode());
v
}
}
impl<Number, Hash, DigestItem, AccountId, Index, Call, Signature> traits::Block
for Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature>
where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
type Extrinsic = UncheckedExtrinsic<AccountId, Index, Call, Signature>;
type Header = Header<Number, Hash, DigestItem>;
fn header(&self) -> &Self::Header {
&self.header
}
fn extrinsics(&self) -> &[Self::Extrinsic] {
&self.extrinsics[..]
}
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
(self.header, self.extrinsics)
}
}
@@ -0,0 +1,87 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo 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 Demo 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 Demo. If not, see <http://www.gnu.org/licenses/>.
//! System manager: Handles all of the top-level stuff; executing block/transaction, setting code
//! and depositing logs.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
extern crate num_traits;
extern crate integer_sqrt;
extern crate substrate_runtime_std as rstd;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_codec as codec;
extern crate substrate_primitives;
#[cfg(feature = "std")] use std::collections::HashMap;
#[cfg(feature = "std")]
pub mod testing;
pub mod traits;
pub mod generic;
#[cfg(feature = "std")]
pub type BuiltExternalities = HashMap<Vec<u8>, Vec<u8>>;
#[cfg(feature = "std")]
pub trait BuildExternalities {
fn build_externalities(self) -> BuiltExternalities;
}
#[macro_export]
macro_rules! __impl_outer_config_types {
($concrete:ident $config:ident $snake:ident $($rest:ident)*) => {
#[cfg(any(feature = "std", test))]
pub type $config = $snake::GenesisConfig<$concrete>;
__impl_outer_config_types! {$concrete $($rest)*}
};
($concrete:ident) => ()
}
#[macro_export]
/// Implement the output "meta" module configuration struct.
macro_rules! impl_outer_config {
( pub struct $main:ident for $concrete:ident { $( $config:ident => $snake:ident, )* } ) => {
__impl_outer_config_types! { $concrete $( $config $snake )* }
#[cfg(any(feature = "std", test))]
pub struct $main {
$(
pub $snake: Option<$config>,
)*
}
#[cfg(any(feature = "std", test))]
impl $crate::BuildExternalities for $main {
fn build_externalities(self) -> $crate::BuiltExternalities {
let mut s = $crate::BuiltExternalities::new();
$(
if let Some(extra) = self.$snake {
s.extend(extra.build_externalities());
}
)*
s
}
}
}
}
@@ -0,0 +1,150 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo 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 Demo 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 Demo. If not, see <http://www.gnu.org/licenses/>.
//! Testing utilities.
use serde;
use codec::{Slicable, Input};
use runtime_support::AuxDispatchable;
use substrate_primitives::H256;
use traits::{self, Checkable, Applyable};
#[derive(Default, PartialEq, Eq, Clone, Serialize, Debug)]
pub struct Digest {
pub logs: Vec<u64>,
}
impl Slicable for Digest {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Vec::<u64>::decode(input).map(|logs| Digest { logs })
}
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.logs.using_encoded(f)
}
}
impl traits::Digest for Digest {
type Item = u64;
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
pub parent_hash: H256,
pub number: u64,
pub state_root: H256,
pub extrinsics_root: H256,
pub digest: Digest,
}
impl Slicable for Header {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Header {
parent_hash: Slicable::decode(input)?,
number: Slicable::decode(input)?,
state_root: Slicable::decode(input)?,
extrinsics_root: Slicable::decode(input)?,
digest: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
self.parent_hash.using_encoded(|s| v.extend(s));
self.number.using_encoded(|s| v.extend(s));
self.state_root.using_encoded(|s| v.extend(s));
self.extrinsics_root.using_encoded(|s| v.extend(s));
self.digest.using_encoded(|s| v.extend(s));
v
}
}
impl traits::Header for Header {
type Number = u64;
type Hash = H256;
type Digest = Digest;
fn number(&self) -> &Self::Number { &self.number }
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self {
Header {
number, extrinsics_root: extrinsics_root, state_root, parent_hash, digest
}
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Debug)]
pub struct Block<Xt: Slicable + Sized + serde::Serialize> {
pub header: Header,
pub extrinsics: Vec<Xt>,
}
impl<Xt: Slicable + Sized + serde::Serialize> Slicable for Block<Xt> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Block {
header: Slicable::decode(input)?,
extrinsics: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v: Vec<u8> = Vec::new();
v.extend(self.header.encode());
v.extend(self.extrinsics.encode());
v
}
}
impl<Xt: Slicable + Sized + serde::Serialize> traits::Block for Block<Xt> {
type Extrinsic = Xt;
type Header = Header;
fn header(&self) -> &Self::Header {
&self.header
}
fn extrinsics(&self) -> &[Self::Extrinsic] {
&self.extrinsics[..]
}
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
(self.header, self.extrinsics)
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Debug)]
pub struct TestXt<Call: AuxDispatchable + Slicable + Sized + serde::Serialize>(pub (u64, u64, Call));
impl<Call: AuxDispatchable + Slicable + Sized + serde::Serialize> Slicable for TestXt<Call> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(TestXt(Slicable::decode(input)?))
}
fn encode(&self) -> Vec<u8> {
self.0.encode()
}
}
impl<Call: AuxDispatchable + Slicable + Sized + serde::Serialize> Checkable for TestXt<Call> {
type Checked = Self;
fn check(self) -> Result<Self, Self> { Ok(self) }
}
impl<Call: AuxDispatchable<Aux = u64> + Slicable + Sized + serde::Serialize> Applyable for TestXt<Call> {
type AccountId = u64;
type Index = u64;
fn sender(&self) -> &u64 { &(self.0).0 }
fn index(&self) -> &u64 { &(self.0).1 }
fn apply(self) { (self.0).2.dispatch(&(self.0).0); }
}
@@ -0,0 +1,293 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Substrate Demo.
// Substrate Demo 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 Demo 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 Demo. If not, see <http://www.gnu.org/licenses/>.
//! Primitives for the runtime modules.
use rstd::prelude::*;
use rstd;
#[cfg(not(feature = "std"))] use runtime_io;
use substrate_primitives;
use codec::{Input, Slicable};
use substrate_primitives::hash::H512;
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{Zero, One, Bounded};
use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
/// Means of signature verification.
pub trait Verify {
/// Type of the signer.
type Signer;
/// Verify a signature.
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool;
}
/// Ed25519 signature verify.
#[derive(Eq, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub struct Ed25519Signature(H512);
impl Verify for Ed25519Signature {
type Signer = [u8; 32];
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool {
::runtime_io::ed25519_verify(&(self.0).0, msg, &signer[..])
}
}
impl Slicable for Ed25519Signature {
fn decode<I: Input>(input: &mut I) -> Option<Self> { Some(Ed25519Signature(Slicable::decode(input)?,)) }
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { self.0.using_encoded(f) }
}
impl From<H512> for Ed25519Signature {
fn from(h: H512) -> Ed25519Signature {
Ed25519Signature(h)
}
}
/// Simple payment making trait, operating on a single generic `AccountId` type.
pub trait MakePayment<AccountId> {
/// Make some sort of payment concerning `who`.
fn make_payment(who: &AccountId);
}
impl<T> MakePayment<T> for () {
fn make_payment(_: &T) {}
}
/// Extensible conversion trait. Generic over both source and destination types.
pub trait Convert<A, B> {
/// Make conversion.
fn convert(a: A) -> B;
}
/// Simple trait similar to `Into`, except that it can be used to convert numerics between each
/// other.
pub trait As<T> {
/// 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, usize, i8, i16, i32, i64, 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, usize, i8, i16, i32, i64, isize);
pub struct Identity;
impl<T> Convert<T, T> for Identity {
fn convert(a: T) -> T { a }
}
pub trait HasPublicAux {
type PublicAux;
}
pub trait RefInto<T> {
fn ref_into(&self) -> &T;
}
impl<T> RefInto<T> for T {
fn ref_into(&self) -> &T { &self }
}
pub trait SimpleArithmetic:
Zero + One + IntegerSquareRoot + As<usize> +
Add<Self, Output = Self> + AddAssign<Self> +
Sub<Self, Output = Self> + SubAssign<Self> +
Mul<Self, Output = Self> + MulAssign<Self> +
Div<Self, Output = Self> + DivAssign<Self> +
Rem<Self, Output = Self> + RemAssign<Self> +
PartialOrd<Self> + Ord
{}
impl<T:
Zero + One + IntegerSquareRoot + As<usize> +
Add<Self, Output = Self> + AddAssign<Self> +
Sub<Self, Output = Self> + SubAssign<Self> +
Mul<Self, Output = Self> + MulAssign<Self> +
Div<Self, Output = Self> + DivAssign<Self> +
Rem<Self, Output = Self> + RemAssign<Self> +
PartialOrd<Self> + Ord
> SimpleArithmetic for T {}
pub trait SimpleBitOps:
Sized +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
{}
impl<T:
Sized +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
> SimpleBitOps for T {}
/// Something that can be executed.
pub trait Executable {
fn execute();
}
impl Executable for () {
fn execute() {}
}
impl<A: Executable, B: Executable> Executable for (A, B) {
fn execute() {
A::execute();
B::execute();
}
}
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Slicable`.
pub trait Digest {
type Item: Sized;
fn push(&mut self, item: Self::Item);
}
impl Digest for substrate_primitives::Digest {
type Item = substrate_primitives::block::Log;
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
}
}
/// 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: Sized + Slicable {
type Number: Sized;
type Hash: Sized;
type Digest: Sized;
fn number(&self) -> &Self::Number;
fn extrinsics_root(&self) -> &Self::Hash;
fn state_root(&self) -> &Self::Hash;
fn parent_hash(&self) -> &Self::Hash;
fn digest(&self) -> &Self::Digest;
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self;
}
impl Header for substrate_primitives::Header {
type Number = substrate_primitives::block::Number;
type Hash = substrate_primitives::block::HeaderHash;
type Digest = substrate_primitives::block::Digest;
fn number(&self) -> &Self::Number { &self.number }
fn extrinsics_root(&self) -> &Self::Hash { &self.transaction_root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self {
substrate_primitives::Header {
number: number,
transaction_root: extrinsics_root,
state_root: state_root,
parent_hash: parent_hash,
digest: digest,
}
}
}
/// Something which fulfills the abstract idea of a Substrate block. It has types for an
/// `Extrinsic` piece of information as well as a `Header`.
///
/// You can get an iterator over each of the `extrinsics` and retrieve the `header`.
pub trait Block {
type Extrinsic: Sized;
type Header: Header;
fn header(&self) -> &Self::Header;
fn extrinsics(&self) -> &[Self::Extrinsic];
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>);
}
impl Block for substrate_primitives::Block {
type Extrinsic = substrate_primitives::block::Transaction;
type Header = substrate_primitives::Header;
fn header(&self) -> &Self::Header {
&self.header
}
fn extrinsics(&self) -> &[Self::Extrinsic] {
&self.transactions[..]
}
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
(self.header, self.transactions)
}
}
/// A "checkable" piece of information, used by the standard Substrate Executive in order to
/// check the validity of a piece of extrinsic information, usually by verifying the signature.
pub trait Checkable: Sized {
type Checked: Sized;
fn check(self) -> Result<Self::Checked, Self>;
}
/// An "executable" piece of information, used by the standard Substrate Executive in order to
/// enact a piece of extrinsic information by marshalling and dispatching to a named functioon
/// call.
///
/// Also provides information on to whom this information is attributable and an index that allows
/// each piece of attributable information to be disambiguated.
pub trait Applyable {
type AccountId;
type Index;
fn index(&self) -> &Self::Index;
fn sender(&self) -> &Self::AccountId;
fn apply(self);
}
/// Something that can be checked for equality and printed out to a debug channel if bad.
pub trait CheckEqual {
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.0 != &other.0 {
println!("Hash: given={}, expected={}", HexDisplay::from(&self.0), HexDisplay::from(&other.0));
}
}
#[cfg(not(feature = "std"))]
fn check_equal(&self, other: &Self) {
if self != other {
runtime_io::print("Hash not equal");
runtime_io::print(&self.0[..]);
runtime_io::print(&other.0[..]);
}
}
}