Phase 1 of repo reorg (#719)

* Remove unneeded script

* Rename Substrate Demo -> Substrate

* Rename demo -> node

* Build wasm from last rename.

* Merge ed25519 into substrate-primitives

* Minor tweak

* Rename substrate -> core

* Move substrate-runtime-support to core/runtime/support

* Rename/move substrate-runtime-version

* Move codec up a level

* Rename substrate-codec -> parity-codec

* Move environmental up a level

* Move pwasm-* up to top, ready for removal

* Remove requirement of s-r-support from s-r-primitives

* Move core/runtime/primitives into core/runtime-primitives

* Remove s-r-support dep from s-r-version

* Remove dep of s-r-support from bft

* Remove dep of s-r-support from node/consensus

* Sever all other core deps from s-r-support

* Forgot the no_std directive

* Rename non-SRML modules to sr-* to avoid match clashes

* Move runtime/* to srml/*

* Rename substrate-runtime-* -> srml-*

* Move srml to top-level
This commit is contained in:
Gav Wood
2018-09-12 11:13:31 +02:00
committed by Arkadiy Paronyan
parent 8fe5aa4c81
commit 1e01162505
374 changed files with 2845 additions and 2902 deletions
+195
View File
@@ -0,0 +1,195 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Message formats for the BFT consensus layer.
use rstd::prelude::*;
use codec::{Decode, Encode, Input, Output};
use substrate_primitives::{AuthorityId, Signature};
/// Type alias for extracting message type from block.
pub type ActionFor<B> = Action<B, <B as ::traits::Block>::Hash>;
/// Actions which can be taken during the BFT process.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub enum Action<Block, H> {
/// Proposal of a block candidate.
#[codec(index = "1")]
Propose(u32, Block),
/// Proposal header of a block candidate. Accompanies any proposal,
/// but is used for misbehavior reporting since blocks themselves are big.
#[codec(index = "2")]
ProposeHeader(u32, H),
/// Preparation to commit for a candidate.
#[codec(index = "3")]
Prepare(u32, H),
/// Vote to commit to a candidate.
#[codec(index = "4")]
Commit(u32, H),
/// Vote to advance round after inactive primary.
#[codec(index = "5")]
AdvanceRound(u32),
}
/// Type alias for extracting message type from block.
pub type MessageFor<B> = Message<B, <B as ::traits::Block>::Hash>;
/// Messages exchanged between participants in the BFT consensus.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Message<Block, Hash> {
/// The parent header hash this action is relative to.
pub parent: Hash,
/// The action being broadcasted.
pub action: Action<Block, Hash>,
}
/// Justification of a block.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Justification<H> {
/// The round consensus was reached in.
pub round_number: u32,
/// The hash of the header justified.
pub hash: H,
/// The signatures and signers of the hash.
pub signatures: Vec<(AuthorityId, Signature)>
}
// single-byte code to represent misbehavior kind.
#[repr(i8)]
enum MisbehaviorCode {
/// BFT: double prepare.
BftDoublePrepare = 0x11,
/// BFT: double commit.
BftDoubleCommit = 0x12,
}
impl MisbehaviorCode {
fn from_i8(x: i8) -> Option<Self> {
match x {
0x11 => Some(MisbehaviorCode::BftDoublePrepare),
0x12 => Some(MisbehaviorCode::BftDoubleCommit),
_ => None,
}
}
}
/// Misbehavior kinds.
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub enum MisbehaviorKind<Hash> {
/// BFT: double prepare.
BftDoublePrepare(u32, (Hash, Signature), (Hash, Signature)),
/// BFT: double commit.
BftDoubleCommit(u32, (Hash, Signature), (Hash, Signature)),
}
impl<Hash: Encode> Encode for MisbehaviorKind<Hash> {
fn encode_to<T: Output>(&self, dest: &mut T) {
match *self {
MisbehaviorKind::BftDoublePrepare(ref round, (ref h_a, ref s_a), (ref h_b, ref s_b)) => {
dest.push(&(MisbehaviorCode::BftDoublePrepare as i8));
dest.push(round);
dest.push(h_a);
dest.push(s_a);
dest.push(h_b);
dest.push(s_b);
}
MisbehaviorKind::BftDoubleCommit(ref round, (ref h_a, ref s_a), (ref h_b, ref s_b)) => {
dest.push(&(MisbehaviorCode::BftDoubleCommit as i8));
dest.push(round);
dest.push(h_a);
dest.push(s_a);
dest.push(h_b);
dest.push(s_b);
}
}
}
}
impl<Hash: Decode> Decode for MisbehaviorKind<Hash> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(match i8::decode(input).and_then(MisbehaviorCode::from_i8)? {
MisbehaviorCode::BftDoublePrepare => {
MisbehaviorKind::BftDoublePrepare(
u32::decode(input)?,
(Hash::decode(input)?, Signature::decode(input)?),
(Hash::decode(input)?, Signature::decode(input)?),
)
}
MisbehaviorCode::BftDoubleCommit => {
MisbehaviorKind::BftDoubleCommit(
u32::decode(input)?,
(Hash::decode(input)?, Signature::decode(input)?),
(Hash::decode(input)?, Signature::decode(input)?),
)
}
})
}
}
/// A report of misbehavior by an authority.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct MisbehaviorReport<Hash, Number> {
/// The parent hash of the block where the misbehavior occurred.
pub parent_hash: Hash,
/// The parent number of the block where the misbehavior occurred.
pub parent_number: Number,
/// The authority who misbehavior.
pub target: AuthorityId,
/// The misbehavior kind.
pub misbehavior: MisbehaviorKind<Hash>,
}
#[cfg(test)]
mod test {
use super::*;
use substrate_primitives::H256;
#[test]
fn misbehavior_report_roundtrip() {
let report = MisbehaviorReport::<H256, u64> {
parent_hash: [0; 32].into(),
parent_number: 999,
target: [1; 32].into(),
misbehavior: MisbehaviorKind::BftDoubleCommit(
511,
([2; 32].into(), [3; 64].into()),
([4; 32].into(), [5; 64].into()),
),
};
let encoded = report.encode();
assert_eq!(MisbehaviorReport::<H256, u64>::decode(&mut &encoded[..]).unwrap(), report);
let report = MisbehaviorReport::<H256, u64> {
parent_hash: [0; 32].into(),
parent_number: 999,
target: [1; 32].into(),
misbehavior: MisbehaviorKind::BftDoublePrepare(
511,
([2; 32].into(), [3; 64].into()),
([4; 32].into(), [5; 64].into()),
),
};
let encoded = report.encode();
assert_eq!(MisbehaviorReport::<H256, u64>::decode(&mut &encoded[..]).unwrap(), report);
}
}
@@ -0,0 +1,105 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Generic implementation of a block and associated items.
#[cfg(feature = "std")]
use std::fmt;
use rstd::prelude::*;
use codec::Codec;
use traits::{self, Member, Block as BlockT, Header as HeaderT};
use bft::Justification;
/// Something to identify a 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 enum BlockId<Block: BlockT> {
/// Identify by block header hash.
Hash(<<Block as BlockT>::Header as HeaderT>::Hash),
/// Identify by block number.
Number(<<Block as BlockT>::Header as HeaderT>::Number),
}
impl<Block: BlockT> BlockId<Block> {
/// Create a block ID from a hash.
pub fn hash(hash: Block::Hash) -> Self {
BlockId::Hash(hash)
}
/// Create a block ID from a number.
pub fn number(number: <Block::Header as HeaderT>::Number) -> Self {
BlockId::Number(number)
}
}
impl<Block: BlockT> Copy for BlockId<Block> {}
#[cfg(feature = "std")]
impl<Block: BlockT> fmt::Display for BlockId<Block> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{:?}", self)
}
}
/// Abstraction over a substrate block.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Block<Header, Extrinsic> {
/// The block header.
pub header: Header,
/// The accompanying extrinsics.
pub extrinsics: Vec<Extrinsic>,
}
impl<Header, Extrinsic> traits::Block for Block<Header, Extrinsic>
where
Header: HeaderT,
Extrinsic: Member + Codec,
{
type Extrinsic = Extrinsic;
type Header = Header;
type Hash = <Self::Header as traits::Header>::Hash;
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)
}
fn new(header: Self::Header, extrinsics: Vec<Self::Extrinsic>) -> Self {
Block { header, extrinsics }
}
}
/// Abstraction over a substrate block and justification.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct SignedBlock<Header, Extrinsic, Hash> {
/// Full block.
pub block: Block<Header, Extrinsic>,
/// Block header justification.
pub justification: Justification<Hash>,
}
@@ -0,0 +1,58 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Generic implementation of an extrinsic that has passed the verification
//! stage.
use traits::{self, Member, SimpleArithmetic, MaybeDisplay};
/// Definition of something that the external world might want to say; its
/// existence implies that it has been checked and is good, particularly with
/// regards to the signature.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct CheckedExtrinsic<AccountId, Index, Call> {
/// Who this purports to be from, if anyone (note this is not a signature).
pub signed: Option<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> traits::Applyable
for CheckedExtrinsic<AccountId, Index, Call>
where
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member
{
type Index = Index;
type AccountId = AccountId;
type Call = Call;
fn index(&self) -> &Self::Index {
&self.index
}
fn sender(&self) -> Option<&Self::AccountId> {
self.signed.as_ref()
}
fn deconstruct(self) -> (Self::Call, Option<Self::AccountId>) {
(self.function, self.signed)
}
}
@@ -0,0 +1,150 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Generic implementation of a digest.
use rstd::prelude::*;
use codec::{Decode, Encode, Codec, Input};
use traits::{self, Member, DigestItem as DigestItemT};
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Digest<Item> {
pub logs: Vec<Item>,
}
impl<Item> Default for Digest<Item> {
fn default() -> Self {
Digest { logs: Vec::new(), }
}
}
impl<Item> traits::Digest for Digest<Item> where
Item: DigestItemT + Codec
{
type Item = Item;
fn logs(&self) -> &[Self::Item] {
&self.logs
}
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
}
}
/// Digest item that is able to encode/decode 'system' digest items and
/// provide opaque access to other items.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub enum DigestItem<AuthorityId> {
/// System digest item announcing that authorities set has been changed
/// in the block. Contains the new set of authorities.
AuthoritiesChange(Vec<AuthorityId>),
/// Any 'non-system' digest item, opaque to the native code.
Other(Vec<u8>),
}
/// A 'referencing view' for digest item. Does not own its contents. Used by
/// final runtime implementations for encoding/decoding its log items.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum DigestItemRef<'a, AuthorityId: 'a> {
/// Reference to `DigestItem::AuthoritiesChange`.
AuthoritiesChange(&'a [AuthorityId]),
/// Reference to `DigestItem::Other`.
Other(&'a Vec<u8>),
}
/// Type of the digest item. Used to gain explicit control over `DigestItem` encoding
/// process. We need an explicit control, because final runtimes are encoding their own
/// digest items using `DigestItemRef` type and we can't auto-derive `Decode`
/// trait for `DigestItemRef`.
#[repr(u32)]
#[derive(Encode, Decode)]
enum DigestItemType {
Other = 0,
AuthoritiesChange,
}
impl<AuthorityId> DigestItem<AuthorityId> {
/// Returns Some if `self` is a `DigestItem::Other`.
pub fn as_other(&self) -> Option<&Vec<u8>> {
match *self {
DigestItem::Other(ref v) => Some(v),
_ => None,
}
}
/// Returns a 'referencing view' for this digest item.
fn dref<'a>(&'a self) -> DigestItemRef<'a, AuthorityId> {
match *self {
DigestItem::AuthoritiesChange(ref v) => DigestItemRef::AuthoritiesChange(v),
DigestItem::Other(ref v) => DigestItemRef::Other(v),
}
}
}
impl<AuthorityId: Member> traits::DigestItem for DigestItem<AuthorityId> {
type AuthorityId = AuthorityId;
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> {
match *self {
DigestItem::AuthoritiesChange(ref authorities) => Some(authorities),
_ => None,
}
}
}
impl<AuthorityId: Encode> Encode for DigestItem<AuthorityId> {
fn encode(&self) -> Vec<u8> {
self.dref().encode()
}
}
impl<AuthorityId: Decode> Decode for DigestItem<AuthorityId> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
let item_type: DigestItemType = Decode::decode(input)?;
match item_type {
DigestItemType::AuthoritiesChange => Some(DigestItem::AuthoritiesChange(
Decode::decode(input)?,
)),
DigestItemType::Other => Some(DigestItem::Other(
Decode::decode(input)?,
)),
}
}
}
impl<'a, AuthorityId: Encode> Encode for DigestItemRef<'a, AuthorityId> {
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
match *self {
DigestItemRef::AuthoritiesChange(authorities) => {
DigestItemType::AuthoritiesChange.encode_to(&mut v);
authorities.encode_to(&mut v);
},
DigestItemRef::Other(val) => {
DigestItemType::Other.encode_to(&mut v);
val.encode_to(&mut v);
},
}
v
}
}
@@ -0,0 +1,167 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Generic implementation of a block header.
#[cfg(feature = "std")]
use serde::{Deserialize, Deserializer};
use codec::{Decode, Encode, Codec, Input, Output};
use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay,
Hash as HashT, DigestItem as DigestItemT};
use generic::Digest;
/// 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: HashT, DigestItem> {
/// The parent hash.
pub parent_hash: <Hash as HashT>::Output,
/// The block number.
pub number: Number,
/// The state trie merkle root
pub state_root: <Hash as HashT>::Output,
/// The merkle root of the extrinsics.
pub extrinsics_root: <Hash as HashT>::Output,
/// A chain-specific digest of data useful for light clients or referencing auxiliary data.
pub digest: Digest<DigestItem>,
}
// Hack to work around the fact that deriving deserialize doesn't work nicely with
// the `hashing` trait used as a parameter.
// dummy struct that uses the hash type directly.
// https://github.com/serde-rs/serde/issues/1296
#[cfg(feature = "std")]
#[serde(rename_all = "camelCase")]
#[derive(Deserialize)]
struct DeserializeHeader<N, H, D> {
parent_hash: H,
number: N,
state_root: H,
extrinsics_root: H,
digest: Digest<D>,
}
#[cfg(feature = "std")]
impl<N, D, Hash: HashT> From<DeserializeHeader<N, Hash::Output, D>> for Header<N, Hash, D> {
fn from(other: DeserializeHeader<N, Hash::Output, D>) -> Self {
Header {
parent_hash: other.parent_hash,
number: other.number,
state_root: other.state_root,
extrinsics_root: other.extrinsics_root,
digest: other.digest,
}
}
}
#[cfg(feature = "std")]
impl<'a, Number: 'a, Hash: 'a + HashT, DigestItem: 'a> Deserialize<'a> for Header<Number, Hash, DigestItem> where
Number: Deserialize<'a>,
Hash::Output: Deserialize<'a>,
DigestItem: Deserialize<'a>,
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
DeserializeHeader::<Number, Hash::Output, DigestItem>::deserialize(de).map(Into::into)
}
}
// TODO [ToDr] Issue with bounds
impl<Number, Hash, DigestItem> Decode for Header<Number, Hash, DigestItem> where
Number: Decode,
Hash: HashT,
Hash::Output: Decode,
DigestItem: DigestItemT + Decode,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Header {
parent_hash: Decode::decode(input)?,
number: Decode::decode(input)?,
state_root: Decode::decode(input)?,
extrinsics_root: Decode::decode(input)?,
digest: Decode::decode(input)?,
})
}
}
impl<Number, Hash, DigestItem> Encode for Header<Number, Hash, DigestItem> where
Number: Encode,
Hash: HashT,
Hash::Output: Encode,
DigestItem: DigestItemT + Encode,
{
fn encode_to<T: Output>(&self, dest: &mut T) {
dest.push(&self.parent_hash);
dest.push(&self.number);
dest.push(&self.state_root);
dest.push(&self.extrinsics_root);
dest.push(&self.digest);
}
}
impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestItem> where
Number: Member + ::rstd::hash::Hash + Copy + Codec + MaybeDisplay + SimpleArithmetic + Codec,
Hash: HashT,
DigestItem: DigestItemT + Codec,
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
{
type Number = Number;
type Hash = <Hash as HashT>::Output;
type Hashing = Hash;
type Digest = Digest<DigestItem>;
fn number(&self) -> &Self::Number { &self.number }
fn set_number(&mut self, num: Self::Number) { self.number = num }
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn set_extrinsics_root(&mut self, root: Self::Hash) { self.extrinsics_root = root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn set_state_root(&mut self, root: Self::Hash) { self.state_root = root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn set_parent_hash(&mut self, hash: Self::Hash) { self.parent_hash = hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn set_digest(&mut self, digest: Self::Digest) { self.digest = 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
}
}
}
impl<Number, Hash, DigestItem> Header<Number, Hash, DigestItem> where
Number: Member + ::rstd::hash::Hash + Copy + Codec + MaybeDisplay + SimpleArithmetic + Codec,
Hash: HashT,
DigestItem: DigestItemT + Codec,
Hash::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Codec,
{
/// Convenience helper for computing the hash of the header without having
/// to import the trait.
pub fn hash(&self) -> Hash::Output {
Hash::hash_of(self)
}
}
@@ -0,0 +1,33 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
// tag::description[]
//! Generic implementations of Extrinsic/Header/Block.
// end::description[]
mod unchecked_extrinsic;
mod checked_extrinsic;
mod header;
mod block;
mod digest;
#[cfg(test)]
mod tests;
pub use self::unchecked_extrinsic::UncheckedExtrinsic;
pub use self::checked_extrinsic::CheckedExtrinsic;
pub use self::header::Header;
pub use self::block::{Block, SignedBlock, BlockId};
pub use self::digest::{Digest, DigestItem, DigestItemRef};
@@ -0,0 +1,105 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Tests for the generic implementations of Extrinsic/Header/Block.
use codec::{Decode, Encode};
use substrate_primitives::{H256, H512};
use super::{Digest, Header, DigestItem, UncheckedExtrinsic};
type Block = super::Block<
Header<u64, ::traits::BlakeTwo256, DigestItem<u32>>,
UncheckedExtrinsic<H256, u64, u64, ::Ed25519Signature>,
>;
#[test]
fn block_roundtrip_serialization() {
let block: Block = Block {
header: Header {
parent_hash: [0u8; 32].into(),
number: 100_000,
state_root: [1u8; 32].into(),
extrinsics_root: [2u8; 32].into(),
digest: Digest { logs: vec![
DigestItem::Other::<u32>(vec![1, 2, 3]),
DigestItem::Other::<u32>(vec![4, 5, 6]),
] },
},
extrinsics: vec![
UncheckedExtrinsic::new_signed(
0,
100,
[255u8; 32].into(),
H512::from([0u8; 64]).into()
),
UncheckedExtrinsic::new_signed(
100,
99,
[128u8; 32].into(),
H512::from([255u8; 64]).into()
)
]
};
{
let encoded = ::serde_json::to_vec(&block).unwrap();
let decoded: Block = ::serde_json::from_slice(&encoded).unwrap();
assert_eq!(block, decoded);
}
{
let encoded = block.encode();
let decoded = Block::decode(&mut &encoded[..]).unwrap();
assert_eq!(block, decoded);
}
}
#[test]
fn system_digest_item_encoding() {
let item = DigestItem::AuthoritiesChange::<u32>(vec![10, 20, 30]);
let encoded = item.encode();
assert_eq!(encoded, vec![
// type = DigestItemType::AuthoritiesChange
1,
// number of items in athorities set
3, 0, 0, 0,
// authorities
10, 0, 0, 0,
20, 0, 0, 0,
30, 0, 0, 0,
]);
let decoded: DigestItem<u32> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}
#[test]
fn non_system_digest_item_encoding() {
let item = DigestItem::Other::<u32>(vec![10, 20, 30]);
let encoded = item.encode();
assert_eq!(encoded, vec![
// type = DigestItemType::Other
0,
// length of other data
3, 0, 0, 0,
// authorities
10, 20, 30,
]);
let decoded: DigestItem<u32> = Decode::decode(&mut &encoded[..]).unwrap();
assert_eq!(item, decoded);
}
@@ -0,0 +1,159 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Generic implementation of an unchecked (pre-verification) extrinsic.
#[cfg(feature = "std")]
use std::fmt;
use rstd::prelude::*;
use codec::{Decode, Encode, Input};
use traits::{self, Member, SimpleArithmetic, MaybeDisplay};
use super::CheckedExtrinsic;
/// A extrinsic right from the external world. This is unchecked and so
/// can contain a signature.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct UncheckedExtrinsic<Address, Index, Call, Signature> {
/// The signature and address, if this is a signed extrinsic.
pub signature: Option<(Address, Signature)>,
/// The number of extrinsics have come before from the same signer.
pub index: Index,
/// The function that should be called.
pub function: Call,
}
impl<Address, Index, Call, Signature> UncheckedExtrinsic<Address, Index, Call, Signature> {
/// New instance of a signed extrinsic aka "transaction".
pub fn new_signed(index: Index, function: Call, signed: Address, signature: Signature) -> Self {
UncheckedExtrinsic {
signature: Some((signed, signature)),
index,
function,
}
}
/// New instance of an unsigned extrinsic aka "inherent".
pub fn new_unsigned(index: Index, function: Call) -> Self {
UncheckedExtrinsic {
signature: None,
index,
function,
}
}
/// `true` if there is a signature.
pub fn is_signed(&self) -> bool {
self.signature.is_some()
}
}
impl<Address, AccountId, Index, Call, Signature, ThisLookup> traits::Checkable<ThisLookup>
for UncheckedExtrinsic<Address, Index, Call, Signature>
where
Address: Member + MaybeDisplay,
Index: Encode + Member + MaybeDisplay + SimpleArithmetic,
Call: Encode + Member,
Signature: Member + traits::Verify<Signer=AccountId>,
AccountId: Member + MaybeDisplay,
ThisLookup: FnOnce(Address) -> Result<AccountId, &'static str>,
{
type Checked = CheckedExtrinsic<AccountId, Index, Call>;
fn check_with(self, lookup: ThisLookup) -> Result<Self::Checked, &'static str> {
Ok(match self.signature {
Some((signed, signature)) => {
let payload = (self.index, self.function);
let signed = lookup(signed)?;
if !::verify_encoded_lazy(&signature, &payload, &signed) {
return Err("bad signature in extrinsic")
}
CheckedExtrinsic {
signed: Some(signed),
index: payload.0,
function: payload.1,
}
}
None => CheckedExtrinsic {
signed: None,
index: self.index,
function: self.function,
},
})
}
}
impl<Address, Index, Call, Signature> Decode
for UncheckedExtrinsic<Address, Index, Call, Signature>
where
Address: Decode,
Signature: Decode,
Index: Decode,
Call: Decode,
{
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 = Decode::decode(input)?;
Some(UncheckedExtrinsic {
signature: Decode::decode(input)?,
index: Decode::decode(input)?,
function: Decode::decode(input)?,
})
}
}
impl<Address, Index, Call, Signature> Encode
for UncheckedExtrinsic<Address, Index, Call, Signature>
where
Address: Encode,
Signature: Encode,
Index: Encode,
Call: Encode,
{
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.signature.encode_to(&mut v);
self.index.encode_to(&mut v);
self.function.encode_to(&mut v);
let length = (v.len() - 4) as u32;
length.using_encoded(|s| v[0..4].copy_from_slice(s));
v
}
}
/// TODO: use derive when possible.
#[cfg(feature = "std")]
impl<Address, Index, Call, Signature> fmt::Debug for UncheckedExtrinsic<Address, Index, Call, Signature> where
Address: fmt::Debug,
Index: fmt::Debug,
Call: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UncheckedExtrinsic({:?}, {:?}, {:?})", self.signature.as_ref().map(|x| &x.0), self.function, self.index)
}
}
+433
View File
@@ -0,0 +1,433 @@
// Copyright 2017 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 <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;
#[cfg(feature = "std")]
#[macro_use]
extern crate log;
#[macro_use]
extern crate parity_codec_derive;
extern crate num_traits;
extern crate integer_sqrt;
extern crate sr_std as rstd;
extern crate sr_io as runtime_io;
extern crate parity_codec as codec;
extern crate substrate_primitives;
#[cfg(test)]
extern crate serde_json;
#[cfg(feature = "std")]
use std::collections::HashMap;
use rstd::prelude::*;
use substrate_primitives::hash::{H256, H512};
#[cfg(feature = "std")]
use substrate_primitives::hexdisplay::ascii_format;
#[cfg(feature = "std")]
pub mod testing;
pub mod traits;
pub mod generic;
pub mod bft;
use traits::{Verify, Lazy};
#[cfg(feature = "std")]
pub use serde::{Serialize, de::DeserializeOwned};
/// A set of key value pairs for storage.
#[cfg(feature = "std")]
pub type StorageMap = HashMap<Vec<u8>, Vec<u8>>;
/// Complex storage builder stuff.
#[cfg(feature = "std")]
pub trait BuildStorage {
fn hash(data: &[u8]) -> [u8; 16] {
let r = runtime_io::twox_128(data);
trace!(target: "build_storage", "{} <= {}", substrate_primitives::hexdisplay::HexDisplay::from(&r), ascii_format(data));
r
}
fn build_storage(self) -> Result<StorageMap, String>;
}
#[cfg(feature = "std")]
impl BuildStorage for StorageMap {
fn build_storage(self) -> Result<StorageMap, String> {
Ok(self)
}
}
/// Permill is parts-per-million (i.e. after multiplying by this, divide by 1000000).
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)]
pub struct Permill(u32);
// TODO: impl Mul<Permill> for N where N: As<usize>
impl Permill {
pub fn times<N: traits::As<usize> + ::rstd::ops::Mul<N, Output=N> + ::rstd::ops::Div<N, Output=N>>(self, b: N) -> N {
// TODO: handle overflows
b * <N as traits::As<usize>>::sa(self.0 as usize) / <N as traits::As<usize>>::sa(1000000)
}
pub fn from_millionths(x: u32) -> Permill { Permill(x) }
pub fn from_percent(x: u32) -> Permill { Permill(x * 10_000) }
#[cfg(feature = "std")]
pub fn from_fraction(x: f64) -> Permill { Permill((x * 1_000_000.0) as u32) }
}
#[cfg(feature = "std")]
impl From<f64> for Permill {
fn from(x: f64) -> Permill {
Permill::from_fraction(x)
}
}
#[cfg(feature = "std")]
impl From<f32> for Permill {
fn from(x: f32) -> Permill {
Permill::from_fraction(x as f64)
}
}
/// Ed25519 signature verify.
#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Ed25519Signature(pub H512);
impl Verify for Ed25519Signature {
type Signer = H256;
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &Self::Signer) -> bool {
runtime_io::ed25519_verify(&(self.0).0, msg.get(), &signer.0[..])
}
}
impl From<H512> for Ed25519Signature {
fn from(h: H512) -> Ed25519Signature {
Ed25519Signature(h)
}
}
#[derive(Eq, PartialEq, Clone, Copy, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[repr(u8)]
/// Outcome of a valid extrinsic application. Capable of being sliced.
pub enum ApplyOutcome {
/// Successful application (extrinsic reported no issue).
Success = 0,
/// Failed application (extrinsic was probably a no-op other than fees).
Fail = 1,
}
impl codec::Encode for ApplyOutcome {
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&[*self as u8])
}
}
#[derive(Eq, PartialEq, Clone, Copy, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[repr(u8)]
/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic).
pub enum ApplyError {
/// Bad signature.
BadSignature = 0,
/// Nonce too low.
Stale = 1,
/// Nonce too high.
Future = 2,
/// Sending account had too low a balance.
CantPay = 3,
}
impl codec::Encode for ApplyError {
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&[*self as u8])
}
}
/// Result from attempt to apply an extrinsic.
pub type ApplyResult = Result<ApplyOutcome, ApplyError>;
/// Verify a signature on an encoded value in a lazy manner. This can be
/// an optimization if the signature scheme has an "unsigned" escape hash.
pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(sig: &V, item: &T, signer: &V::Signer) -> bool {
// The `Lazy<T>` trait expresses something like `X: FnMut<Output = for<'a> &'a T>`.
// unfortunately this is a lifetime relationship that can't
// be expressed without generic associated types, better unification of HRTBs in type position,
// and some kind of integration into the Fn* traits.
struct LazyEncode<F> {
inner: F,
encoded: Option<Vec<u8>>,
}
impl<F: Fn() -> Vec<u8>> traits::Lazy<[u8]> for LazyEncode<F> {
fn get(&mut self) -> &[u8] {
self.encoded.get_or_insert_with(&self.inner).as_slice()
}
}
sig.verify(
LazyEncode { inner: || item.encode(), encoded: None },
signer,
)
}
#[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))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct $main {
$(
pub $snake: Option<$config>,
)*
}
#[cfg(any(feature = "std", test))]
impl $crate::BuildStorage for $main {
fn build_storage(self) -> ::std::result::Result<$crate::StorageMap, String> {
let mut s = $crate::StorageMap::new();
$(
if let Some(extra) = self.$snake {
s.extend(extra.build_storage()?);
}
)*
Ok(s)
}
}
}
}
/// Generates enum that contains all possible log entries for the runtime.
/// Every individual module of the runtime that is mentioned, must
/// expose a `Log` and `RawLog` enums.
///
/// Generated enum is binary-compatible with and could be interpreted
/// as `generic::DigestItem`.
///
/// Requires `use runtime_primitives::generic;` to be used.
///
/// Runtime requirements:
/// 1) binary representation of all supported 'system' log items should stay
/// the same. Otherwise, the native code will be unable to read log items
/// generated by previous runtime versions
/// 2) the support of 'system' log items should never be dropped by runtime.
/// Otherwise, native code will lost its ability to read items of this type
/// even if they were generated by the versions which have supported these
/// items.
#[macro_export]
macro_rules! impl_outer_log {
(
$(#[$attr:meta])*
pub enum $name:ident ($internal:ident: DigestItem<$( $genarg:ty ),*>) for $trait:ident {
$( $module:ident($( $item:ident ),*) ),*
}
) => {
/// Wrapper for all possible log entries for the `$trait` runtime. Provides binary-compatible
/// `Encode`/`Decode` implementations with the corresponding `generic::DigestItem`.
#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
#[allow(non_camel_case_types)]
pub struct $name($internal);
/// All possible log entries for the `$trait` runtime. `Encode`/`Decode` implementations
/// are auto-generated => it is not binary-compatible with `generic::DigestItem`.
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
$(#[$attr])*
#[allow(non_camel_case_types)]
enum $internal {
$(
$module($module::Log<$trait>),
)*
}
impl $name {
/// Try to convert `$name` into `generic::DigestItemRef`. Returns Some when
/// `self` is a 'system' log && it has been marked as 'system' in macro call.
/// Otherwise, None is returned.
#[allow(unreachable_patterns)]
fn dref<'a>(&'a self) -> Option<generic::DigestItemRef<'a, $($genarg),*>> {
match self.0 {
$($(
$internal::$module($module::RawLog::$item(ref v)) =>
Some(generic::DigestItemRef::$item(v)),
)*)*
_ => None,
}
}
}
impl From<generic::DigestItem<$($genarg),*>> for $name {
/// Converts `generic::DigestItem` into `$name`. If `generic::DigestItem` represents
/// a system item which is supported by the runtime, it is returned.
/// Otherwise we expect a `Other` log item. Trying to convert from anything other
/// will lead to panic in runtime, since the runtime does not supports this 'system'
/// log item.
#[allow(unreachable_patterns)]
fn from(gen: generic::DigestItem<$($genarg),*>) -> Self {
match gen {
$($(
generic::DigestItem::$item(value) =>
$name($internal::$module($module::RawLog::$item(value))),
)*)*
_ => gen.as_other()
.and_then(|value| Decode::decode(&mut &value[..]))
.map($name)
.expect("not allowed to fail in runtime"),
}
}
}
impl Decode for $name {
/// `generic::DigestItem` binray compatible decode.
fn decode<I: Input>(input: &mut I) -> Option<Self> {
let gen: generic::DigestItem<$($genarg),*> = Decode::decode(input)?;
Some($name::from(gen))
}
}
impl Encode for $name {
/// `generic::DigestItem` binray compatible encode.
fn encode(&self) -> Vec<u8> {
match self.dref() {
Some(dref) => dref.encode(),
None => {
let gen: generic::DigestItem<$($genarg),*> = generic::DigestItem::Other(self.0.encode());
gen.encode()
},
}
}
}
$(
impl From<$module::Log<$trait>> for $name {
/// Converts single module log item into `$name`.
fn from(x: $module::Log<$trait>) -> Self {
$name(x.into())
}
}
impl From<$module::Log<$trait>> for $internal {
/// Converts single module log item into `$internal`.
fn from(x: $module::Log<$trait>) -> Self {
$internal::$module(x)
}
}
)*
};
}
#[cfg(test)]
mod tests {
use codec::{Encode, Decode, Input};
pub trait RuntimeT {
type AuthorityId;
}
pub struct Runtime;
impl RuntimeT for Runtime {
type AuthorityId = u64;
}
#[test]
fn impl_outer_log_works() {
mod a {
use super::RuntimeT;
pub type Log<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { A1(AuthorityId), AuthoritiesChange(Vec<AuthorityId>), A3(AuthorityId) }
}
mod b {
use super::RuntimeT;
pub type Log<R> = RawLog<<R as RuntimeT>::AuthorityId>;
#[derive(Serialize, Deserialize, Debug, Encode, Decode, PartialEq, Eq, Clone)]
pub enum RawLog<AuthorityId> { B1(AuthorityId), B2(AuthorityId) }
}
use super::generic; // required before macro invocation
// TODO try to avoid redundant brackets: a(AuthoritiesChange), b
impl_outer_log! {
pub enum Log(InternalLog: DigestItem<u64>) for Runtime {
a(AuthoritiesChange), b()
}
}
// encode/decode regular item
let b1: Log = b::RawLog::B1::<u64>(777).into();
let encoded_b1 = b1.encode();
let decoded_b1: Log = Decode::decode(&mut &encoded_b1[..]).unwrap();
assert_eq!(b1, decoded_b1);
// encode/decode system item
let auth_change: Log = a::RawLog::AuthoritiesChange::<u64>(vec![100, 200, 300]).into();
let encoded_auth_change = auth_change.encode();
let decoded_auth_change: Log = Decode::decode(&mut &encoded_auth_change[..]).unwrap();
assert_eq!(auth_change, decoded_auth_change);
// interpret regular item using `generic::DigestItem`
let generic_b1: generic::DigestItem<u64> = Decode::decode(&mut &encoded_b1[..]).unwrap();
match generic_b1 {
generic::DigestItem::Other(_) => (),
_ => panic!("unexpected generic_b1: {:?}", generic_b1),
}
// interpret system item using `generic::DigestItem`
let generic_auth_change: generic::DigestItem<u64> = Decode::decode(&mut &encoded_auth_change[..]).unwrap();
match generic_auth_change {
generic::DigestItem::AuthoritiesChange(authorities) => assert_eq!(authorities, vec![100, 200, 300]),
_ => panic!("unexpected generic_auth_change: {:?}", generic_auth_change),
}
}
}
+139
View File
@@ -0,0 +1,139 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Testing utilities.
use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Debug;
use codec::Codec;
use traits::{self, Checkable, Applyable, BlakeTwo256};
pub use substrate_primitives::H256;
#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
pub struct Digest {
pub logs: Vec<u64>,
}
impl traits::Digest for Digest {
type Item = u64;
fn logs(&self) -> &[Self::Item] {
&self.logs
}
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
}
}
impl traits::DigestItem for () {
type AuthorityId = ();
}
impl traits::DigestItem for u64 {
type AuthorityId = ();
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
#[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 traits::Header for Header {
type Number = u64;
type Hashing = BlakeTwo256;
type Hash = H256;
type Digest = Digest;
fn number(&self) -> &Self::Number { &self.number }
fn set_number(&mut self, num: Self::Number) { self.number = num }
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn set_extrinsics_root(&mut self, root: Self::Hash) { self.extrinsics_root = root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn set_state_root(&mut self, root: Self::Hash) { self.state_root = root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn set_parent_hash(&mut self, hash: Self::Hash) { self.parent_hash = hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn set_digest(&mut self, digest: Self::Digest) { self.digest = 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, Deserialize, Debug, Encode, Decode)]
pub struct Block<Xt> {
pub header: Header,
pub extrinsics: Vec<Xt>,
}
impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> traits::Block for Block<Xt> {
type Extrinsic = Xt;
type Header = Header;
type Hash = <Header as traits::Header>::Hash;
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)
}
fn new(header: Self::Header, extrinsics: Vec<Self::Extrinsic>) -> Self {
Block { header, extrinsics }
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
pub struct TestXt<Call>(pub Option<u64>, pub u64, pub Call);
impl<Call: Codec + Sync + Send + Serialize, Context> Checkable<Context> for TestXt<Call> {
type Checked = Self;
fn check_with(self, _: Context) -> Result<Self::Checked, &'static str> { Ok(self) }
}
impl<Call> Applyable for TestXt<Call> where
Call: 'static + Sized + Send + Sync + Clone + Eq + Codec + Debug + Serialize + DeserializeOwned,
{
type AccountId = u64;
type Index = u64;
type Call = Call;
fn sender(&self) -> Option<&u64> { self.0.as_ref() }
fn index(&self) -> &u64 { &self.1 }
fn deconstruct(self) -> (Self::Call, Option<Self::AccountId>) {
(self.2, self.0)
}
}
+463
View File
@@ -0,0 +1,463 @@
// Copyright 2017 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 <http://www.gnu.org/licenses/>.
//! Primitives for the runtime modules.
use rstd::prelude::*;
use rstd::{self, result};
use runtime_io;
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
#[cfg(feature = "std")] use serde::{Serialize, de::DeserializeOwned};
use substrate_primitives;
use substrate_primitives::Blake2Hasher;
use codec::{Codec, Encode};
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{Zero, One, Bounded};
pub use num_traits::ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign,
RemAssign, Shl, Shr};
/// A lazy value.
pub trait Lazy<T: ?Sized> {
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<L: Lazy<[u8]>>(&self, msg: L, signer: &Self::Signer) -> bool;
}
/// Some sort of check on the origin is performed by this object.
pub trait EnsureOrigin<OuterOrigin> {
type Success;
fn ensure_origin(o: OuterOrigin) -> Result<Self::Success, &'static str>;
}
/// 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(s: Self::Source) -> result::Result<Self::Target, &'static str>;
}
/// Simple payment making trait, operating on a single generic `AccountId` type.
pub trait MakePayment<AccountId> {
/// Make some sort of payment concerning `who` for an extrinsic (transaction) of encoded length
/// `encoded_len` bytes. Return true iff the payment was successful.
fn make_payment(who: &AccountId, encoded_len: usize) -> Result<(), &'static str>;
}
impl<T> MakePayment<T> for () {
fn make_payment(_: &T, _: usize) -> Result<(), &'static str> { Ok(()) }
}
/// 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, 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);
pub struct Identity;
impl<T> Convert<T, T> for Identity {
fn convert(a: T) -> T { a }
}
impl<T> Convert<T, ()> for () {
fn convert(_: T) -> () { () }
}
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<u64> +
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> +
Shl<u32, Output = Self> + Shr<u32, Output = Self> +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
PartialOrd<Self> + Ord
{}
impl<T:
Zero + One + IntegerSquareRoot + As<u64> +
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> +
Shl<u32, Output = Self> + Shr<u32, Output = Self> +
CheckedAdd +
CheckedSub +
CheckedMul +
CheckedDiv +
PartialOrd<Self> + Ord
> 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<T: Default + Eq + PartialEq> Clear for T {
fn is_clear(&self) -> bool { *self == Self::clear() }
fn clear() -> Self { Default::default() }
}
pub trait SimpleBitOps:
Sized + Clear +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
{}
impl<T:
Sized + Clear +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
> SimpleBitOps for T {}
/// The block finalisation trait. Implementing this lets you express what should happen
/// for your module when the block is ending.
pub trait OnFinalise<BlockNumber> {
/// The block is being finalised. Implement to have something happen.
fn on_finalise(_n: BlockNumber) {}
}
impl<N> OnFinalise<N> for () {}
macro_rules! tuple_impl {
($one:ident,) => {
impl<Number: Copy, $one: OnFinalise<Number>> OnFinalise<Number> for ($one,) {
fn on_finalise(n: Number) {
$one::on_finalise(n);
}
}
};
($first:ident, $($rest:ident,)+) => {
impl<
Number: Copy,
$first: OnFinalise<Number>,
$($rest: OnFinalise<Number>),+
> OnFinalise<Number> for ($first, $($rest),+) {
fn on_finalise(n: Number) {
$first::on_finalise(n);
$($rest::on_finalise(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 + AsRef<[u8]>;
/// 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: Codec>(s: &S) -> Self::Output {
Encode::using_encoded(s, Self::hash)
}
/// Produce the patricia-trie 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<Item = A>,
A: AsRef<[u8]>
>(input: I) -> Self::Output;
/// The Patricia tree root of the given mapping as an iterator.
fn trie_root<
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>
>(input: I) -> Self::Output;
/// Acquire the global storage root.
fn storage_root() -> Self::Output;
}
/// 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;
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::<Blake2Hasher>(items).into()
}
fn trie_root<
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::trie_root::<Blake2Hasher, _, _, _>(input).into()
}
fn ordered_trie_root<
I: IntoIterator<Item = A>,
A: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::ordered_trie_root::<Blake2Hasher, _, _>(input).into()
}
fn storage_root() -> Self::Output {
runtime_io::storage_root().into()
}
}
/// 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[..]);
}
}
}
#[cfg(feature = "std")]
pub trait MaybeSerializeDebugButNotDeserialize: Serialize + Debug {}
#[cfg(feature = "std")]
impl<T: Serialize + Debug> MaybeSerializeDebugButNotDeserialize for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebugButNotDeserialize {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebugButNotDeserialize for T {}
#[cfg(feature = "std")]
pub trait MaybeSerializeDebug: Serialize + DeserializeOwned + Debug {}
#[cfg(feature = "std")]
impl<T: Serialize + DeserializeOwned + Debug> MaybeSerializeDebug for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebug {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebug for T {}
#[cfg(feature = "std")]
pub trait MaybeDisplay: Display {}
#[cfg(feature = "std")]
impl<T: Display> MaybeDisplay for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeDisplay {}
#[cfg(not(feature = "std"))]
impl<T> MaybeDisplay for T {}
pub trait Member: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static {}
impl<T: Send + Sync + Sized + MaybeSerializeDebug + Eq + PartialEq + Clone + 'static> 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 + MaybeSerializeDebug + 'static {
type Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Codec;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>;
type Hashing: Hash<Output = Self::Hash>;
type Digest: Digest;
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self;
fn number(&self) -> &Self::Number;
fn set_number(&mut self, Self::Number);
fn extrinsics_root(&self) -> &Self::Hash;
fn set_extrinsics_root(&mut self, Self::Hash);
fn state_root(&self) -> &Self::Hash;
fn set_state_root(&mut self, Self::Hash);
fn parent_hash(&self) -> &Self::Hash;
fn set_parent_hash(&mut self, Self::Hash);
fn digest(&self) -> &Self::Digest;
fn set_digest(&mut self, Self::Digest);
fn hash(&self) -> Self::Hash {
<Self::Hashing as Hash>::hash_of(self)
}
}
/// 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: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static {
type Extrinsic: Member + Codec;
type Header: Header<Hash=Self::Hash>;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>;
fn header(&self) -> &Self::Header;
fn extrinsics(&self) -> &[Self::Extrinsic];
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>);
fn new(header: Self::Header, extrinsics: Vec<Self::Extrinsic>) -> Self;
fn hash(&self) -> Self::Hash {
<<Self::Header as Header>::Hashing as Hash>::hash_of(self.header())
}
}
/// Extract the hashing type for a block.
pub type HashFor<B> = <<B as Block>::Header as Header>::Hashing;
/// Extract the number type for a block.
pub type NumberFor<B> = <<B as Block>::Header as Header>::Number;
/// 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.
/// Implement for pieces of information that require some additional context `Context` in order to be
/// checked.
pub trait Checkable<Context>: Sized {
/// Returned if `check_with` succeeds.
type Checked;
fn check_with(self, context: Context) -> Result<Self::Checked, &'static str>;
}
/// 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.
/// Implement for pieces of information that don't require additional context in order to be
/// checked.
pub trait BlindCheckable: Sized {
/// Returned if `check` succeeds.
type Checked;
fn check(self) -> Result<Self::Checked, &'static str>;
}
// Every `BlindCheckable` is also a `Checkable` for arbitrary `Context`.
impl<T: BlindCheckable, Context> Checkable<Context> for T {
type Checked = <Self as BlindCheckable>::Checked;
fn check_with(self, _: Context) -> Result<Self::Checked, &'static str> {
BlindCheckable::check(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: Sized + Send + Sync {
type AccountId: Member + MaybeDisplay;
type Index: Member + MaybeDisplay + SimpleArithmetic;
type Call: Member;
fn index(&self) -> &Self::Index;
fn sender(&self) -> Option<&Self::AccountId>;
fn deconstruct(self) -> (Self::Call, Option<Self::AccountId>);
}
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Codec`.
pub trait Digest: Member + Default {
type Item: DigestItem;
fn logs(&self) -> &[Self::Item];
fn push(&mut self, item: Self::Item);
}
/// Single digest item. Could be any type that implements `Member` and provides methods
/// for casting member to 'system' log items, known to substrate.
///
/// If the runtime does not supports some 'system' items, use `()` as a stub.
pub trait DigestItem: Member {
type AuthorityId;
/// Returns Some if the entry is the `AuthoritiesChange` entry.
fn as_authorities_change(&self) -> Option<&[Self::AuthorityId]> {
None
}
}