mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 04:01:10 +00:00
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:
committed by
Arkadiy Paronyan
parent
8fe5aa4c81
commit
1e01162505
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user