mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 20:01:08 +00:00
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:
committed by
Robert Habermeier
parent
4e844760a3
commit
b94cf078af
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user