Make substrate generic (#169)

* Some initial work on RPC and client

* Rephrase as params

* More work on traitifying substrate.

* Traitify in_mem.rs

* traitify client.rs

* Make new primitives (mainly traits) build again.

* Many (superficial) build fixes throughout.

* Fix remaining build issues up to bft interface.

* Make bft primitives be generic.

* Switch out MisBehaviorReport for generic version.

* Merge Hashing into Header.

* Update runtime for new generics (with Hashing).

* Update demo runtime.

* Make runtime compile.

* Build fixes for runtime

* Remove old modules.

* port substrate-bft to use generic substrate types

* port client

* port substrate-test-runtime

* mostly port test-runtime to get compiling for std

* Ensure `AccountId` has a `Default`.

* Fix type deps.

* finish porting

* initialize test_runtime from genesis correctly

* remove commented code

* maybe unsigned signatures

* runtimes compile

* port over most of network

* serialization for generic types

* fix comment

* remove some unnecessary trait bounds

* network compiles

* tests compile for sync

* fix deserialization

* temporarily remove deserialize derives

* workarounds for serde issues for deriving deserialization

* get demo-runtime compiling on std

* port extrinsic-pool

* primitives reshuffling

* get network compiling again

* remove debugging file

* runtime tests now passing

* port client-db

* start to port over substrate-rpc

* mostly port over PolkadotApi

* test_runtime follows normal conventions

* substrate runtime tests pass

* deal with inherent extrinsics correctly in polkadot-api

* port transaction-pool

* port polkadot-consensus

* port substrate-rpc

* everything compiles

* tests compile

* fix grumbles

* test-runtime uses its own transfer type

* switch to master branch of jsonrpc

* fix network tests and some warnings

* all tests pass locally

* [ci-skip] add another comment about issue

* remove some curlies
This commit is contained in:
Gav Wood
2018-06-06 17:58:45 +02:00
committed by Robert Habermeier
parent 4e844760a3
commit b94cf078af
132 changed files with 4695 additions and 4303 deletions
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
substrate-codec = { path = "../../codec", default_features = false }
substrate-primitives = { path = "../../primitives", default_features = false }
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
@@ -18,6 +19,7 @@ substrate-runtime-system = { path = "../system", default_features = false }
default = ["std"]
std = [
"serde/std",
"serde_derive",
"substrate-codec/std",
"substrate-primitives/std",
"substrate-runtime-std/std",
@@ -25,6 +25,13 @@ extern crate substrate_runtime_std as rstd;
#[macro_use]
extern crate substrate_runtime_support as runtime_support;
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_primitives as primitives;
extern crate substrate_codec as codec;
@@ -36,8 +43,7 @@ use runtime_support::{storage, Parameter};
use runtime_support::dispatch::Result;
use runtime_support::storage::unhashed::StorageVec;
use primitives::traits::RefInto;
use substrate_primitives::bft::MisbehaviorReport;
use primitives::bft::MisbehaviorReport;
pub const AUTHORITY_AT: &'static [u8] = b":auth:";
pub const AUTHORITY_COUNT: &'static [u8] = b":auth:len";
@@ -59,9 +65,13 @@ pub trait Trait: system::Trait {
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn report_misbehavior(aux, report: MisbehaviorReport) -> Result = 0;
fn report_misbehavior(aux, report: MisbehaviorReport<T::Hash, T::BlockNumber>) -> Result = 0;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn set_code(new: Vec<u8>) -> Result = 0;
fn set_storage(items: Vec<KeyValue>) -> Result = 1;
@@ -89,7 +99,7 @@ impl<T: Trait> Module<T> {
}
/// Report some misbehaviour.
fn report_misbehavior(_aux: &T::PublicAux, _report: MisbehaviorReport) -> Result {
fn report_misbehavior(_aux: &T::PublicAux, _report: MisbehaviorReport<T::Hash, T::BlockNumber>) -> Result {
// TODO.
Ok(())
}
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
hex-literal = "0.1.0"
integer-sqrt = { git = "https://github.com/paritytech/integer-sqrt-rs.git", branch = "master" }
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { path = "../../../safe-mix", default_features = false}
substrate-keyring = { path = "../../keyring", optional = true }
substrate-codec = { path = "../../codec", default_features = false }
@@ -25,6 +26,7 @@ substrate-runtime-system = { path = "../system", default_features = false }
default = ["std"]
std = [
"serde/std",
"serde_derive",
"safe-mix/std",
"substrate-keyring",
"substrate-codec/std",
+16 -6
View File
@@ -18,7 +18,12 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")] extern crate serde;
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
extern crate integer_sqrt;
extern crate substrate_codec as codec;
@@ -26,7 +31,7 @@ extern crate substrate_primitives;
#[cfg(any(feature = "std", test))] extern crate substrate_keyring as keyring;
#[macro_use] extern crate substrate_runtime_std as rstd;
extern crate substrate_runtime_io as runtime_io;
#[macro_use] extern crate substrate_runtime_support as runtime_support;
#[macro_use] extern crate substrate_runtime_support;
extern crate substrate_runtime_primitives as primitives;
extern crate substrate_runtime_consensus as consensus;
extern crate substrate_runtime_democracy as democracy;
@@ -36,8 +41,8 @@ extern crate substrate_runtime_system as system;
use rstd::prelude::*;
use primitives::traits::{Zero, One, RefInto, As};
use runtime_support::{StorageValue, StorageMap};
use runtime_support::dispatch::Result;
use substrate_runtime_support::{StorageValue, StorageMap};
use substrate_runtime_support::dispatch::Result;
pub mod voting;
@@ -101,6 +106,8 @@ pub trait Trait: democracy::Trait {}
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn set_approvals(aux, votes: Vec<bool>, index: VoteIndex) -> Result = 0;
fn reap_inactive_voter(aux, signed_index: u32, who: T::AccountId, who_index: u32, assumed_vote_index: VoteIndex) -> Result = 1;
@@ -108,6 +115,8 @@ decl_module! {
fn submit_candidacy(aux, slot: u32) -> Result = 3;
fn present_winner(aux, candidate: T::AccountId, total: T::Balance, index: VoteIndex) -> Result = 4;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn set_desired_seats(count: u32) -> Result = 0;
fn remove_member(who: T::AccountId) -> Result = 1;
@@ -597,10 +606,11 @@ mod tests {
pub use runtime_io::with_externalities;
pub use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::traits::{HasPublicAux, Identity};
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
impl_outer_dispatch! {
#[derive(Debug, Clone, Eq, Serialize, Deserialize, PartialEq)]
pub enum Proposal {
Staking = 0,
Democracy = 1,
@@ -619,7 +629,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
@@ -18,20 +18,24 @@
use rstd::prelude::*;
use rstd::borrow::Borrow;
use primitives::traits::{Executable, RefInto};
use runtime_io::{Hashing, print};
use runtime_support::{StorageValue, StorageMap, IsSubType};
use runtime_support::dispatch::Result;
use primitives::traits::{Executable, RefInto, Hashing};
use runtime_io::print;
use substrate_runtime_support::dispatch::Result;
use substrate_runtime_support::{StorageValue, StorageMap, IsSubType};
use {system, democracy};
use super::{Trait, Module as Council};
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn propose(aux, proposal: Box<T::Proposal>) -> Result = 0;
fn vote(aux, proposal: T::Hash, approve: bool) -> Result = 1;
fn veto(aux, proposal_hash: T::Hash) -> Result = 2;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn set_cooloff_period(blocks: T::BlockNumber) -> Result = 0;
fn set_voting_period(blocks: T::BlockNumber) -> Result = 1;
@@ -214,7 +218,7 @@ impl<T: Trait> Executable for Council<T> {
mod tests {
use super::*;
use ::tests::*;
use runtime_support::Hashable;
use substrate_runtime_support::Hashable;
use democracy::VoteThreshold;
type CouncilVoting = super::Module<Test>;
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { path = "../../../safe-mix", default_features = false}
substrate-codec = { path = "../../codec", default_features = false }
substrate-primitives = { path = "../../primitives", default_features = false }
@@ -22,6 +23,7 @@ substrate-runtime-system = { path = "../system", default_features = false }
default = ["std"]
std = [
"serde/std",
"serde_derive",
"safe-mix/std",
"substrate-codec/std",
"substrate-primitives/std",
@@ -21,8 +21,12 @@
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate substrate_runtime_support as runtime_support;
extern crate serde_derive;
#[macro_use]
extern crate substrate_runtime_support;
#[cfg(feature = "std")]
extern crate substrate_primitives;
@@ -40,9 +44,9 @@ extern crate substrate_runtime_system as system;
use rstd::prelude::*;
use rstd::result;
use primitives::traits::{Zero, Executable, RefInto, As};
use runtime_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType};
use runtime_support::dispatch::Result;
use primitives::traits::{Zero, Executable, RefInto, As, MaybeSerializeDebug};
use substrate_runtime_support::{StorageValue, StorageMap, Parameter, Dispatchable, IsSubType};
use substrate_runtime_support::dispatch::Result;
mod vote_threshold;
pub use vote_threshold::{Approved, VoteThreshold};
@@ -53,16 +57,20 @@ pub type PropIndex = u32;
pub type ReferendumIndex = u32;
pub trait Trait: staking::Trait + Sized {
type Proposal: Parameter + Dispatchable + IsSubType<Module<Self>>;
type Proposal: Parameter + Dispatchable + IsSubType<Module<Self>> + MaybeSerializeDebug;
}
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn propose(aux, proposal: Box<T::Proposal>, value: T::Balance) -> Result = 0;
fn second(aux, proposal: PropIndex) -> Result = 1;
fn vote(aux, ref_index: ReferendumIndex, approve_proposal: bool) -> Result = 2;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn start_referendum(proposal: Box<T::Proposal>, vote_threshold: VoteThreshold) -> Result = 0;
fn cancel_referendum(ref_index: ReferendumIndex) -> Result = 1;
@@ -346,10 +354,11 @@ mod tests {
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::traits::{HasPublicAux, Identity};
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
impl_outer_dispatch! {
#[derive(Debug, Clone, Eq, Serialize, Deserialize, PartialEq)]
pub enum Proposal {
Session = 0,
Staking = 1,
@@ -369,7 +378,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
@@ -22,7 +22,7 @@ use rstd::ops::{Add, Mul, Div, Rem};
/// A means of determining if a vote is past pass threshold.
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub enum VoteThreshold {
/// A supermajority of approvals is needed to pass this vote.
SuperMajorityApprove,
@@ -18,7 +18,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "std")] extern crate serde;
#[cfg(feature = "std")]
extern crate serde;
extern crate substrate_runtime_std as rstd;
extern crate substrate_runtime_support as runtime_support;
@@ -45,9 +46,9 @@ extern crate substrate_runtime_staking as staking;
use rstd::prelude::*;
use rstd::marker::PhantomData;
use runtime_io::Hashing;
use runtime_support::StorageValue;
use primitives::traits::{self, Header, Zero, One, Checkable, Applyable, CheckEqual, Executable, MakePayment};
use primitives::traits::{self, Header, Zero, One, Checkable, Applyable, CheckEqual, Executable,
MakePayment, Hashing};
use codec::Slicable;
use system::extrinsics_root;
@@ -60,7 +61,7 @@ pub struct Executive<
impl<
System: system::Trait,
Block: traits::Block<Header = System::Header>,
Block: traits::Block<Header = System::Header,Hash = System::Hash>,
Payment: MakePayment<System::AccountId>,
Finalisation: Executable,
> Executive<System, Block, Payment, Finalisation> where
@@ -181,7 +182,7 @@ mod tests {
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::traits::{HasPublicAux, Identity, Header as HeaderT};
use primitives::traits::{HasPublicAux, Identity, Header as HeaderT, BlakeTwo256};
use primitives::testing::{Digest, Header, Block};
pub struct Test;
@@ -196,7 +197,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = substrate_primitives::H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
@@ -14,6 +14,9 @@ substrate-runtime-std = { path = "../../runtime-std", default_features = false }
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
[dev-dependencies]
serde_json = "1.0"
[features]
default = ["std"]
std = [
@@ -0,0 +1,311 @@
// 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::{Slicable, Input};
use substrate_primitives::{AuthorityId, Signature};
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))]
#[repr(i8)]
enum ActionKind {
Propose = 1,
ProposeHeader = 2,
Prepare = 3,
Commit = 4,
AdvanceRound = 5,
}
/// 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)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub enum Action<Block, H> {
/// Proposal of a block candidate.
Propose(u32, Block),
/// Proposal header of a block candidate. Accompanies any proposal,
/// but is used for misbehavior reporting since blocks themselves are big.
ProposeHeader(u32, H),
/// Preparation to commit for a candidate.
Prepare(u32, H),
/// Vote to commit to a candidate.
Commit(u32, H),
/// Vote to advance round after inactive primary.
AdvanceRound(u32),
}
impl<Block: Slicable, Hash: Slicable> Slicable for Action<Block, Hash> {
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
match *self {
Action::Propose(ref round, ref block) => {
v.push(ActionKind::Propose as u8);
round.using_encoded(|s| v.extend(s));
block.using_encoded(|s| v.extend(s));
}
Action::ProposeHeader(ref round, ref hash) => {
v.push(ActionKind::ProposeHeader as u8);
round.using_encoded(|s| v.extend(s));
hash.using_encoded(|s| v.extend(s));
}
Action::Prepare(ref round, ref hash) => {
v.push(ActionKind::Prepare as u8);
round.using_encoded(|s| v.extend(s));
hash.using_encoded(|s| v.extend(s));
}
Action::Commit(ref round, ref hash) => {
v.push(ActionKind::Commit as u8);
round.using_encoded(|s| v.extend(s));
hash.using_encoded(|s| v.extend(s));
}
Action::AdvanceRound(ref round) => {
v.push(ActionKind::AdvanceRound as u8);
round.using_encoded(|s| v.extend(s));
}
}
v
}
fn decode<I: Input>(value: &mut I) -> Option<Self> {
match i8::decode(value) {
Some(x) if x == ActionKind::Propose as i8 => {
let (round, block) = Slicable::decode(value)?;
Some(Action::Propose(round, block))
}
Some(x) if x == ActionKind::ProposeHeader as i8 => {
let (round, hash) = Slicable::decode(value)?;
Some(Action::ProposeHeader(round, hash))
}
Some(x) if x == ActionKind::Prepare as i8 => {
let (round, hash) = Slicable::decode(value)?;
Some(Action::Prepare(round, hash))
}
Some(x) if x == ActionKind::Commit as i8 => {
let (round, hash) = Slicable::decode(value)?;
Some(Action::Commit(round, hash))
}
Some(x) if x == ActionKind::AdvanceRound as i8 => {
Slicable::decode(value).map(Action::AdvanceRound)
}
_ => None,
}
}
}
/// 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)]
#[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>,
}
impl<Block: Slicable, Hash: Slicable> Slicable for Message<Block, Hash> {
fn encode(&self) -> Vec<u8> {
let mut v = self.parent.encode();
self.action.using_encoded(|s| v.extend(s));
v
}
fn decode<I: Input>(value: &mut I) -> Option<Self> {
Some(Message {
parent: Slicable::decode(value)?,
action: Slicable::decode(value)?,
})
}
}
/// Justification of a block.
#[derive(Clone, PartialEq, Eq)]
#[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)>
}
impl<H: Slicable> Slicable for Justification<H> {
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
self.round_number.using_encoded(|s| v.extend(s));
self.hash.using_encoded(|s| v.extend(s));
self.signatures.using_encoded(|s| v.extend(s));
v
}
fn decode<I: Input>(value: &mut I) -> Option<Self> {
Some(Justification {
round_number: Slicable::decode(value)?,
hash: Slicable::decode(value)?,
signatures: Slicable::decode(value)?,
})
}
}
// 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)),
}
/// A report of misbehavior by an authority.
#[derive(Clone, PartialEq, Eq)]
#[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>,
}
impl<Hash: Slicable, Number: Slicable> Slicable for MisbehaviorReport<Hash, Number> {
fn encode(&self) -> Vec<u8> {
let mut v = Vec::new();
self.parent_hash.using_encoded(|s| v.extend(s));
self.parent_number.using_encoded(|s| v.extend(s));
self.target.using_encoded(|s| v.extend(s));
match self.misbehavior {
MisbehaviorKind::BftDoublePrepare(ref round, (ref h_a, ref s_a), (ref h_b, ref s_b)) => {
(MisbehaviorCode::BftDoublePrepare as i8).using_encoded(|s| v.extend(s));
round.using_encoded(|s| v.extend(s));
h_a.using_encoded(|s| v.extend(s));
s_a.using_encoded(|s| v.extend(s));
h_b.using_encoded(|s| v.extend(s));
s_b.using_encoded(|s| v.extend(s));
}
MisbehaviorKind::BftDoubleCommit(ref round, (ref h_a, ref s_a), (ref h_b, ref s_b)) => {
(MisbehaviorCode::BftDoubleCommit as i8).using_encoded(|s| v.extend(s));
round.using_encoded(|s| v.extend(s));
h_a.using_encoded(|s| v.extend(s));
s_a.using_encoded(|s| v.extend(s));
h_b.using_encoded(|s| v.extend(s));
s_b.using_encoded(|s| v.extend(s));
}
}
v
}
fn decode<I: Input>(input: &mut I) -> Option<Self> {
let parent_hash = Hash::decode(input)?;
let parent_number = Number::decode(input)?;
let target = AuthorityId::decode(input)?;
let misbehavior = 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)?),
)
}
};
Some(MisbehaviorReport {
parent_hash,
parent_number,
target,
misbehavior,
})
}
}
#[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);
}
}
@@ -16,37 +16,23 @@
//! Generic implementations of Extrinsic/Header/Block.
#[cfg(feature = "std")] use serde::Serialize;
#[cfg(feature = "std")]
use std::fmt;
#[cfg(feature = "std")]
use serde::{Deserialize, Deserializer};
use rstd::prelude::*;
use codec::{Slicable, Input};
use runtime_support::AuxDispatchable;
use traits;
use traits::{self, Member, SimpleArithmetic, SimpleBitOps, MaybeDisplay, Block as BlockT,
Header as HeaderT, Hashing as HashingT};
use rstd::ops;
#[cfg(feature = "std")]
use std::fmt::{self, Debug};
#[cfg(feature = "std")]
pub trait MaybeSerializeDebug: Serialize + Debug {}
#[cfg(feature = "std")]
impl<T: Serialize + Debug> MaybeSerializeDebug for T {}
#[cfg(not(feature = "std"))]
pub trait MaybeSerializeDebug {}
#[cfg(not(feature = "std"))]
impl<T> MaybeSerializeDebug for T {}
pub trait Member: MaybeSerializeDebug + Eq + PartialEq + Clone {}
impl<T: MaybeSerializeDebug + Eq + PartialEq + Clone> Member for T {}
/// A vetted and verified extrinsic from the external world.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
pub struct Extrinsic<AccountId, Index, Call> where
AccountId: Member,
Index: Member,
Call: Member,
{
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct Extrinsic<AccountId, Index, Call> {
/// Who signed it (note this is not a signature).
pub signed: AccountId,
/// The number of extrinsics have come before from the same signer.
@@ -56,8 +42,8 @@ pub struct Extrinsic<AccountId, Index, Call> where
}
impl<AccountId, Index, Call> Slicable for Extrinsic<AccountId, Index, Call> where
AccountId: Member + Slicable,
Index: Member + Slicable,
AccountId: Member + Slicable + MaybeDisplay,
Index: Member + Slicable + MaybeDisplay + SimpleArithmetic,
Call: Member + Slicable
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
@@ -81,37 +67,51 @@ impl<AccountId, Index, Call> Slicable for Extrinsic<AccountId, Index, Call> wher
/// A extrinsics right from the external world. Unchecked.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize))]
pub struct UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member, // TODO: should be Option<Signature>
{
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct UncheckedExtrinsic<AccountId, Index, Call, Signature> {
/// The actual extrinsic information.
pub extrinsic: Extrinsic<AccountId, Index, Call>,
/// The signature; should be an Ed25519 signature applied to the serialised `extrinsic` field.
pub signature: Signature,
}
impl<AccountId, Index, Call, Signature> UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member + Default,
Index: Member,
impl<AccountId, Index, Call, Signature> traits::Checkable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member,
Signature: Member + Default,
Signature: Member + traits::Verify<Signer = AccountId>,
Extrinsic<AccountId, Index, Call>: Slicable,
{
type Checked = CheckedExtrinsic<AccountId, Index, Call, Signature>;
fn check(self) -> Result<Self::Checked, Self> {
if ::verify_encoded_lazy(&self.signature, &self.extrinsic, &self.extrinsic.signed) {
Ok(CheckedExtrinsic(self))
} else {
Err(self)
}
}
}
impl<AccountId, Index, Call, Signature> UncheckedExtrinsic<AccountId, Index, Call, ::MaybeUnsigned<Signature>> where
AccountId: Member + Default + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member,
Signature: Member + Default + traits::Verify<Signer = AccountId>,
Extrinsic<AccountId, Index, Call>: Slicable,
{
/// Is this extrinsic signed?
pub fn is_signed(&self) -> bool {
// TODO: should be Option<Signature> and Option<AccountId>
self.signature != Signature::default() || self.extrinsic.signed != AccountId::default()
self.signature.is_signed(&self.extrinsic.signed)
}
}
impl<AccountId, Index, Call, Signature> Slicable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member + Slicable,
Index: Member + Slicable,
Call: Member + Slicable,
Signature: Member + Slicable
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member,
Signature: Member + Slicable,
Extrinsic<AccountId, Index, Call>: Slicable,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
// This is a little more complicated than usual since the binary format must be compatible
@@ -133,9 +133,11 @@ impl<AccountId, Index, Call, Signature> Slicable for UncheckedExtrinsic<AccountI
// Vec<u8>. we'll make room for it here, then overwrite once we know the length.
v.extend(&[0u8; 4]);
self.extrinsic.signed.using_encoded(|s| v.extend(s));
/* self.extrinsic.signed.using_encoded(|s| v.extend(s));
self.extrinsic.index.using_encoded(|s| v.extend(s));
self.extrinsic.function.using_encoded(|s| v.extend(s));
self.extrinsic.function.using_encoded(|s| v.extend(s));*/
self.extrinsic.using_encoded(|s| v.extend(s));
self.signature.using_encoded(|s| v.extend(s));
let length = (v.len() - 4) as u32;
@@ -147,55 +149,25 @@ impl<AccountId, Index, Call, Signature> Slicable for UncheckedExtrinsic<AccountI
#[cfg(feature = "std")]
impl<AccountId, Index, Call, Signature> fmt::Debug for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member,
AccountId: fmt::Debug,
Index: fmt::Debug,
Call: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UncheckedExtrinsic({:?})", self.extrinsic)
}
}
impl<AccountId, Index, Call, Signature> traits::Checkable for UncheckedExtrinsic<AccountId, Index, Call, Signature> where
AccountId: Member + Default,
Index: Member,
Call: Member,
Signature: Member + Default + traits::Verify<Signer = AccountId>,
Extrinsic<AccountId, Index, Call>: Slicable
{
type Checked = CheckedExtrinsic<AccountId, Index, Call, Signature>;
fn check(self) -> Result<Self::Checked, Self> {
if !self.is_signed() {
Ok(CheckedExtrinsic(self))
} else {
if ::codec::Slicable::using_encoded(&self.extrinsic, |msg|
self.signature.verify(msg, &self.extrinsic.signed)
) {
Ok(CheckedExtrinsic(self))
} else {
Err(self)
}
}
}
}
/// A type-safe indicator that a extrinsic has been checked.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
pub struct CheckedExtrinsic<AccountId, Index, Call, Signature>
(UncheckedExtrinsic<AccountId, Index, Call, Signature>)
where
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member;
(UncheckedExtrinsic<AccountId, Index, Call, Signature>);
impl<AccountId, Index, Call, Signature> CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member,
Signature: Member
{
@@ -218,8 +190,8 @@ where
impl<AccountId, Index, Call, Signature> ops::Deref
for CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member,
Signature: Member
{
@@ -233,8 +205,8 @@ where
impl<AccountId, Index, Call, Signature> traits::Applyable
for CheckedExtrinsic<AccountId, Index, Call, Signature>
where
AccountId: Member,
Index: Member,
AccountId: Member + MaybeDisplay,
Index: Member + MaybeDisplay + SimpleArithmetic,
Call: Member + AuxDispatchable<Aux = AccountId>,
Signature: Member
{
@@ -256,12 +228,13 @@ where
}
#[derive(Default, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub struct Digest<Item: Member> {
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Digest<Item> {
pub logs: Vec<Item>,
}
impl<Item> Slicable for Digest<Item> where
Item: Member + Slicable
Item: Member + Default + Slicable
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Digest { logs: Slicable::decode(input)? })
@@ -271,7 +244,7 @@ impl<Item> Slicable for Digest<Item> where
}
}
impl<Item> traits::Digest for Digest<Item> where
Item: Member + Slicable
Item: Member + Default + Slicable
{
type Item = Item;
fn push(&mut self, item: Self::Item) {
@@ -279,32 +252,69 @@ impl<Item> traits::Digest for Digest<Item> where
}
}
/// Abstraction over a block header for a substrate chain.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Header<Number, Hash, DigestItem> where
Number: Member,
Hash: Member,
DigestItem: Member,
{
pub struct Header<Number, Hashing: HashingT, DigestItem> {
/// The parent hash.
pub parent_hash: Hash,
pub parent_hash: <Hashing as HashingT>::Output,
/// The block number.
pub number: Number,
/// The state trie merkle root
pub state_root: Hash,
pub state_root: <Hashing as HashingT>::Output,
/// The merkle root of the extrinsics.
pub extrinsics_root: Hash,
pub extrinsics_root: <Hashing as HashingT>::Output,
/// A chain-specific digest of data useful for light clients or referencing auxiliary data.
pub digest: Digest<DigestItem>,
}
impl<Number, Hash, DigestItem> Slicable for Header<Number, Hash, DigestItem> where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
// 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")]
#[cfg_attr(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, Hashing: HashingT> From<DeserializeHeader<N, Hashing::Output, D>> for Header<N, Hashing, D> {
fn from(other: DeserializeHeader<N, Hashing::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, Hashing: 'a + HashingT, DigestItem: 'a> Deserialize<'a> for Header<Number, Hashing, DigestItem> where
Number: Deserialize<'a>,
Hashing::Output: Deserialize<'a>,
DigestItem: Deserialize<'a>,
{
fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
DeserializeHeader::<Number, Hashing::Output, DigestItem>::deserialize(de).map(Into::into)
}
}
impl<Number, Hashing, DigestItem> Slicable for Header<Number, Hashing, DigestItem> where
Number: Member + Slicable + MaybeDisplay + SimpleArithmetic + Slicable,
Hashing: HashingT,
DigestItem: Member + Default + Slicable,
Hashing::Output: Default + Member + MaybeDisplay + SimpleBitOps + Slicable,
{
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Header {
@@ -326,20 +336,33 @@ impl<Number, Hash, DigestItem> Slicable for Header<Number, Hash, DigestItem> whe
v
}
}
impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestItem> where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
impl<Number, Hashing, DigestItem> traits::Header for Header<Number, Hashing, DigestItem> where
Number: Member + ::rstd::hash::Hash + Copy + Slicable + MaybeDisplay + SimpleArithmetic + Slicable,
Hashing: HashingT,
DigestItem: Member + Default + Slicable,
Hashing::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Slicable,
{
type Number = Number;
type Hash = Hash;
type Hash = <Hashing as HashingT>::Output;
type Hashing = Hashing;
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,
@@ -353,45 +376,72 @@ impl<Number, Hash, DigestItem> traits::Header for Header<Number, Hash, DigestIte
}
}
/// Abstraction over a substrate block.
impl<Number, Hashing, DigestItem> Header<Number, Hashing, DigestItem> where
Number: Member + ::rstd::hash::Hash + Copy + Slicable + MaybeDisplay + SimpleArithmetic + Slicable,
Hashing: HashingT,
DigestItem: Member + Default + Slicable,
Hashing::Output: Default + ::rstd::hash::Hash + Copy + Member + MaybeDisplay + SimpleBitOps + Slicable,
{
/// Convenience helper for computing the hash of the header without having
/// to import the trait.
pub fn hash(&self) -> Hashing::Output {
Hashing::hash_of(self)
}
}
/// 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 struct Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature> where
Number: Member,
Hash: Member,
DigestItem: Member,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
{
/// The block header.
pub header: Header<Number, Hash, DigestItem>,
/// The accompanying extrinsics.
pub extrinsics: Vec<UncheckedExtrinsic<AccountId, Index, Call, Signature>>,
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<Number, Hash, DigestItem, AccountId, Index, Call, Signature> Slicable
for Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature>
where
Number: Member,
Hash: Member,
DigestItem: Member,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member,
Header<Number, Hash, DigestItem>: Slicable,
UncheckedExtrinsic<AccountId, Index, Call, Signature>: Slicable,
{
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)]
#[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: Slicable, Extrinsic: Slicable> Slicable for Block<Header, Extrinsic> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Block {
header: Slicable::decode(input)?,
extrinsics: Slicable::decode(input)?,
})
}
fn encode(&self) -> Vec<u8> {
let mut v: Vec<u8> = Vec::new();
v.extend(self.header.encode());
@@ -400,19 +450,15 @@ where
}
}
impl<Number, Hash, DigestItem, AccountId, Index, Call, Signature> traits::Block
for Block<Number, Hash, DigestItem, AccountId, Index, Call, Signature>
impl<Header, Extrinsic> traits::Block for Block<Header, Extrinsic>
where
Number: Member + Slicable,
Hash: Member + Slicable,
DigestItem: Member + Slicable,
AccountId: Member,
Index: Member,
Call: Member,
Signature: Member
Header: HeaderT,
Extrinsic: Member + Slicable,
{
type Extrinsic = UncheckedExtrinsic<AccountId, Index, Call, Signature>;
type Header = Header<Number, Hash, DigestItem>;
type Extrinsic = Extrinsic;
type Header = Header;
type Hash = <Self::Header as traits::Header>::Hash;
fn header(&self) -> &Self::Header {
&self.header
}
@@ -422,4 +468,64 @@ where
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 }
}
}
#[cfg(test)]
mod tests {
use codec::Slicable;
use substrate_primitives::{H256, H512};
use super::{Digest, Header, UncheckedExtrinsic, Extrinsic};
type Block = super::Block<
Header<u64, ::traits::BlakeTwo256, Vec<u8>>,
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![vec![1, 2, 3], vec![4, 5, 6]] },
},
extrinsics: vec![
UncheckedExtrinsic {
signature: H512::from([0u8; 64]).into(),
extrinsic: Extrinsic {
signed: [255u8; 32].into(),
index: 0,
function: 100,
}
},
UncheckedExtrinsic {
signature: H512::from([255u8; 64]).into(),
extrinsic: Extrinsic {
signed: [128u8; 32].into(),
index: 100,
function: 99,
}
},
]
};
{
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);
}
}
}
@@ -34,16 +34,23 @@ extern crate substrate_runtime_support as runtime_support;
extern crate substrate_codec as codec;
extern crate substrate_primitives;
#[cfg(test)]
extern crate serde_json;
#[cfg(feature = "std")]
use std::collections::HashMap;
use substrate_primitives::hash::H512;
use rstd::prelude::*;
use substrate_primitives::hash::{H256, H512};
#[cfg(feature = "std")]
pub mod testing;
pub mod traits;
pub mod generic;
pub mod bft;
use traits::{Verify, Lazy};
#[cfg(feature = "std")]
pub type BuiltExternalities = HashMap<Vec<u8>, Vec<u8>>;
@@ -55,24 +62,90 @@ pub trait BuildExternalities {
/// Ed25519 signature verify.
#[derive(Eq, PartialEq, Clone, Default)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
pub struct Ed25519Signature(H512);
impl traits::Verify for Ed25519Signature {
type Signer = [u8; 32];
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool {
runtime_io::ed25519_verify(&(self.0).0, msg, &signer[..])
#[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 codec::Slicable for Ed25519Signature {
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> { Some(Ed25519Signature(codec::Slicable::decode(input)?,)) }
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { self.0.using_encoded(f) }
}
impl From<H512> for Ed25519Signature {
fn from(h: H512) -> Ed25519Signature {
Ed25519Signature(h)
}
}
/// Potentially "unsigned" signature verification.
#[derive(Eq, PartialEq, Clone, Default)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct MaybeUnsigned<T>(pub T);
impl<T: Verify> MaybeUnsigned<T> where
T: Default + Eq,
<T as Verify>::Signer: Default + Eq,
{
fn is_signed(&self, signer: &<Self as Verify>::Signer) -> bool {
self.0 != T::default() || signer != &<Self as Verify>::Signer::default()
}
}
impl<T: Verify> Verify for MaybeUnsigned<T> where
T: Default + Eq,
<T as Verify>::Signer: Default + Eq,
{
type Signer = T::Signer;
fn verify<L: Lazy<[u8]>>(&self, msg: L, signer: &Self::Signer) -> bool {
if !self.is_signed(signer) {
true
} else {
self.0.verify(msg, signer)
}
}
}
impl<T: codec::Slicable> codec::Slicable for MaybeUnsigned<T> {
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> { Some(MaybeUnsigned(codec::Slicable::decode(input)?)) }
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { self.0.using_encoded(f) }
}
impl<T> From<T> for MaybeUnsigned<T> {
fn from(t: T) -> Self {
MaybeUnsigned(t)
}
}
/// 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::Slicable>(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)*) => {
@@ -16,13 +16,15 @@
//! Testing utilities.
use serde;
use serde::{Serialize, de::DeserializeOwned};
use std::fmt::Debug;
use codec::{Slicable, Input};
use runtime_support::AuxDispatchable;
use substrate_primitives::H256;
use traits::{self, Checkable, Applyable};
use traits::{self, Checkable, Applyable, BlakeTwo256};
#[derive(Default, PartialEq, Eq, Clone, Serialize, Debug)]
pub use substrate_primitives::H256;
#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
pub struct Digest {
pub logs: Vec<u64>,
}
@@ -41,7 +43,7 @@ impl traits::Digest for Digest {
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Debug)]
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
@@ -74,13 +76,25 @@ impl Slicable for Header {
}
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,
@@ -94,12 +108,12 @@ impl traits::Header for Header {
}
}
#[derive(PartialEq, Eq, Clone, Serialize, Debug)]
pub struct Block<Xt: Slicable + Sized + serde::Serialize> {
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
pub struct Block<Xt: Slicable + Sized + Send + Sync + Serialize + Clone + Eq + Debug> {
pub header: Header,
pub extrinsics: Vec<Xt>,
}
impl<Xt: Slicable + Sized + serde::Serialize> Slicable for Block<Xt> {
impl<Xt: Slicable + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> Slicable for Block<Xt> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(Block {
header: Slicable::decode(input)?,
@@ -113,9 +127,11 @@ impl<Xt: Slicable + Sized + serde::Serialize> Slicable for Block<Xt> {
v
}
}
impl<Xt: Slicable + Sized + serde::Serialize> traits::Block for Block<Xt> {
impl<Xt: 'static + Slicable + 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
}
@@ -125,11 +141,15 @@ impl<Xt: Slicable + Sized + serde::Serialize> traits::Block for Block<Xt> {
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, Debug)]
pub struct TestXt<Call: AuxDispatchable + Slicable + Sized + serde::Serialize>(pub (u64, u64, Call));
impl<Call: AuxDispatchable + Slicable + Sized + serde::Serialize> Slicable for TestXt<Call> {
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
pub struct TestXt<Call: AuxDispatchable + Slicable + Sized + Send + Sync + Serialize>(pub (u64, u64, Call));
impl<Call: AuxDispatchable + Slicable + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> Slicable for TestXt<Call> {
fn decode<I: Input>(input: &mut I) -> Option<Self> {
Some(TestXt(Slicable::decode(input)?))
}
@@ -137,11 +157,11 @@ impl<Call: AuxDispatchable + Slicable + Sized + serde::Serialize> Slicable for T
self.0.encode()
}
}
impl<Call: AuxDispatchable + Slicable + Sized + serde::Serialize> Checkable for TestXt<Call> {
impl<Call: 'static + AuxDispatchable + Slicable + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> Checkable for TestXt<Call> {
type Checked = Self;
fn check(self) -> Result<Self, Self> { Ok(self) }
}
impl<Call: AuxDispatchable<Aux = u64> + Slicable + Sized + serde::Serialize> Applyable for TestXt<Call> {
impl<Call: AuxDispatchable<Aux = u64> + Slicable + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> Applyable for TestXt<Call> {
type AccountId = u64;
type Index = u64;
fn sender(&self) -> &u64 { &(self.0).0 }
@@ -18,19 +18,26 @@
use rstd::prelude::*;
use rstd;
#[cfg(not(feature = "std"))] use runtime_io;
use runtime_io;
#[cfg(feature = "std")] use std::fmt::{Debug, Display};
#[cfg(feature = "std")] use serde::{Serialize, de::DeserializeOwned};
use substrate_primitives;
use codec::Slicable;
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{Zero, One, Bounded};
use rstd::ops::{Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
/// A lazy value.
pub trait Lazy<T: ?Sized> {
fn get(&mut self) -> &T;
}
/// Means of signature verification.
pub trait Verify {
/// Type of the signer.
type Signer;
/// Verify a signature.
fn verify(&self, msg: &[u8], signer: &Self::Signer) -> bool;
fn verify<L: Lazy<[u8]>>(&self, msg: L, signer: &Self::Signer) -> bool;
}
/// Simple payment making trait, operating on a single generic `AccountId` type.
@@ -122,13 +129,28 @@ impl<T:
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 +
Sized + Clear +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
{}
impl<T:
Sized +
Sized + Clear +
rstd::ops::BitOr<Self, Output = Self> +
rstd::ops::BitAnd<Self, Output = Self>
> SimpleBitOps for T {}
@@ -148,114 +170,69 @@ impl<A: Executable, B: Executable> Executable for (A, B) {
}
}
/// Something that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Slicable`.
pub trait Digest {
type Item: Sized;
fn push(&mut self, item: Self::Item);
}
/// Abstraction around hashing
pub trait Hashing: '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]>;
impl Digest for substrate_primitives::Digest {
type Item = substrate_primitives::block::Log;
fn push(&mut self, item: Self::Item) {
self.logs.push(item);
/// 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: Slicable>(s: &S) -> Self::Output {
Slicable::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;
}
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and
/// `parent_hash`, as well as a `digest` and a block `number`.
///
/// You can also create a `new` one from those fields.
pub trait Header: Sized + Slicable {
type Number: Sized;
type Hash: Sized;
type Digest: Sized;
fn number(&self) -> &Self::Number;
fn extrinsics_root(&self) -> &Self::Hash;
fn state_root(&self) -> &Self::Hash;
fn parent_hash(&self) -> &Self::Hash;
fn digest(&self) -> &Self::Digest;
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self;
}
/// Blake2-256 Hashing implementation.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct BlakeTwo256;
impl Header for substrate_primitives::Header {
type Number = substrate_primitives::block::Number;
type Hash = substrate_primitives::block::HeaderHash;
type Digest = substrate_primitives::block::Digest;
fn number(&self) -> &Self::Number { &self.number }
fn extrinsics_root(&self) -> &Self::Hash { &self.extrinsics_root }
fn state_root(&self) -> &Self::Hash { &self.state_root }
fn parent_hash(&self) -> &Self::Hash { &self.parent_hash }
fn digest(&self) -> &Self::Digest { &self.digest }
fn new(
number: Self::Number,
extrinsics_root: Self::Hash,
state_root: Self::Hash,
parent_hash: Self::Hash,
digest: Self::Digest
) -> Self {
substrate_primitives::Header {
number: number,
extrinsics_root: extrinsics_root,
state_root: state_root,
parent_hash: parent_hash,
digest: digest,
}
impl Hashing for BlakeTwo256 {
type Output = substrate_primitives::H256;
fn hash(s: &[u8]) -> Self::Output {
runtime_io::blake2_256(s).into()
}
}
/// Something which fulfills the abstract idea of a Substrate block. It has types for an
/// `Extrinsic` piece of information as well as a `Header`.
///
/// You can get an iterator over each of the `extrinsics` and retrieve the `header`.
pub trait Block {
type Extrinsic: Sized;
type Header: Header;
fn header(&self) -> &Self::Header;
fn extrinsics(&self) -> &[Self::Extrinsic];
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>);
}
impl Block for substrate_primitives::Block {
type Extrinsic = substrate_primitives::block::Extrinsic;
type Header = substrate_primitives::Header;
fn header(&self) -> &Self::Header {
&self.header
fn enumerated_trie_root(items: &[&[u8]]) -> Self::Output {
runtime_io::enumerated_trie_root(items).into()
}
fn extrinsics(&self) -> &[Self::Extrinsic] {
&self.transactions[..]
fn trie_root<
I: IntoIterator<Item = (A, B)>,
A: AsRef<[u8]> + Ord,
B: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::trie_root(input).into()
}
fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
(self.header, self.transactions)
fn ordered_trie_root<
I: IntoIterator<Item = A>,
A: AsRef<[u8]>
>(input: I) -> Self::Output {
runtime_io::ordered_trie_root(input).into()
}
fn storage_root() -> Self::Output {
runtime_io::storage_root().into()
}
}
/// A "checkable" piece of information, used by the standard Substrate Executive in order to
/// check the validity of a piece of extrinsic information, usually by verifying the signature.
pub trait Checkable: Sized {
type Checked: Sized;
fn check(self) -> Result<Self::Checked, Self>;
}
/// An "executable" piece of information, used by the standard Substrate Executive in order to
/// enact a piece of extrinsic information by marshalling and dispatching to a named functioon
/// call.
///
/// Also provides information on to whom this information is attributable and an index that allows
/// each piece of attributable information to be disambiguated.
pub trait Applyable {
type AccountId;
type Index;
fn index(&self) -> &Self::Index;
fn sender(&self) -> &Self::AccountId;
fn apply(self);
}
/// Something that can be checked for equality and printed out to a debug channel if bad.
@@ -281,3 +258,114 @@ impl CheckEqual for substrate_primitives::H256 {
}
}
}
#[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 that acts like a `Digest` - it can have `Log`s `push`ed onto it and these `Log`s are
/// each `Slicable`.
pub trait Digest {
type Item: Member;
fn push(&mut self, item: Self::Item);
}
/// Something which fulfills the abstract idea of a Substrate header. It has types for a `Number`,
/// a `Hash` and a `Digest`. It provides access to an `extrinsics_root`, `state_root` and
/// `parent_hash`, as well as a `digest` and a block `number`.
///
/// You can also create a `new` one from those fields.
pub trait Header: Clone + Send + Sync + Slicable + Eq + MaybeSerializeDebug {
type Number: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + SimpleArithmetic + Slicable;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Slicable + AsRef<[u8]>;
type Hashing: Hashing<Output = Self::Hash>;
type Digest: Member + Default;
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 Hashing>::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 + Slicable + Eq + MaybeSerializeDebug {
type Extrinsic: Member + Slicable;
type Header: Header<Hash=Self::Hash>;
type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Slicable + 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 Hashing>::hash_of(self.header())
}
}
/// Extract the hashing type for a block.
pub type HashingFor<B> = <<B as Block>::Header as Header>::Hashing;
/// A "checkable" piece of information, used by the standard Substrate Executive in order to
/// check the validity of a piece of extrinsic information, usually by verifying the signature.
pub trait Checkable: Sized + Send + Sync {
type Checked: Member;
fn check(self) -> Result<Self::Checked, Self>;
}
/// An "executable" piece of information, used by the standard Substrate Executive in order to
/// enact a piece of extrinsic information by marshalling and dispatching to a named functioon
/// call.
///
/// Also provides information on to whom this information is attributable and an index that allows
/// each piece of attributable information to be disambiguated.
pub trait Applyable: Sized + Send + Sync {
type AccountId: Member + MaybeDisplay;
type Index: Member + MaybeDisplay + SimpleArithmetic;
fn index(&self) -> &Self::Index;
fn sender(&self) -> &Self::AccountId;
fn apply(self);
}
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { path = "../../../safe-mix", default_features = false}
substrate-keyring = { path = "../../keyring", optional = true }
substrate-codec = { path = "../../codec", default_features = false }
@@ -21,6 +22,7 @@ substrate-runtime-system = { path = "../system", default_features = false }
default = ["std"]
std = [
"serde/std",
"serde_derive",
"safe-mix/std",
"substrate-keyring",
"substrate-codec/std",
+10 -2
View File
@@ -22,6 +22,10 @@
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[cfg(any(feature = "std", test))]
extern crate substrate_keyring as keyring;
@@ -51,9 +55,13 @@ pub trait Trait: consensus::Trait {
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn set_key(aux, key: T::SessionKey) -> Result = 0;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn set_length(new: T::BlockNumber) -> Result = 0;
fn force_new_session() -> Result = 1;
@@ -197,7 +205,7 @@ mod tests {
use runtime_io::with_externalities;
use substrate_primitives::H256;
use primitives::BuildExternalities;
use primitives::traits::{HasPublicAux, Identity};
use primitives::traits::{HasPublicAux, Identity, BlakeTwo256};
use primitives::testing::{Digest, Header};
pub struct Test;
@@ -212,7 +220,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
safe-mix = { path = "../../../safe-mix", default_features = false}
substrate-keyring = { path = "../../keyring", optional = true }
substrate-codec = { path = "../../codec", default_features = false }
@@ -27,6 +28,7 @@ wabt = "0.1.7"
default = ["std"]
std = [
"serde/std",
"serde_derive",
"safe-mix/std",
"substrate-keyring",
"substrate-codec/std",
+11 -6
View File
@@ -21,6 +21,10 @@
#[cfg(feature = "std")]
extern crate serde;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
extern crate wabt;
@@ -48,7 +52,7 @@ use rstd::collections::btree_map::{BTreeMap, Entry};
use codec::Slicable;
use runtime_support::{StorageValue, StorageMap, Parameter};
use runtime_support::dispatch::Result;
use primitives::traits::{Zero, One, Bounded, RefInto, SimpleArithmetic, Executable, MakePayment, As};
use primitives::traits::{Zero, One, As, Bounded, RefInto, SimpleArithmetic, Executable, MakePayment, Hashing as HashingT};
#[cfg(test)]
#[derive(Debug, PartialEq, Clone)]
@@ -71,7 +75,7 @@ pub trait ContractAddressFor<AccountId: Sized> {
}
impl<Hashing, AccountId> ContractAddressFor<AccountId> for Hashing where
Hashing: runtime_io::Hashing,
Hashing: HashingT,
AccountId: Sized + Slicable + From<Hashing::Output>,
Hashing::Output: Slicable
{
@@ -90,11 +94,15 @@ pub trait Trait: system::Trait + session::Trait {
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn transfer(aux, dest: T::AccountId, value: T::Balance) -> Result = 0;
fn stake(aux) -> Result = 1;
fn unstake(aux) -> Result = 2;
}
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum PrivCall {
fn set_sessions_per_era(new: T::BlockNumber) -> Result = 0;
fn set_bonding_duration(new: T::BlockNumber) -> Result = 1;
@@ -701,7 +709,6 @@ pub struct GenesisConfig<T: Trait> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> GenesisConfig<T> where T::AccountId: From<u64> {
pub fn simple() -> Self {
use primitives::traits::As;
GenesisConfig {
sessions_per_era: T::BlockNumber::sa(2),
current_era: T::BlockNumber::sa(0),
@@ -715,7 +722,6 @@ impl<T: Trait> GenesisConfig<T> where T::AccountId: From<u64> {
}
pub fn extended() -> Self {
use primitives::traits::As;
GenesisConfig {
sessions_per_era: T::BlockNumber::sa(3),
current_era: T::BlockNumber::sa(1),
@@ -740,7 +746,6 @@ impl<T: Trait> GenesisConfig<T> where T::AccountId: From<u64> {
#[cfg(any(feature = "std", test))]
impl<T: Trait> Default for GenesisConfig<T> {
fn default() -> Self {
use primitives::traits::As;
GenesisConfig {
sessions_per_era: T::BlockNumber::sa(1000),
current_era: T::BlockNumber::sa(0),
@@ -801,7 +806,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = ::primitives::traits::BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;
+13 -8
View File
@@ -34,8 +34,8 @@ extern crate substrate_runtime_primitives as primitives;
extern crate safe_mix;
use rstd::prelude::*;
use runtime_io::Hashing;
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded};
use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, Zero, One, Bounded,
Hashing, Member, MaybeDisplay};
use runtime_support::{StorageValue, StorageMap, Parameter};
use safe_mix::TripletMix;
@@ -59,13 +59,18 @@ pub fn extrinsics_data_root<H: Hashing>(xts: Vec<Vec<u8>>) -> H::Output {
}
pub trait Trait {
type Index: Parameter + Default + SimpleArithmetic + Copy;
type BlockNumber: Parameter + SimpleArithmetic + Default + Bounded + Copy;
type Hash: Parameter + SimpleBitOps + Default + Copy + CheckEqual;
type Index: Parameter + Member + Default + MaybeDisplay + SimpleArithmetic + Copy;
type BlockNumber: Parameter + Member + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy + rstd::hash::Hash;
type Hash: Parameter + Member + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + rstd::hash::Hash + AsRef<[u8]>;
type Hashing: Hashing<Output = Self::Hash>;
type Digest: Parameter + Default + traits::Digest;
type AccountId: Parameter + Ord + Default;
type Header: traits::Header<Number = Self::BlockNumber, Hash = Self::Hash, Digest = Self::Digest>;
type Digest: Parameter + Member + Default + traits::Digest;
type AccountId: Parameter + Member + MaybeDisplay + Ord + Default;
type Header: Parameter + traits::Header<
Number = Self::BlockNumber,
Hashing = Self::Hashing,
Hash = Self::Hash,
Digest = Self::Digest
>;
}
decl_module! {
@@ -6,6 +6,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
hex-literal = "0.1.0"
serde = { version = "1.0", default_features = false }
serde_derive = { version = "1.0", optional = true }
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
@@ -25,6 +26,7 @@ std = [
"substrate-runtime-support/std",
"substrate-runtime-primitives/std",
"serde/std",
"serde_derive",
"substrate-codec/std",
"substrate-primitives/std",
"substrate-runtime-system/std",
@@ -27,6 +27,10 @@ extern crate substrate_runtime_support as runtime_support;
#[cfg(any(feature = "std", test))]
extern crate substrate_runtime_io as runtime_io;
#[cfg(feature = "std")]
#[macro_use]
extern crate serde_derive;
#[cfg(test)]
extern crate substrate_primitives;
extern crate substrate_runtime_primitives as runtime_primitives;
@@ -46,6 +50,8 @@ pub trait Trait: HasPublicAux + system::Trait {
decl_module! {
pub struct Module<T: Trait>;
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Call where aux: T::PublicAux {
fn set(aux, now: T::Value) -> Result = 0;
}
@@ -111,7 +117,7 @@ mod tests {
use runtime_support::storage::StorageValue;
use substrate_primitives::H256;
use runtime_primitives::BuildExternalities;
use runtime_primitives::traits::{HasPublicAux};
use runtime_primitives::traits::{HasPublicAux, BlakeTwo256};
use runtime_primitives::testing::{Digest, Header};
pub struct Test;
@@ -122,7 +128,7 @@ mod tests {
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = runtime_io::BlakeTwo256;
type Hashing = BlakeTwo256;
type Digest = Digest;
type AccountId = u64;
type Header = Header;