mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 09:21:05 +00:00
Derivable Encode & Decode (#509)
* Derive macro for simple structs. * Derive Encode/Decode wherever we can. * Derive for enums. * Support discriminant. * Get rid of some repetition. * Support custom indices. * Derive codec for enums wherever possible. * Fix no_std * WASM rebuilt * Avoid excessive import. * Fix compilation. * Address review grumbles.
This commit is contained in:
committed by
Sergey Pepyakin
parent
6eece0174e
commit
96b3a8f92f
Generated
+23
@@ -3,6 +3,7 @@ name = "adder"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"polkadot-parachain 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1953,6 +1954,7 @@ dependencies = [
|
||||
"rhododendron 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-bft 0.1.0",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-network 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1964,6 +1966,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"tiny-keccak 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1976,6 +1979,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -2047,6 +2051,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"polkadot-primitives 0.1.0",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
@@ -2722,6 +2727,7 @@ dependencies = [
|
||||
"patricia-trie 0.1.0 (git+https://github.com/paritytech/parity.git)",
|
||||
"substrate-client 0.1.0",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-executor 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
@@ -2737,6 +2743,16 @@ dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-codec-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-executor"
|
||||
version = "0.1.0"
|
||||
@@ -2829,6 +2845,7 @@ dependencies = [
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-client 0.1.0",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-keyring 0.1.0",
|
||||
"substrate-network-libp2p 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
@@ -2875,6 +2892,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"substrate-serializer 0.1.0",
|
||||
"twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2990,6 +3008,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-consensus 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
@@ -3047,6 +3066,7 @@ dependencies = [
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -3172,6 +3192,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"substrate-runtime-support 0.1.0",
|
||||
]
|
||||
@@ -3223,6 +3244,7 @@ dependencies = [
|
||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
|
||||
@@ -3282,6 +3304,7 @@ dependencies = [
|
||||
"serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-keyring 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
|
||||
@@ -41,6 +41,7 @@ members = [
|
||||
"substrate/client",
|
||||
"substrate/client/db",
|
||||
"substrate/codec",
|
||||
"substrate/codec/derive",
|
||||
"substrate/environmental",
|
||||
"substrate/executor",
|
||||
"substrate/extrinsic-pool",
|
||||
|
||||
Generated
+16
-3
@@ -639,7 +639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -706,6 +706,15 @@ dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-codec-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-keyring"
|
||||
version = "0.1.0"
|
||||
@@ -723,10 +732,11 @@ dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
"rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)",
|
||||
"rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
@@ -781,6 +791,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-consensus 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
@@ -831,6 +842,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -954,6 +966,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"substrate-runtime-support 0.1.0",
|
||||
]
|
||||
@@ -1206,7 +1219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rlp 0.2.1 (git+https://github.com/paritytech/parity.git)" = "<none>"
|
||||
"checksum rlp 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89db7f8dfdd5eb7ab3ac3ece7a07fd273a680b4b224cb231181280e8996f9f0b"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "<none>"
|
||||
"checksum rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b03280c2813907a030785570c577fb27d3deec8da4c18566751ade94de0ace"
|
||||
"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -12,6 +12,7 @@ polkadot-consensus = { path = "../consensus" }
|
||||
polkadot-primitives = { path = "../primitives" }
|
||||
substrate-bft = { path = "../../substrate/bft" }
|
||||
substrate-codec = { path = "../../substrate/codec" }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive" }
|
||||
substrate-network = { path = "../../substrate/network" }
|
||||
substrate-primitives = { path = "../../substrate/primitives" }
|
||||
ed25519 = { path = "../../substrate/ed25519" }
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
use polkadot_primitives::{AccountId, Hash};
|
||||
use polkadot_primitives::parachain::{Id as ParaId, Collation};
|
||||
use codec;
|
||||
|
||||
use futures::sync::oneshot;
|
||||
|
||||
@@ -28,7 +27,7 @@ use std::time::{Duration, Instant};
|
||||
const COLLATION_LIFETIME: Duration = Duration::from_secs(60 * 5);
|
||||
|
||||
/// The role of the collator. Whether they're the primary or backup for this parachain.
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
#[derive(PartialEq, Debug, Clone, Copy, Encode, Decode)]
|
||||
pub enum Role {
|
||||
/// Primary collators should send collations whenever it's time.
|
||||
Primary = 0,
|
||||
@@ -36,22 +35,6 @@ pub enum Role {
|
||||
Backup = 1,
|
||||
}
|
||||
|
||||
impl codec::Encode for Role {
|
||||
fn encode_to<T: codec::Output>(&self, dest: &mut T) {
|
||||
dest.push_byte(*self as u8);
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Decode for Role {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
x if x == Role::Primary as u8 => Some(Role::Primary),
|
||||
x if x == Role::Backup as u8 => Some(Role::Backup),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A maintenance action for the collator set.
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[allow(dead_code)]
|
||||
|
||||
@@ -38,13 +38,15 @@ extern crate rhododendron;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
mod collator_pool;
|
||||
mod local_collations;
|
||||
mod router;
|
||||
pub mod consensus;
|
||||
|
||||
use codec::{Decode, Encode, Input, Output};
|
||||
use codec::{Decode, Encode};
|
||||
use futures::sync::oneshot;
|
||||
use parking_lot::Mutex;
|
||||
use polkadot_consensus::{Statement, SignedStatement, GenericStatement};
|
||||
@@ -74,36 +76,11 @@ type FullStatus = GenericFullStatus<Block>;
|
||||
pub type NetworkService = ::substrate_network::Service<Block, PolkadotProtocol>;
|
||||
|
||||
/// Status of a Polkadot node.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct Status {
|
||||
collating_for: Option<(AccountId, ParaId)>,
|
||||
}
|
||||
|
||||
impl Encode for Status {
|
||||
fn encode_to<T: codec::Output>(&self, dest: &mut T) {
|
||||
match self.collating_for {
|
||||
Some(ref details) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(details);
|
||||
}
|
||||
None => {
|
||||
dest.push_byte(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Status {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
let collating_for = match input.read_byte()? {
|
||||
0 => None,
|
||||
1 => Some(Decode::decode(input)?),
|
||||
_ => return None,
|
||||
};
|
||||
Some(Status { collating_for })
|
||||
}
|
||||
}
|
||||
|
||||
struct BlockDataRequest {
|
||||
attempted_peers: HashSet<SessionKey>,
|
||||
consensus_parent: Hash,
|
||||
@@ -207,7 +184,7 @@ impl CurrentConsensus {
|
||||
}
|
||||
|
||||
/// Polkadot-specific messages.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Encode, Decode)]
|
||||
pub enum Message {
|
||||
/// signed statement and localized parent hash.
|
||||
Statement(Hash, SignedStatement),
|
||||
@@ -224,59 +201,6 @@ pub enum Message {
|
||||
Collation(Hash, Collation),
|
||||
}
|
||||
|
||||
impl Encode for Message {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
Message::Statement(ref h, ref s) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(h);
|
||||
dest.push(s);
|
||||
}
|
||||
Message::SessionKey(ref k) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(k);
|
||||
}
|
||||
Message::RequestBlockData(ref id, ref r, ref d) => {
|
||||
dest.push_byte(2);
|
||||
dest.push(id);
|
||||
dest.push(r);
|
||||
dest.push(d);
|
||||
}
|
||||
Message::BlockData(ref id, ref d) => {
|
||||
dest.push_byte(3);
|
||||
dest.push(id);
|
||||
dest.push(d);
|
||||
}
|
||||
Message::CollatorRole(ref r) => {
|
||||
dest.push_byte(4);
|
||||
dest.push(r);
|
||||
}
|
||||
Message::Collation(ref h, ref c) => {
|
||||
dest.push_byte(5);
|
||||
dest.push(h);
|
||||
dest.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Message {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(Message::Statement(Decode::decode(input)?, Decode::decode(input)?)),
|
||||
1 => Some(Message::SessionKey(Decode::decode(input)?)),
|
||||
2 => {
|
||||
let x: (_, _, _) = Decode::decode(input)?;
|
||||
Some(Message::RequestBlockData(x.0, x.1, x.2))
|
||||
}
|
||||
3 => Some(Message::BlockData(Decode::decode(input)?, Decode::decode(input)?)),
|
||||
4 => Some(Message::CollatorRole(Decode::decode(input)?)),
|
||||
5 => Some(Message::Collation(Decode::decode(input)?, Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn send_polkadot_message(ctx: &mut Context<Block>, to: NodeIndex, message: Message) {
|
||||
trace!(target: "p_net", "Sending polkadot message to {}: {:?}", to, message);
|
||||
let encoded = message.encode();
|
||||
|
||||
@@ -6,6 +6,7 @@ description = "Types and utilities for creating and working with parachains"
|
||||
|
||||
[dependencies]
|
||||
substrate-codec = { path = "../../substrate/codec", default-features = false }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive", default-features = false }
|
||||
wasmi = { version = "0.4", optional = true }
|
||||
error-chain = { version = "0.12", optional = true }
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
/// Re-export of substrate-codec.
|
||||
pub extern crate substrate_codec as codec;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
|
||||
@@ -61,14 +64,14 @@ extern crate error_chain;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
use codec::{Encode, Decode, Input, Output};
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod wasm;
|
||||
|
||||
/// Validation parameters for evaluating the parachain validity function.
|
||||
// TODO: consolidated ingress and balance downloads
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct ValidationParams {
|
||||
/// The collation body.
|
||||
@@ -77,45 +80,15 @@ pub struct ValidationParams {
|
||||
pub parent_head: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Encode for ValidationParams {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.block_data);
|
||||
dest.push(&self.parent_head);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for ValidationParams {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(ValidationParams {
|
||||
block_data: Decode::decode(input)?,
|
||||
parent_head: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of parachain validation.
|
||||
// TODO: egress and balance uploads
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct ValidationResult {
|
||||
/// New head data that should be included in the relay chain state.
|
||||
pub head_data: Vec<u8>
|
||||
}
|
||||
|
||||
impl Encode for ValidationResult {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.head_data);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for ValidationResult {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(ValidationResult {
|
||||
head_data: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Load the validation params from memory when implementing a Rust parachain.
|
||||
///
|
||||
/// Offset and length must have been provided by the validation
|
||||
|
||||
@@ -16,66 +16,35 @@
|
||||
|
||||
//! Basic parachain that adds a number as part of its state.
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate polkadot_parachain as parachain;
|
||||
extern crate tiny_keccak;
|
||||
|
||||
use parachain::ValidationParams;
|
||||
use parachain::codec::{Decode, Encode, Input, Output};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
// Head data for this parachain.
|
||||
#[derive(Default, Clone)]
|
||||
/// Head data for this parachain.
|
||||
#[derive(Default, Clone, Encode, Decode)]
|
||||
struct HeadData {
|
||||
// Block number
|
||||
/// Block number
|
||||
number: u64,
|
||||
// parent block keccak256
|
||||
/// parent block keccak256
|
||||
parent_hash: [u8; 32],
|
||||
// hash of post-execution state.
|
||||
/// hash of post-execution state.
|
||||
post_state: [u8; 32],
|
||||
}
|
||||
|
||||
impl Encode for HeadData {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.number);
|
||||
dest.push(&self.parent_hash);
|
||||
dest.push(&self.post_state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for HeadData {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(HeadData {
|
||||
number: Decode::decode(input)?,
|
||||
parent_hash: Decode::decode(input)?,
|
||||
post_state: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Block data for this parachain.
|
||||
#[derive(Default, Clone)]
|
||||
/// Block data for this parachain.
|
||||
#[derive(Default, Clone, Encode, Decode)]
|
||||
struct BlockData {
|
||||
// State to begin from.
|
||||
/// State to begin from.
|
||||
state: u64,
|
||||
// Amount to add (overflowing)
|
||||
/// Amount to add (overflowing)
|
||||
add: u64,
|
||||
}
|
||||
|
||||
impl Encode for BlockData {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.state);
|
||||
dest.push(&self.add);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for BlockData {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockData {
|
||||
state: Decode::decode(input)?,
|
||||
add: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const TEST_CODE: &[u8] = include_bytes!("res/adder.wasm");
|
||||
|
||||
fn hash_state(state: u64) -> [u8; 32] {
|
||||
|
||||
Binary file not shown.
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
serde = { version = "1.0", default_features = false }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
substrate-codec = { path = "../../substrate/codec", default_features = false }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive", default_features = false }
|
||||
substrate-primitives = { path = "../../substrate/primitives", default_features = false }
|
||||
substrate-runtime-std = { path = "../../substrate/runtime-std", default_features = false }
|
||||
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives", default_features = false }
|
||||
|
||||
@@ -21,13 +21,16 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(not(feature = "std"), feature(alloc))]
|
||||
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate substrate_primitives as primitives;
|
||||
extern crate substrate_runtime_primitives as runtime_primitives;
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate substrate_serializer;
|
||||
|
||||
extern crate substrate_codec as codec;
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[macro_use]
|
||||
@@ -42,7 +45,6 @@ use primitives::bytes;
|
||||
use rstd::prelude::*;
|
||||
use runtime_primitives::traits::BlakeTwo256;
|
||||
use runtime_primitives::generic;
|
||||
use codec::{Encode, Decode, Input, Output};
|
||||
|
||||
pub mod parachain;
|
||||
|
||||
@@ -105,18 +107,6 @@ pub type Balance = u128;
|
||||
pub type BlockId = generic::BlockId<Block>;
|
||||
|
||||
/// A log entry in the block.
|
||||
#[derive(PartialEq, Eq, Clone, Default)]
|
||||
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Log(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
impl Decode for Log {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Vec::<u8>::decode(input).map(Log)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Log {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
self.0.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
//! Polkadot parachain types.
|
||||
|
||||
use codec::{Encode, Decode, Input, Output};
|
||||
use rstd::prelude::*;
|
||||
use rstd::cmp::Ordering;
|
||||
use super::Hash;
|
||||
@@ -28,7 +27,7 @@ use primitives::bytes;
|
||||
pub type CandidateSignature = ::runtime_primitives::Ed25519Signature;
|
||||
|
||||
/// Unique identifier of a parachain.
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Id(u32);
|
||||
|
||||
@@ -47,20 +46,8 @@ impl Id {
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Id {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
u32::decode(input).map(Id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Id {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.using_encoded(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifier for a chain, either one of a number of parachains or the relay chain.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum Chain {
|
||||
/// The relay chain.
|
||||
@@ -69,31 +56,8 @@ pub enum Chain {
|
||||
Parachain(Id),
|
||||
}
|
||||
|
||||
impl Decode for Chain {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
let disc = input.read_byte()?;
|
||||
match disc {
|
||||
0 => Some(Chain::Relay),
|
||||
1 => Some(Chain::Parachain(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Chain {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
Chain::Relay => { dest.push_byte(0); }
|
||||
Chain::Parachain(id) => {
|
||||
dest.push_byte(1u8);
|
||||
dest.push(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The duty roster specifying what jobs each validator must do.
|
||||
#[derive(Clone, PartialEq)]
|
||||
#[derive(Clone, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Default, Debug))]
|
||||
pub struct DutyRoster {
|
||||
/// Lookup from validator index to chain on which that validator has a duty to validate.
|
||||
@@ -103,22 +67,6 @@ pub struct DutyRoster {
|
||||
pub guarantor_duty: Vec<Chain>,
|
||||
}
|
||||
|
||||
impl Decode for DutyRoster {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(DutyRoster {
|
||||
validator_duty: Decode::decode(input)?,
|
||||
guarantor_duty: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for DutyRoster {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.validator_duty);
|
||||
dest.push(&self.guarantor_duty);
|
||||
}
|
||||
}
|
||||
|
||||
/// Extrinsic data for a parachain.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
@@ -127,7 +75,7 @@ impl Encode for DutyRoster {
|
||||
pub struct Extrinsic;
|
||||
|
||||
/// Candidate receipt type.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
@@ -150,34 +98,6 @@ pub struct CandidateReceipt {
|
||||
pub block_data_hash: Hash,
|
||||
}
|
||||
|
||||
impl Encode for CandidateReceipt {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.parachain_index);
|
||||
dest.push(&self.collator);
|
||||
dest.push(&self.signature);
|
||||
dest.push(&self.head_data.0);
|
||||
dest.push(&self.balance_uploads);
|
||||
dest.push(&self.egress_queue_roots);
|
||||
dest.push(&self.fees);
|
||||
dest.push(&self.block_data_hash);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for CandidateReceipt {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(CandidateReceipt {
|
||||
parachain_index: Decode::decode(input)?,
|
||||
collator: Decode::decode(input)?,
|
||||
signature: Decode::decode(input)?,
|
||||
head_data: Decode::decode(input).map(HeadData)?,
|
||||
balance_uploads: Decode::decode(input)?,
|
||||
egress_queue_roots: Decode::decode(input)?,
|
||||
fees: Decode::decode(input)?,
|
||||
block_data_hash: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CandidateReceipt {
|
||||
/// Get the blake2_256 hash
|
||||
#[cfg(feature = "std")]
|
||||
@@ -213,7 +133,7 @@ impl Ord for CandidateReceipt {
|
||||
}
|
||||
|
||||
/// A full collation.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
@@ -224,22 +144,6 @@ pub struct Collation {
|
||||
pub receipt: CandidateReceipt,
|
||||
}
|
||||
|
||||
impl Decode for Collation {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Collation {
|
||||
block_data: Decode::decode(input)?,
|
||||
receipt: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Collation {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.block_data);
|
||||
dest.push(&self.receipt);
|
||||
}
|
||||
}
|
||||
|
||||
/// Parachain ingress queue message.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
@@ -256,7 +160,7 @@ pub struct ConsolidatedIngress(pub Vec<(Id, Vec<Message>)>);
|
||||
/// Parachain block data.
|
||||
///
|
||||
/// contains everything required to validate para-block, may contain block and witness data
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct BlockData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
@@ -268,26 +172,13 @@ impl BlockData {
|
||||
BlakeTwo256::hash(&self.0[..])
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for BlockData {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockData(Decode::decode(input)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for BlockData {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Parachain header raw bytes wrapper type.
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Header(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Parachain head data included in the chain.
|
||||
#[derive(PartialEq, Eq, Clone, PartialOrd, Ord)]
|
||||
#[derive(PartialEq, Eq, Clone, PartialOrd, Ord, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
@@ -297,22 +188,10 @@ pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8
|
||||
pub struct ValidationCode(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Activitiy bit field
|
||||
#[derive(PartialEq, Eq, Clone, Default)]
|
||||
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Activity(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
impl Decode for Activity {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Vec::<u8>::decode(input).map(Activity)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Activity {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
self.0.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
/// Statements which can be made about parachain candidates.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
|
||||
+17
-3
@@ -454,6 +454,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -639,7 +640,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -706,6 +707,15 @@ dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-codec-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-keyring"
|
||||
version = "0.1.0"
|
||||
@@ -723,10 +733,11 @@ dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
"rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)",
|
||||
"rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
@@ -781,6 +792,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-consensus 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
@@ -831,6 +843,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -954,6 +967,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"substrate-runtime-support 0.1.0",
|
||||
]
|
||||
@@ -1206,7 +1220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rlp 0.2.1 (git+https://github.com/paritytech/parity.git)" = "<none>"
|
||||
"checksum rlp 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89db7f8dfdd5eb7ab3ac3ece7a07fd273a680b4b224cb231181280e8996f9f0b"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "<none>"
|
||||
"checksum rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b03280c2813907a030785570c577fb27d3deec8da4c18566751ade94de0ace"
|
||||
"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -5,5 +5,6 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
substrate-codec = { path = "../../substrate/codec" }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive" }
|
||||
substrate-primitives = { path = "../../substrate/primitives" }
|
||||
polkadot-primitives = { path = "../primitives" }
|
||||
|
||||
@@ -31,8 +31,6 @@ use std::collections::hash_map::{HashMap, Entry};
|
||||
use std::hash::Hash;
|
||||
use std::fmt::Debug;
|
||||
|
||||
use codec::{Decode, Encode, Input, Output};
|
||||
|
||||
/// Context for the statement table.
|
||||
pub trait Context {
|
||||
/// A authority ID
|
||||
@@ -70,78 +68,30 @@ pub trait Context {
|
||||
}
|
||||
|
||||
/// Statements circulated among peers.
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode)]
|
||||
pub enum Statement<C, D> {
|
||||
/// Broadcast by a authority to indicate that this is his candidate for
|
||||
/// inclusion.
|
||||
///
|
||||
/// Broadcasting two different candidate messages per round is not allowed.
|
||||
#[codec(index = "1")]
|
||||
Candidate(C),
|
||||
/// Broadcast by a authority to attest that the candidate with given digest
|
||||
/// is valid.
|
||||
#[codec(index = "2")]
|
||||
Valid(D),
|
||||
/// Broadcast by a authority to attest that the auxiliary data for a candidate
|
||||
/// with given digest is available.
|
||||
Available(D),
|
||||
/// Broadcast by a authority to attest that the candidate with given digest
|
||||
/// is invalid.
|
||||
#[codec(index = "3")]
|
||||
Invalid(D),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
enum StatementKind {
|
||||
Candidate = 1,
|
||||
Valid = 2,
|
||||
Invalid = 3,
|
||||
Available = 4,
|
||||
}
|
||||
|
||||
impl<C: Encode, D: Encode> Encode for Statement<C, D> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
Statement::Candidate(ref candidate) => {
|
||||
dest.push_byte(StatementKind::Candidate as u8);
|
||||
dest.push(candidate);
|
||||
}
|
||||
Statement::Valid(ref digest) => {
|
||||
dest.push_byte(StatementKind::Valid as u8);
|
||||
dest.push(digest);
|
||||
}
|
||||
Statement::Invalid(ref digest) => {
|
||||
dest.push_byte(StatementKind::Invalid as u8);
|
||||
dest.push(digest);
|
||||
}
|
||||
Statement::Available(ref digest) => {
|
||||
dest.push_byte(StatementKind::Available as u8);
|
||||
dest.push(digest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Decode, D: Decode> Decode for Statement<C, D> {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
match value.read_byte() {
|
||||
Some(x) if x == StatementKind::Candidate as u8 => {
|
||||
Decode::decode(value).map(Statement::Candidate)
|
||||
}
|
||||
Some(x) if x == StatementKind::Valid as u8 => {
|
||||
Decode::decode(value).map(Statement::Valid)
|
||||
}
|
||||
Some(x) if x == StatementKind::Invalid as u8 => {
|
||||
Decode::decode(value).map(Statement::Invalid)
|
||||
}
|
||||
Some(x) if x == StatementKind::Available as u8 => {
|
||||
Decode::decode(value).map(Statement::Available)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Broadcast by a authority to attest that the auxiliary data for a candidate
|
||||
/// with given digest is available.
|
||||
#[codec(index = "4")]
|
||||
Available(D),
|
||||
}
|
||||
|
||||
/// A signed statement.
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Encode, Decode)]
|
||||
pub struct SignedStatement<C, D, V, S> {
|
||||
/// The statement.
|
||||
pub statement: Statement<C, D>,
|
||||
@@ -151,23 +101,6 @@ pub struct SignedStatement<C, D, V, S> {
|
||||
pub sender: V,
|
||||
}
|
||||
|
||||
impl<C: Encode, D: Encode, V: Encode, S: Encode> Encode for SignedStatement<C, D, V, S> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.statement);
|
||||
dest.push(&self.signature);
|
||||
dest.push(&self.sender);
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Decode, D: Decode, V: Decode, S: Decode> Decode for SignedStatement<C, D, V, S> {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
Some(SignedStatement {
|
||||
statement: Decode::decode(value)?,
|
||||
signature: Decode::decode(value)?,
|
||||
sender: Decode::decode(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
/// Misbehavior: voting more than one way on candidate validity.
|
||||
///
|
||||
/// Since there are three possible ways to vote, a double vote is possible in
|
||||
|
||||
@@ -18,6 +18,9 @@ extern crate substrate_codec as codec;
|
||||
extern crate substrate_primitives;
|
||||
extern crate polkadot_primitives as primitives;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
pub mod generic;
|
||||
|
||||
pub use generic::Table;
|
||||
|
||||
@@ -6,4 +6,5 @@ description = "Test parachain which adds to a number as its state transition"
|
||||
|
||||
[dependencies]
|
||||
polkadot-parachain = { path = "../../parachain/", default-features = false }
|
||||
substrate-codec-derive = { path = "../../../substrate/codec/derive", default-features = false }
|
||||
tiny-keccak = "1.4"
|
||||
|
||||
@@ -18,13 +18,16 @@
|
||||
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
extern crate polkadot_parachain as parachain;
|
||||
extern crate tiny_keccak;
|
||||
|
||||
use parachain::codec::{Decode, Encode, Input, Output};
|
||||
use parachain::codec::{self, Encode};
|
||||
|
||||
/// Head data for this parachain.
|
||||
#[derive(Default, Clone, Hash, Eq, PartialEq)]
|
||||
#[derive(Default, Clone, Hash, Eq, PartialEq, Encode, Decode)]
|
||||
pub struct HeadData {
|
||||
/// Block number
|
||||
pub number: u64,
|
||||
@@ -40,26 +43,8 @@ impl HeadData {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for HeadData {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.number);
|
||||
dest.push(&self.parent_hash);
|
||||
dest.push(&self.post_state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for HeadData {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(HeadData {
|
||||
number: Decode::decode(input)?,
|
||||
parent_hash: Decode::decode(input)?,
|
||||
post_state: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Block data for this parachain.
|
||||
#[derive(Default, Clone)]
|
||||
#[derive(Default, Clone, Encode, Decode)]
|
||||
pub struct BlockData {
|
||||
/// State to begin from.
|
||||
pub state: u64,
|
||||
@@ -67,22 +52,6 @@ pub struct BlockData {
|
||||
pub add: u64,
|
||||
}
|
||||
|
||||
impl Encode for BlockData {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.state);
|
||||
dest.push(&self.add);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for BlockData {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockData {
|
||||
state: Decode::decode(input)?,
|
||||
add: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_state(state: u64) -> [u8; 32] {
|
||||
::tiny_keccak::keccak256(state.encode().as_slice())
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ substrate-client = { path = "../../../substrate/client" }
|
||||
substrate-state-machine = { path = "../../../substrate/state-machine" }
|
||||
substrate-runtime-support = { path = "../../../substrate/runtime-support" }
|
||||
substrate-codec = { path = "../../../substrate/codec" }
|
||||
substrate-codec-derive = { path = "../../../substrate/codec/derive" }
|
||||
substrate-executor = { path = "../../../substrate/executor" }
|
||||
substrate-state-db = { path = "../../../substrate/state-db" }
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use kvdb::{KeyValueDB, DBTransaction};
|
||||
|
||||
use client::blockchain::Cache as BlockchainCache;
|
||||
use client::error::Result as ClientResult;
|
||||
use codec::{Codec, Encode, Decode, Input, Output};
|
||||
use codec::{Codec, Encode, Decode};
|
||||
use primitives::AuthorityId;
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Block as BlockT, As, NumberFor};
|
||||
@@ -107,6 +107,7 @@ pub struct Entry<N, T: Clone> {
|
||||
|
||||
/// Internal representation of the single cache entry. The entry points to the
|
||||
/// previous entry in the cache, allowing us to traverse back in time in list-style.
|
||||
#[derive(Encode, Decode)]
|
||||
#[cfg_attr(test, derive(Debug, PartialEq))]
|
||||
struct StorageEntry<N, T> {
|
||||
/// None if valid from the beginning
|
||||
@@ -298,22 +299,6 @@ fn read_storage_entry<Block, T>(
|
||||
.map_err(db_err)
|
||||
}
|
||||
|
||||
impl<N: Encode, T: Encode> Encode for StorageEntry<N, T> {
|
||||
fn encode_to<O: Output>(&self, dest: &mut O) {
|
||||
dest.push(&self.prev_valid_from);
|
||||
dest.push(&self.value);
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Decode, T: Decode> Decode for StorageEntry<N, T> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(StorageEntry {
|
||||
prev_valid_from: Decode::decode(input)?,
|
||||
value: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use runtime_primitives::testing::Block as RawBlock;
|
||||
|
||||
@@ -33,6 +33,9 @@ extern crate substrate_state_db as state_db;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate kvdb_memorydb;
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "substrate-codec-derive"
|
||||
description = "Serialization and deserialization derive macro"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
syn = "0.14"
|
||||
quote = "0.6"
|
||||
proc-macro2 = "0.4"
|
||||
|
||||
[dev-dependencies]
|
||||
substrate-codec = { path = "../" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright 2018 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/>.
|
||||
|
||||
use proc_macro2::{Span, TokenStream, Ident};
|
||||
use syn::{
|
||||
Data, Fields,
|
||||
spanned::Spanned,
|
||||
};
|
||||
|
||||
pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream {
|
||||
let call_site = Span::call_site();
|
||||
match *data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(_) | Fields::Unnamed(_) => create_instance(
|
||||
call_site,
|
||||
quote! { #type_name },
|
||||
input,
|
||||
&data.fields,
|
||||
),
|
||||
Fields::Unit => {
|
||||
quote_spanned! {call_site =>
|
||||
drop(#input);
|
||||
Some(#type_name)
|
||||
}
|
||||
},
|
||||
},
|
||||
Data::Enum(ref data) => {
|
||||
assert!(data.variants.len() < 256, "Currently only enums with at most 256 variants are encodable.");
|
||||
|
||||
let recurse = data.variants.iter().enumerate().map(|(i, v)| {
|
||||
let name = &v.ident;
|
||||
let index = super::index(v, i);
|
||||
|
||||
let create = create_instance(
|
||||
call_site,
|
||||
quote! { #type_name :: #name },
|
||||
input,
|
||||
&v.fields,
|
||||
);
|
||||
|
||||
quote_spanned! { v.span() =>
|
||||
x if x == #index as u8 => {
|
||||
#create
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
match #input.read_byte()? {
|
||||
#( #recurse )*
|
||||
_ => None,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
Data::Union(_) => panic!("Union types are not supported."),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_instance(call_site: Span, name: TokenStream, input: &TokenStream, fields: &Fields) -> TokenStream {
|
||||
match *fields {
|
||||
Fields::Named(ref fields) => {
|
||||
let recurse = fields.named.iter().map(|f| {
|
||||
let name = &f.ident;
|
||||
let field = quote_spanned!(call_site => #name);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#field: ::codec::Decode::decode(#input)?
|
||||
}
|
||||
});
|
||||
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name {
|
||||
#( #recurse, )*
|
||||
})
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref fields) => {
|
||||
let recurse = fields.unnamed.iter().map(|f| {
|
||||
quote_spanned! { f.span() =>
|
||||
::codec::Decode::decode(#input)?
|
||||
}
|
||||
});
|
||||
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name (
|
||||
#( #recurse, )*
|
||||
))
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Copyright 2018 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/>.
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use core::str::from_utf8;
|
||||
#[cfg(feature = "std")]
|
||||
use std::str::from_utf8;
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use syn::{
|
||||
Data, Field, Fields, Ident, Index,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token::Comma,
|
||||
};
|
||||
|
||||
type FieldsList = Punctuated<Field, Comma>;
|
||||
|
||||
fn encode_fields<F>(
|
||||
dest: &TokenStream,
|
||||
fields: &FieldsList,
|
||||
field_name: F,
|
||||
) -> TokenStream where
|
||||
F: Fn(usize, &Option<Ident>) -> TokenStream,
|
||||
{
|
||||
let recurse = fields.iter().enumerate().map(|(i, f)| {
|
||||
let field = field_name(i, &f.ident);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#dest.push(#field);
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#( #recurse )*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn quote(data: &Data, type_name: &Ident, self_: &TokenStream, dest: &TokenStream) -> TokenStream {
|
||||
let call_site = Span::call_site();
|
||||
match *data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref fields) => encode_fields(
|
||||
dest,
|
||||
&fields.named,
|
||||
|_, name| quote_spanned!(call_site => &#self_.#name),
|
||||
),
|
||||
Fields::Unnamed(ref fields) => encode_fields(
|
||||
dest,
|
||||
&fields.unnamed,
|
||||
|i, _| {
|
||||
let index = Index { index: i as u32, span: call_site };
|
||||
quote_spanned!(call_site => &#self_.#index)
|
||||
},
|
||||
),
|
||||
Fields::Unit => quote_spanned! { call_site =>
|
||||
drop(#dest);
|
||||
},
|
||||
},
|
||||
Data::Enum(ref data) => {
|
||||
assert!(data.variants.len() < 256, "Currently only enums with at most 256 variants are encodable.");
|
||||
|
||||
let recurse = data.variants.iter().enumerate().map(|(i, f)| {
|
||||
let name = &f.ident;
|
||||
let index = super::index(f, i);
|
||||
|
||||
match f.fields {
|
||||
Fields::Named(ref fields) => {
|
||||
let field_name = |_, ident: &Option<Ident>| quote_spanned!(call_site => #ident);
|
||||
let names = fields.named
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, f)| field_name(i, &f.ident));
|
||||
|
||||
let encode_fields = encode_fields(
|
||||
dest,
|
||||
&fields.named,
|
||||
|a, b| field_name(a, b),
|
||||
);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name { #( ref #names, )* } => {
|
||||
#dest.push_byte(#index as u8);
|
||||
#encode_fields
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref fields) => {
|
||||
let field_name = |i, _: &Option<Ident>| {
|
||||
let data = stringify(i as u8);
|
||||
let ident = from_utf8(&data).expect("We never go beyond ASCII");
|
||||
let ident = Ident::new(ident, call_site);
|
||||
quote_spanned!(call_site => #ident)
|
||||
};
|
||||
let names = fields.unnamed
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, f)| field_name(i, &f.ident));
|
||||
|
||||
let encode_fields = encode_fields(
|
||||
dest,
|
||||
&fields.unnamed,
|
||||
|a, b| field_name(a, b),
|
||||
);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name ( #( ref #names, )* ) => {
|
||||
#dest.push_byte(#index as u8);
|
||||
#encode_fields
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name => {
|
||||
#dest.push_byte(#index as u8);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
match *#self_ {
|
||||
#( #recurse )*,
|
||||
}
|
||||
}
|
||||
},
|
||||
Data::Union(_) => panic!("Union types are not supported."),
|
||||
}
|
||||
}
|
||||
pub fn stringify(id: u8) -> [u8; 2] {
|
||||
const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz";
|
||||
let len = CHARS.len() as u8;
|
||||
let symbol = |id: u8| CHARS[(id % len) as usize];
|
||||
let a = symbol(id);
|
||||
let b = symbol(id / len);
|
||||
|
||||
[a, b]
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// Copyright 2018 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/>.
|
||||
|
||||
//! Derives serialization and deserialization codec for complex structs for simple marshalling.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(not(feature = "std"), feature(alloc))]
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{DeriveInput, Generics, GenericParam, Ident};
|
||||
|
||||
mod decode;
|
||||
mod encode;
|
||||
|
||||
const ENCODE_ERR: &str = "derive(Encode) failed";
|
||||
|
||||
#[proc_macro_derive(Encode, attributes(codec))]
|
||||
pub fn encode_derive(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = syn::parse(input).expect(ENCODE_ERR);
|
||||
let name = &input.ident;
|
||||
|
||||
let generics = add_trait_bounds(input.generics, parse_quote!(::codec::Encode));
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let self_ = quote!(self);
|
||||
let dest_ = quote!(dest);
|
||||
let encoding = encode::quote(&input.data, name, &self_, &dest_);
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics ::codec::Encode for #name #ty_generics #where_clause {
|
||||
fn encode_to<EncOut: ::codec::Output>(&#self_, #dest_: &mut EncOut) {
|
||||
#encoding
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Decode, attributes(codec))]
|
||||
pub fn decode_derive(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = syn::parse(input).expect(ENCODE_ERR);
|
||||
let name = &input.ident;
|
||||
|
||||
let generics = add_trait_bounds(input.generics, parse_quote!(::codec::Decode));
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let input_ = quote!(input);
|
||||
let decoding = decode::quote(&input.data, name, &input_);
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics ::codec::Decode for #name #ty_generics #where_clause {
|
||||
fn decode<DecIn: ::codec::Input>(#input_: &mut DecIn) -> Option<Self> {
|
||||
#decoding
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
fn add_trait_bounds(mut generics: Generics, bounds: syn::TypeParamBound) -> Generics {
|
||||
for param in &mut generics.params {
|
||||
if let GenericParam::Type(ref mut type_param) = *param {
|
||||
type_param.bounds.push(bounds.clone());
|
||||
}
|
||||
}
|
||||
generics
|
||||
}
|
||||
|
||||
fn index(v: &syn::Variant, i: usize) -> proc_macro2::TokenStream {
|
||||
// look for an index in attributes
|
||||
let index = v.attrs.iter().filter_map(|attr| {
|
||||
let pair = attr.path.segments.first()?;
|
||||
let seg = pair.value();
|
||||
|
||||
if seg.ident == Ident::new("codec", seg.ident.span()) {
|
||||
assert_eq!(attr.path.segments.len(), 1);
|
||||
|
||||
let meta = attr.interpret_meta();
|
||||
if let Some(syn::Meta::List(ref l)) = meta {
|
||||
if let syn::NestedMeta::Meta(syn::Meta::NameValue(ref nv)) = l.nested.last().unwrap().value() {
|
||||
assert_eq!(nv.ident, Ident::new("index", nv.ident.span()));
|
||||
if let syn::Lit::Str(ref s) = nv.lit {
|
||||
let byte: u8 = s.value().parse().expect("Numeric index expected.");
|
||||
return Some(byte)
|
||||
}
|
||||
panic!("Invalid syntax for `codec` attribute: Expected string literal.")
|
||||
}
|
||||
}
|
||||
panic!("Invalid syntax for `codec` attribute: Expected `name = value` pair.")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).next();
|
||||
|
||||
// then fallback to discriminant or just index
|
||||
index.map(|i| quote! { #i })
|
||||
.unwrap_or_else(|| v.discriminant
|
||||
.as_ref()
|
||||
.map(|&(_, ref expr)| quote! { #expr })
|
||||
.unwrap_or_else(|| quote! { #i })
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
// Copyright 2018 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/>.
|
||||
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
|
||||
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||
struct Unit;
|
||||
|
||||
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||
struct Indexed(u32, u64);
|
||||
|
||||
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||
struct Struct<A, B, C> {
|
||||
pub a: A,
|
||||
pub b: B,
|
||||
pub c: C,
|
||||
}
|
||||
|
||||
type TestType = Struct<u32, u64, Vec<u8>>;
|
||||
|
||||
impl <A, B, C> Struct<A, B, C> {
|
||||
fn new(a: A, b: B, c: C) -> Self {
|
||||
Self { a, b, c }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||
enum EnumType {
|
||||
#[codec(index = "15")]
|
||||
A,
|
||||
B(u32, u64),
|
||||
C {
|
||||
a: u32,
|
||||
b: u64,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Encode, Decode)]
|
||||
enum EnumWithDiscriminant {
|
||||
A = 1,
|
||||
B = 15,
|
||||
C = 255,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_work_for_simple_enum() {
|
||||
let a = EnumType::A;
|
||||
let b = EnumType::B(1, 2);
|
||||
let c = EnumType::C { a: 1, b: 2 };
|
||||
|
||||
a.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &b"\x0f");
|
||||
});
|
||||
b.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0");
|
||||
});
|
||||
c.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0");
|
||||
});
|
||||
|
||||
let mut da: &[u8] = b"\x0f";
|
||||
assert_eq!(EnumType::decode(&mut da), Some(a));
|
||||
let mut db: &[u8] = b"\x01\x01\0\0\0\x02\0\0\0\0\0\0\0";
|
||||
assert_eq!(EnumType::decode(&mut db), Some(b));
|
||||
let mut dc: &[u8] = b"\x02\x01\0\0\0\x02\0\0\0\0\0\0\0";
|
||||
assert_eq!(EnumType::decode(&mut dc), Some(c));
|
||||
let mut dz: &[u8] = &[0];
|
||||
assert_eq!(EnumType::decode(&mut dz), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_work_for_enum_with_discriminant() {
|
||||
EnumWithDiscriminant::A.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &[1]);
|
||||
});
|
||||
EnumWithDiscriminant::B.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &[15]);
|
||||
});
|
||||
EnumWithDiscriminant::C.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &[255]);
|
||||
});
|
||||
|
||||
let mut da: &[u8] = &[1];
|
||||
assert_eq!(EnumWithDiscriminant::decode(&mut da), Some(EnumWithDiscriminant::A));
|
||||
let mut db: &[u8] = &[15];
|
||||
assert_eq!(EnumWithDiscriminant::decode(&mut db), Some(EnumWithDiscriminant::B));
|
||||
let mut dc: &[u8] = &[255];
|
||||
assert_eq!(EnumWithDiscriminant::decode(&mut dc), Some(EnumWithDiscriminant::C));
|
||||
let mut dz: &[u8] = &[2];
|
||||
assert_eq!(EnumWithDiscriminant::decode(&mut dz), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_derive_encode() {
|
||||
let v = TestType::new(15, 9, b"Hello world".to_vec());
|
||||
|
||||
v.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &b"\x0f\0\0\0\x09\0\0\0\0\0\0\0\x0b\0\0\0Hello world")
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_derive_decode() {
|
||||
let slice = b"\x0f\0\0\0\x09\0\0\0\0\0\0\0\x0b\0\0\0Hello world".to_vec();
|
||||
|
||||
let v = TestType::decode(&mut &*slice);
|
||||
|
||||
assert_eq!(v, Some(TestType::new(15, 9, b"Hello world".to_vec())));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_work_for_unit() {
|
||||
let v = Unit;
|
||||
|
||||
v.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &[]);
|
||||
});
|
||||
|
||||
let mut a: &[u8] = &[];
|
||||
assert_eq!(Unit::decode(&mut a), Some(Unit));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_work_for_indexed() {
|
||||
let v = Indexed(1, 2);
|
||||
|
||||
v.using_encoded(|ref slice| {
|
||||
assert_eq!(slice, &b"\x01\0\0\0\x02\0\0\0\0\0\0\0")
|
||||
});
|
||||
|
||||
let mut v: &[u8] = b"\x01\0\0\0\x02\0\0\0\0\0\0\0";
|
||||
assert_eq!(Indexed::decode(&mut v), Some(Indexed(1, 2)));
|
||||
}
|
||||
@@ -20,6 +20,7 @@ use alloc::vec::Vec;
|
||||
use alloc::boxed::Box;
|
||||
use core::{mem, slice};
|
||||
use arrayvec::ArrayVec;
|
||||
|
||||
/// Trait that allows reading of data into a slice.
|
||||
pub trait Input {
|
||||
/// Read into the provided input slice. Returns the number of bytes read.
|
||||
@@ -113,6 +114,7 @@ pub trait Decode: Sized {
|
||||
|
||||
/// Trait that allows zero-copy read/write of value-references to/from slices in LE format.
|
||||
pub trait Codec: Decode + Encode {}
|
||||
|
||||
impl<S: Decode + Encode> Codec for S {}
|
||||
|
||||
impl<T: Encode, E: Encode> Encode for Result<T, E> {
|
||||
@@ -252,6 +254,40 @@ impl Decode for Vec<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Encode for &'a str {
|
||||
fn encode_to<W: Output>(&self, dest: &mut W) {
|
||||
self.as_bytes().encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a > Encode for ::std::borrow::Cow<'a, str> {
|
||||
fn encode_to<W: Output>(&self, dest: &mut W) {
|
||||
self.as_bytes().encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'a> Decode for ::std::borrow::Cow<'a, str> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(::std::borrow::Cow::Owned(String::from_utf8_lossy(&Vec::decode(input)?).into()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Encode for String {
|
||||
fn encode_to<W: Output>(&self, dest: &mut W) {
|
||||
self.as_bytes().encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Decode for String {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Self::from_utf8_lossy(&Vec::decode(input)?).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Encode> Encode for [T] {
|
||||
fn encode_to<W: Output>(&self, dest: &mut W) {
|
||||
let len = self.len();
|
||||
|
||||
@@ -20,7 +20,7 @@ use Codec;
|
||||
use core::iter::Extend;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Trait to allow itselg to be serialised and prepended by a given slice.
|
||||
/// Trait to allow itself to be serialised and prepended by a given slice.
|
||||
pub trait KeyedVec {
|
||||
fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8>;
|
||||
}
|
||||
|
||||
+48
-3
@@ -26,6 +26,14 @@ name = "nodrop"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pwasm-alloc"
|
||||
version = "0.1.0"
|
||||
@@ -38,6 +46,14 @@ dependencies = [
|
||||
name = "pwasm-libc"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "runtime-test"
|
||||
version = "0.1.0"
|
||||
@@ -49,7 +65,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -84,6 +100,15 @@ dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-codec-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-primitives"
|
||||
version = "0.1.0"
|
||||
@@ -91,9 +116,10 @@ dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
"rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)",
|
||||
"rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
]
|
||||
@@ -128,6 +154,16 @@ dependencies = [
|
||||
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uint"
|
||||
version = "0.1.2"
|
||||
@@ -137,15 +173,24 @@ dependencies = [
|
||||
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
|
||||
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
|
||||
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
||||
"checksum fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "<none>"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "<none>"
|
||||
"checksum proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "cccdc7557a98fe98453030f077df7f3a042052fae465bb61d2c2c41435cfd9b6"
|
||||
"checksum quote 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3372dc35766b36a99ce2352bd1b6ea0137c38d215cc0c8780bf6de6df7842ba9"
|
||||
"checksum rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b03280c2813907a030785570c577fb27d3deec8da4c18566751ade94de0ace"
|
||||
"checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
|
||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"
|
||||
"checksum syn 0.14.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e13df71f29f9440b50261a5882c86eac334f1badb3134ec26f0de2f1418e44"
|
||||
"checksum uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "<none>"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -20,6 +20,7 @@ substrate-primitives = { path = "../../substrate/primitives" }
|
||||
substrate-client = { path = "../../substrate/client" }
|
||||
substrate-runtime-primitives = { path = "../../substrate/runtime/primitives" }
|
||||
substrate-codec = { path = "../../substrate/codec" }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive" }
|
||||
substrate-network-libp2p = { path = "../../substrate/network-libp2p" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -33,6 +33,7 @@ extern crate ed25519;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate bitflags;
|
||||
#[macro_use] extern crate error_chain;
|
||||
#[macro_use] extern crate substrate_codec_derive;
|
||||
|
||||
#[cfg(test)] extern crate env_logger;
|
||||
#[cfg(test)] extern crate substrate_keyring as keyring;
|
||||
|
||||
@@ -102,7 +102,19 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
impl Encode for BlockAttributes {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push_byte(self.bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for BlockAttributes {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Self::from_bits(input.read_byte()?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)]
|
||||
/// Block enumeration direction.
|
||||
pub enum Direction {
|
||||
/// Enumerate in ascending order (from child to parent).
|
||||
@@ -112,7 +124,7 @@ pub enum Direction {
|
||||
}
|
||||
|
||||
/// Remote call response.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct RemoteCallResponse {
|
||||
/// Id of a request this response was made for.
|
||||
pub id: RequestId,
|
||||
@@ -120,26 +132,9 @@ pub struct RemoteCallResponse {
|
||||
pub proof: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl Encode for RemoteCallResponse {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.id);
|
||||
dest.push(&self.proof);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for RemoteCallResponse {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(RemoteCallResponse {
|
||||
id: Decode::decode(input)?,
|
||||
proof: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic types.
|
||||
pub mod generic {
|
||||
use primitives::AuthorityId;
|
||||
use codec::{Decode, Encode, Input, Output};
|
||||
use runtime_primitives::bft::Justification;
|
||||
use ed25519;
|
||||
use service::Roles;
|
||||
@@ -147,7 +142,7 @@ pub mod generic {
|
||||
|
||||
|
||||
/// Block data sent in the response.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct BlockData<Header, Hash, Extrinsic> {
|
||||
/// Block header hash.
|
||||
pub hash: Hash,
|
||||
@@ -163,32 +158,8 @@ pub mod generic {
|
||||
pub justification: Option<Justification<Hash>>,
|
||||
}
|
||||
|
||||
impl<Header: Encode, Hash: Encode, Extrinsic: Encode> Encode for BlockData<Header, Hash, Extrinsic> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.hash);
|
||||
dest.push(&self.header);
|
||||
dest.push(&self.body);
|
||||
dest.push(&self.receipt);
|
||||
dest.push(&self.message_queue);
|
||||
dest.push(&self.justification);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header: Decode, Hash: Decode, Extrinsic: Decode> Decode for BlockData<Header, Hash, Extrinsic> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockData {
|
||||
hash: Decode::decode(input)?,
|
||||
header: Decode::decode(input)?,
|
||||
body: Decode::decode(input)?,
|
||||
receipt: Decode::decode(input)?,
|
||||
message_queue: Decode::decode(input)?,
|
||||
justification: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifies starting point of a block sequence.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub enum FromBlock<Hash, Number> {
|
||||
/// Start with given hash.
|
||||
Hash(Hash),
|
||||
@@ -196,33 +167,8 @@ pub mod generic {
|
||||
Number(Number),
|
||||
}
|
||||
|
||||
impl<Hash: Encode, Number: Encode> Encode for FromBlock<Hash, Number> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
FromBlock::Hash(ref h) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(h);
|
||||
}
|
||||
FromBlock::Number(ref n) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode, Number: Decode> Decode for FromBlock<Hash, Number> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(FromBlock::Hash(Decode::decode(input)?)),
|
||||
1 => Some(FromBlock::Number(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Communication that can occur between participants in consensus.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub enum BftMessage<Block, Hash> {
|
||||
/// A consensus message (proposal or vote)
|
||||
Consensus(SignedConsensusMessage<Block, Hash>),
|
||||
@@ -230,33 +176,8 @@ pub mod generic {
|
||||
Auxiliary(Justification<Hash>),
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for BftMessage<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
BftMessage::Consensus(ref h) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(h);
|
||||
}
|
||||
BftMessage::Auxiliary(ref n) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for BftMessage<Block, Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(BftMessage::Consensus(Decode::decode(input)?)),
|
||||
1 => Some(BftMessage::Auxiliary(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// BFT Consensus message with parent header hash attached to it.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct LocalizedBftMessage<Block, Hash> {
|
||||
/// Consensus message.
|
||||
pub message: BftMessage<Block, Hash>,
|
||||
@@ -264,24 +185,8 @@ pub mod generic {
|
||||
pub parent_hash: Hash,
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for LocalizedBftMessage<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.message);
|
||||
dest.push(&self.parent_hash);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for LocalizedBftMessage<Block, Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(LocalizedBftMessage {
|
||||
message: Decode::decode(input)?,
|
||||
parent_hash: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A localized proposal message. Contains two signed pieces of data.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct SignedConsensusProposal<Block, Hash> {
|
||||
/// The round number.
|
||||
pub round_number: u32,
|
||||
@@ -297,32 +202,8 @@ pub mod generic {
|
||||
pub full_signature: ed25519::Signature,
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for SignedConsensusProposal<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.round_number);
|
||||
dest.push(&self.proposal);
|
||||
dest.push(&self.digest);
|
||||
dest.push(&self.sender);
|
||||
dest.push(&self.digest_signature);
|
||||
dest.push(&self.full_signature);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for SignedConsensusProposal<Block, Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(SignedConsensusProposal {
|
||||
round_number: Decode::decode(input)?,
|
||||
proposal: Decode::decode(input)?,
|
||||
digest: Decode::decode(input)?,
|
||||
sender: Decode::decode(input)?,
|
||||
digest_signature: Decode::decode(input)?,
|
||||
full_signature: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A localized vote message, including the sender.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct SignedConsensusVote<H> {
|
||||
/// The message sent.
|
||||
pub vote: ConsensusVote<H>,
|
||||
@@ -332,26 +213,8 @@ pub mod generic {
|
||||
pub signature: ed25519::Signature,
|
||||
}
|
||||
|
||||
impl<Hash: Encode> Encode for SignedConsensusVote<Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.vote);
|
||||
dest.push(&self.sender);
|
||||
dest.push(&self.signature);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode> Decode for SignedConsensusVote<Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(SignedConsensusVote {
|
||||
vote: Decode::decode(input)?,
|
||||
sender: Decode::decode(input)?,
|
||||
signature: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Votes during a consensus round.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub enum ConsensusVote<H> {
|
||||
/// Prepare to vote for proposal with digest D.
|
||||
Prepare(u32, H),
|
||||
@@ -361,40 +224,8 @@ pub mod generic {
|
||||
AdvanceRound(u32),
|
||||
}
|
||||
|
||||
impl<Hash: Encode> Encode for ConsensusVote<Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
ConsensusVote::Prepare(ref r, ref h) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(r);
|
||||
dest.push(h);
|
||||
}
|
||||
ConsensusVote::Commit(ref r, ref h) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(r);
|
||||
dest.push(h);
|
||||
}
|
||||
ConsensusVote::AdvanceRound(ref r) => {
|
||||
dest.push_byte(2);
|
||||
dest.push(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode> Decode for ConsensusVote<Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(ConsensusVote::Prepare(Decode::decode(input)?, Decode::decode(input)?)),
|
||||
1 => Some(ConsensusVote::Commit(Decode::decode(input)?, Decode::decode(input)?)),
|
||||
2 => Some(ConsensusVote::AdvanceRound(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A localized message.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub enum SignedConsensusMessage<Block, Hash> {
|
||||
/// A proposal.
|
||||
Propose(SignedConsensusProposal<Block, Hash>),
|
||||
@@ -402,33 +233,8 @@ pub mod generic {
|
||||
Vote(SignedConsensusVote<Hash>),
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for SignedConsensusMessage<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
SignedConsensusMessage::Propose(ref m) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(m);
|
||||
}
|
||||
SignedConsensusMessage::Vote(ref m) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for SignedConsensusMessage<Block, Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(SignedConsensusMessage::Propose(Decode::decode(input)?)),
|
||||
1 => Some(SignedConsensusMessage::Vote(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A network message.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub enum Message<Block, Header, Hash, Number, Extrinsic> {
|
||||
/// Status packet.
|
||||
Status(Status<Hash, Number>),
|
||||
@@ -447,75 +253,12 @@ pub mod generic {
|
||||
/// Remote method call response.
|
||||
RemoteCallResponse(RemoteCallResponse),
|
||||
/// Chain-specific message
|
||||
#[codec(index = "255")]
|
||||
ChainSpecific(Vec<u8>),
|
||||
}
|
||||
|
||||
impl<Block: Encode, Header: Encode, Hash: Encode, Number: Encode, Extrinsic: Encode> Encode
|
||||
for Message<Block, Header, Hash, Number, Extrinsic>
|
||||
{
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
Message::Status(ref m) => {
|
||||
dest.push_byte(0);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::BlockRequest(ref m) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::BlockResponse(ref m) => {
|
||||
dest.push_byte(2);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::BlockAnnounce(ref m) => {
|
||||
dest.push_byte(3);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::Transactions(ref m) => {
|
||||
dest.push_byte(4);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::BftMessage(ref m) => {
|
||||
dest.push_byte(5);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::RemoteCallRequest(ref m) => {
|
||||
dest.push_byte(6);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::RemoteCallResponse(ref m) => {
|
||||
dest.push_byte(7);
|
||||
dest.push(m);
|
||||
}
|
||||
Message::ChainSpecific(ref m) => {
|
||||
dest.push_byte(255);
|
||||
dest.push(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Header: Decode, Hash: Decode, Number: Decode, Extrinsic: Decode> Decode
|
||||
for Message<Block, Header, Hash, Number, Extrinsic>
|
||||
{
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
0 => Some(Message::Status(Decode::decode(input)?)),
|
||||
1 => Some(Message::BlockRequest(Decode::decode(input)?)),
|
||||
2 => Some(Message::BlockResponse(Decode::decode(input)?)),
|
||||
3 => Some(Message::BlockAnnounce(Decode::decode(input)?)),
|
||||
4 => Some(Message::Transactions(Decode::decode(input)?)),
|
||||
5 => Some(Message::BftMessage(Decode::decode(input)?)),
|
||||
6 => Some(Message::RemoteCallRequest(Decode::decode(input)?)),
|
||||
7 => Some(Message::RemoteCallResponse(Decode::decode(input)?)),
|
||||
255 => Some(Message::ChainSpecific(Decode::decode(input)?)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Status sent on connection.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct Status<Hash, Number> {
|
||||
/// Protocol version.
|
||||
pub version: u32,
|
||||
@@ -531,32 +274,8 @@ pub mod generic {
|
||||
pub chain_status: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<Hash: Encode, Number: Encode> Encode for Status<Hash, Number> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.version);
|
||||
dest.push_byte(self.roles.bits());
|
||||
dest.push(&self.best_number);
|
||||
dest.push(&self.best_hash);
|
||||
dest.push(&self.genesis_hash);
|
||||
dest.push(&self.chain_status);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode, Number: Decode> Decode for Status<Hash, Number> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Status {
|
||||
version: Decode::decode(input)?,
|
||||
roles: Roles::from_bits(input.read_byte()?)?,
|
||||
best_number: Decode::decode(input)?,
|
||||
best_hash: Decode::decode(input)?,
|
||||
genesis_hash: Decode::decode(input)?,
|
||||
chain_status: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Request block data from a peer.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct BlockRequest<Hash, Number> {
|
||||
/// Unique request id.
|
||||
pub id: RequestId,
|
||||
@@ -572,36 +291,8 @@ pub mod generic {
|
||||
pub max: Option<u32>,
|
||||
}
|
||||
|
||||
impl<Hash: Encode, Number: Encode> Encode for BlockRequest<Hash, Number> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.id);
|
||||
dest.push_byte(self.fields.bits());
|
||||
dest.push(&self.from);
|
||||
dest.push(&self.to);
|
||||
dest.push_byte(self.direction as u8);
|
||||
dest.push(&self.max);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode, Number: Decode> Decode for BlockRequest<Hash, Number> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockRequest {
|
||||
id: Decode::decode(input)?,
|
||||
fields: BlockAttributes::from_bits(input.read_byte()?)?,
|
||||
from: Decode::decode(input)?,
|
||||
to: Decode::decode(input)?,
|
||||
direction: match input.read_byte()? {
|
||||
x if x == Direction::Ascending as u8 => Some(Direction::Ascending),
|
||||
x if x == Direction::Descending as u8 => Some(Direction::Descending),
|
||||
_ => None,
|
||||
}?,
|
||||
max: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Response to `BlockRequest`
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct BlockResponse<Header, Hash, Extrinsic> {
|
||||
/// Id of a request this response was made for.
|
||||
pub id: RequestId,
|
||||
@@ -609,44 +300,14 @@ pub mod generic {
|
||||
pub blocks: Vec<BlockData<Header, Hash, Extrinsic>>,
|
||||
}
|
||||
|
||||
impl<Header: Encode, Hash: Encode, Extrinsic: Encode> Encode for BlockResponse<Header, Hash, Extrinsic> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.id);
|
||||
dest.push(&self.blocks)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header: Decode, Hash: Decode, Extrinsic: Decode> Decode for BlockResponse<Header, Hash, Extrinsic> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockResponse {
|
||||
id: Decode::decode(input)?,
|
||||
blocks: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Announce a new complete relay chain block on the network.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
pub struct BlockAnnounce<H> {
|
||||
/// New block header.
|
||||
pub header: H,
|
||||
}
|
||||
|
||||
impl<Header: Encode> Encode for BlockAnnounce<Header> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.header);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header: Decode> Decode for BlockAnnounce<Header> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(BlockAnnounce {
|
||||
header: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
/// Remote call request.
|
||||
pub struct RemoteCallRequest<H> {
|
||||
/// Unique request id.
|
||||
@@ -658,24 +319,4 @@ pub mod generic {
|
||||
/// Call data.
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<Hash: Encode> Encode for RemoteCallRequest<Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.id);
|
||||
dest.push(&self.block);
|
||||
dest.push(self.method.as_bytes());
|
||||
dest.push(&self.data);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode> Decode for RemoteCallRequest<Hash> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(RemoteCallRequest {
|
||||
id: Decode::decode(input)?,
|
||||
block: Decode::decode(input)?,
|
||||
method: String::from_utf8_lossy(&Vec::decode(input)?).into(),
|
||||
data: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,6 +59,18 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::Encode for Roles {
|
||||
fn encode_to<T: ::codec::Output>(&self, dest: &mut T) {
|
||||
dest.push_byte(self.bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::Decode for Roles {
|
||||
fn decode<I: ::codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Self::from_bits(input.read_byte()?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sync status
|
||||
pub trait SyncProvider<B: BlockT>: Send + Sync {
|
||||
/// Get sync status
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
crunchy = "0.1"
|
||||
substrate-runtime-std = { path = "../runtime-std", default_features = false }
|
||||
substrate-codec = { path = "../codec", default_features = false }
|
||||
substrate-codec-derive = { path = "../codec/derive", default_features = false }
|
||||
fixed-hash = { git = "https://github.com/rphmeier/primitives.git", branch = "compile-for-wasm", default_features = false }
|
||||
rustc-hex = { version = "2.0", default_features = false }
|
||||
serde = { version = "1.0", default_features = false }
|
||||
|
||||
@@ -17,11 +17,10 @@
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
use codec;
|
||||
use H256;
|
||||
|
||||
/// An identifier for an authority in the consensus algorithm. The same size as ed25519::Public.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default, Encode, Decode)]
|
||||
pub struct AuthorityId(pub [u8; 32]);
|
||||
|
||||
impl AuthorityId {
|
||||
@@ -105,16 +104,3 @@ impl<'de> Deserialize<'de> for AuthorityId {
|
||||
.map(|x| AuthorityId::from_slice(&x))
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Encode for AuthorityId {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.using_encoded(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Decode for AuthorityId {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
<[u8; 32] as codec::Decode>::decode(input).map(AuthorityId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,17 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(not(feature = "std"), feature(alloc))]
|
||||
|
||||
extern crate rustc_hex;
|
||||
extern crate byteorder;
|
||||
#[macro_use]
|
||||
extern crate crunchy;
|
||||
#[macro_use]
|
||||
extern crate fixed_hash;
|
||||
#[macro_use]
|
||||
extern crate uint as uint_crate;
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
extern crate rustc_hex;
|
||||
extern crate byteorder;
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
|
||||
@@ -16,53 +16,33 @@
|
||||
|
||||
//! Definition of a sandbox environment.
|
||||
|
||||
use codec::{Encode, Decode, Input, Output};
|
||||
#[cfg(test)]
|
||||
use codec::Encode;
|
||||
use rstd::vec::Vec;
|
||||
|
||||
/// Error error that can be returned from host function.
|
||||
#[derive(Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct HostError;
|
||||
|
||||
impl Encode for HostError {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(&[])
|
||||
}
|
||||
|
||||
fn encode(&self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for HostError {
|
||||
fn decode<I: Input>(_: &mut I) -> Option<Self> {
|
||||
Some(HostError)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
#[repr(i8)]
|
||||
enum ValueType {
|
||||
I32 = 1,
|
||||
I64 = 2,
|
||||
F32 = 3,
|
||||
F64 = 4,
|
||||
}
|
||||
|
||||
/// Representation of a typed wasm value.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum TypedValue {
|
||||
/// Value of 32-bit signed or unsigned integer.
|
||||
#[codec(index = "1")]
|
||||
I32(i32),
|
||||
|
||||
/// Value of 64-bit signed or unsigned integer.
|
||||
#[codec(index = "2")]
|
||||
I64(i64),
|
||||
|
||||
/// Value of 32-bit IEEE 754-2008 floating point number represented as a bit pattern.
|
||||
#[codec(index = "3")]
|
||||
F32(i32),
|
||||
|
||||
/// Value of 64-bit IEEE 754-2008 floating point number represented as a bit pattern.
|
||||
#[codec(index = "4")]
|
||||
F64(i64),
|
||||
}
|
||||
|
||||
@@ -103,53 +83,16 @@ impl From<TypedValue> for ::wasmi::RuntimeValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for TypedValue {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
TypedValue::I32(i) => {
|
||||
dest.push_byte(ValueType::I32 as u8);
|
||||
dest.push(&i);
|
||||
}
|
||||
TypedValue::I64(i) => {
|
||||
dest.push_byte(ValueType::I64 as u8);
|
||||
dest.push(&i);
|
||||
}
|
||||
TypedValue::F32(f_bits) => {
|
||||
dest.push_byte(ValueType::F32 as u8);
|
||||
dest.push(&f_bits);
|
||||
}
|
||||
TypedValue::F64(f_bits) => {
|
||||
dest.push_byte(ValueType::F64 as u8);
|
||||
dest.push(&f_bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for TypedValue {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
let typed_value = match i8::decode(value) {
|
||||
Some(x) if x == ValueType::I32 as i8 => TypedValue::I32(i32::decode(value)?),
|
||||
Some(x) if x == ValueType::I64 as i8 => TypedValue::I64(i64::decode(value)?),
|
||||
Some(x) if x == ValueType::F32 as i8 => TypedValue::F32(i32::decode(value)?),
|
||||
Some(x) if x == ValueType::F64 as i8 => TypedValue::F64(i64::decode(value)?),
|
||||
_ => return None,
|
||||
};
|
||||
Some(typed_value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Typed value that can be returned from a function.
|
||||
///
|
||||
/// Basically a `TypedValue` plus `Unit`, for functions which return nothing.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, Copy, PartialEq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum ReturnValue {
|
||||
/// For returning some concrete value.
|
||||
Value(TypedValue),
|
||||
|
||||
/// For returning nothing.
|
||||
Unit,
|
||||
/// For returning some concrete value.
|
||||
Value(TypedValue),
|
||||
}
|
||||
|
||||
impl From<TypedValue> for ReturnValue {
|
||||
@@ -158,30 +101,6 @@ impl From<TypedValue> for ReturnValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for ReturnValue {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
ReturnValue::Unit => {
|
||||
dest.push_byte(0);
|
||||
}
|
||||
ReturnValue::Value(ref val) => {
|
||||
dest.push_byte(1);
|
||||
dest.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for ReturnValue {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
match i8::decode(value) {
|
||||
Some(0) => Some(ReturnValue::Unit),
|
||||
Some(1) => Some(ReturnValue::Value(TypedValue::decode(value)?)),
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ReturnValue {
|
||||
/// Maximum number of bytes `ReturnValue` might occupy when serialized with
|
||||
/// `Codec`.
|
||||
@@ -199,63 +118,26 @@ fn return_value_encoded_max_size() {
|
||||
assert_eq!(encoded.len(), ReturnValue::ENCODED_MAX_SIZE);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
#[repr(i8)]
|
||||
enum ExternEntityKind {
|
||||
Function = 1,
|
||||
Memory = 2,
|
||||
}
|
||||
|
||||
/// Describes an entity to define or import into the environment.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum ExternEntity {
|
||||
/// Function that is specified by an index in a default table of
|
||||
/// a module that creates the sandbox.
|
||||
#[codec(index = "1")]
|
||||
Function(u32),
|
||||
|
||||
/// Linear memory that is specified by some identifier returned by sandbox
|
||||
/// module upon creation new sandboxed memory.
|
||||
#[codec(index = "2")]
|
||||
Memory(u32),
|
||||
}
|
||||
|
||||
impl Encode for ExternEntity {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
ExternEntity::Function(ref index) => {
|
||||
dest.push_byte(ExternEntityKind::Function as u8);
|
||||
dest.push(index);
|
||||
}
|
||||
ExternEntity::Memory(ref mem_id) => {
|
||||
dest.push_byte(ExternEntityKind::Memory as u8);
|
||||
dest.push(mem_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for ExternEntity {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
match i8::decode(value) {
|
||||
Some(x) if x == ExternEntityKind::Function as i8 => {
|
||||
let idx = u32::decode(value)?;
|
||||
Some(ExternEntity::Function(idx))
|
||||
}
|
||||
Some(x) if x == ExternEntityKind::Memory as i8 => {
|
||||
let mem_id = u32::decode(value)?;
|
||||
Some(ExternEntity::Memory(mem_id))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An entry in a environment definition table.
|
||||
///
|
||||
/// Each entry has a two-level name and description of an entity
|
||||
/// being defined.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct Entry {
|
||||
/// Module name of which corresponding entity being defined.
|
||||
@@ -266,52 +148,14 @@ pub struct Entry {
|
||||
pub entity: ExternEntity,
|
||||
}
|
||||
|
||||
impl Encode for Entry {
|
||||
fn encode_to<T: ::codec::Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.module_name);
|
||||
dest.push(&self.field_name);
|
||||
dest.push(&self.entity);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Entry {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
let module_name = Vec::decode(value)?;
|
||||
let field_name = Vec::decode(value)?;
|
||||
let entity = ExternEntity::decode(value)?;
|
||||
|
||||
Some(Entry {
|
||||
module_name,
|
||||
field_name,
|
||||
entity,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Definition of runtime that could be used by sandboxed code.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct EnvironmentDefinition {
|
||||
/// Vector of all entries in the environment defintion.
|
||||
pub entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
impl Encode for EnvironmentDefinition {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
self.entries.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for EnvironmentDefinition {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
let entries = Vec::decode(value)?;
|
||||
|
||||
Some(EnvironmentDefinition {
|
||||
entries,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Constant for specifying no limit when creating a sandboxed
|
||||
/// memory instance. For FFI purposes.
|
||||
pub const MEM_UNLIMITED: u32 = -1i32 as u32;
|
||||
|
||||
@@ -430,7 +430,6 @@ macro_rules! __decl_dispatch_module_common {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ 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-codec-derive = { path = "../../codec/derive", default_features = false }
|
||||
substrate-primitives = { path = "../../primitives", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
|
||||
|
||||
@@ -21,18 +21,19 @@
|
||||
#[cfg(feature = "std")]
|
||||
extern crate serde;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate substrate_primitives;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_support;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate substrate_primitives;
|
||||
|
||||
extern crate substrate_codec_derive;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_support;
|
||||
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
|
||||
@@ -17,11 +17,10 @@
|
||||
//! Voting thresholds.
|
||||
|
||||
use primitives::traits::{Zero, IntegerSquareRoot};
|
||||
use codec::{Decode, Encode, Input};
|
||||
use rstd::ops::{Add, Mul, Div, Rem};
|
||||
|
||||
/// A means of determining if a vote is past pass threshold.
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub enum VoteThreshold {
|
||||
/// A supermajority of approvals is needed to pass this vote.
|
||||
@@ -32,27 +31,6 @@ pub enum VoteThreshold {
|
||||
SimpleMajority,
|
||||
}
|
||||
|
||||
impl Decode for VoteThreshold {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
input.read_byte().and_then(|v| match v {
|
||||
0 => Some(VoteThreshold::SuperMajorityApprove),
|
||||
1 => Some(VoteThreshold::SuperMajorityAgainst),
|
||||
2 => Some(VoteThreshold::SimpleMajority),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for VoteThreshold {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(&[match *self {
|
||||
VoteThreshold::SuperMajorityApprove => 0u8,
|
||||
VoteThreshold::SuperMajorityAgainst => 1u8,
|
||||
VoteThreshold::SimpleMajority => 2u8,
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Approved<Balance> {
|
||||
/// Given `approve` votes for and `against` votes against from a total electorate size of
|
||||
/// `electorate` (`electorate - (approve + against)` are abstainers), then returns true if the
|
||||
|
||||
@@ -9,6 +9,7 @@ integer-sqrt = { git = "https://github.com/paritytech/integer-sqrt-rs.git", bran
|
||||
serde = { version = "1.0", optional = true }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
substrate-codec = { path = "../../codec", default_features = false }
|
||||
substrate-codec-derive = { path = "../../codec/derive", default_features = false }
|
||||
substrate-primitives = { path = "../../primitives", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default_features = false }
|
||||
|
||||
@@ -20,100 +20,36 @@ use rstd::prelude::*;
|
||||
use codec::{Decode, Encode, Input, Output};
|
||||
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)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub enum Action<Block, H> {
|
||||
/// Proposal of a block candidate.
|
||||
#[codec(index = "1")]
|
||||
Propose(u32, Block),
|
||||
/// Proposal header of a block candidate. Accompanies any proposal,
|
||||
/// but is used for misbehavior reporting since blocks themselves are big.
|
||||
#[codec(index = "2")]
|
||||
ProposeHeader(u32, H),
|
||||
/// Preparation to commit for a candidate.
|
||||
#[codec(index = "3")]
|
||||
Prepare(u32, H),
|
||||
/// Vote to commit to a candidate.
|
||||
#[codec(index = "4")]
|
||||
Commit(u32, H),
|
||||
/// Vote to advance round after inactive primary.
|
||||
#[codec(index = "5")]
|
||||
AdvanceRound(u32),
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for Action<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
match *self {
|
||||
Action::Propose(ref round, ref block) => {
|
||||
dest.push_byte(ActionKind::Propose as u8);
|
||||
dest.push(round);
|
||||
dest.push(block);
|
||||
}
|
||||
Action::ProposeHeader(ref round, ref hash) => {
|
||||
dest.push_byte(ActionKind::ProposeHeader as u8);
|
||||
dest.push(round);
|
||||
dest.push(hash);
|
||||
}
|
||||
Action::Prepare(ref round, ref hash) => {
|
||||
dest.push_byte(ActionKind::Prepare as u8);
|
||||
dest.push(round);
|
||||
dest.push(hash);
|
||||
}
|
||||
Action::Commit(ref round, ref hash) => {
|
||||
dest.push_byte(ActionKind::Commit as u8);
|
||||
dest.push(round);
|
||||
dest.push(hash);
|
||||
}
|
||||
Action::AdvanceRound(ref round) => {
|
||||
dest.push_byte(ActionKind::AdvanceRound as u8);
|
||||
dest.push(round);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for Action<Block, Hash> {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
match i8::decode(value) {
|
||||
Some(x) if x == ActionKind::Propose as i8 => {
|
||||
let (round, block) = Decode::decode(value)?;
|
||||
Some(Action::Propose(round, block))
|
||||
}
|
||||
Some(x) if x == ActionKind::ProposeHeader as i8 => {
|
||||
let (round, hash) = Decode::decode(value)?;
|
||||
Some(Action::ProposeHeader(round, hash))
|
||||
}
|
||||
Some(x) if x == ActionKind::Prepare as i8 => {
|
||||
let (round, hash) = Decode::decode(value)?;
|
||||
Some(Action::Prepare(round, hash))
|
||||
}
|
||||
Some(x) if x == ActionKind::Commit as i8 => {
|
||||
let (round, hash) = Decode::decode(value)?;
|
||||
Some(Action::Commit(round, hash))
|
||||
}
|
||||
Some(x) if x == ActionKind::AdvanceRound as i8 => {
|
||||
Decode::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)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Message<Block, Hash> {
|
||||
/// The parent header hash this action is relative to.
|
||||
@@ -122,24 +58,8 @@ pub struct Message<Block, Hash> {
|
||||
pub action: Action<Block, Hash>,
|
||||
}
|
||||
|
||||
impl<Block: Encode, Hash: Encode> Encode for Message<Block, Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.parent);
|
||||
dest.push(&self.action);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block: Decode, Hash: Decode> Decode for Message<Block, Hash> {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
Some(Message {
|
||||
parent: Decode::decode(value)?,
|
||||
action: Decode::decode(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Justification of a block.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Justification<H> {
|
||||
/// The round consensus was reached in.
|
||||
@@ -150,24 +70,6 @@ pub struct Justification<H> {
|
||||
pub signatures: Vec<(AuthorityId, Signature)>
|
||||
}
|
||||
|
||||
impl<H: Encode> Encode for Justification<H> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.round_number);
|
||||
dest.push(&self.hash);
|
||||
dest.push(&self.signatures);
|
||||
}
|
||||
}
|
||||
|
||||
impl<H: Decode> Decode for Justification<H> {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
Some(Justification {
|
||||
round_number: Decode::decode(value)?,
|
||||
hash: Decode::decode(value)?,
|
||||
signatures: Decode::decode(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// single-byte code to represent misbehavior kind.
|
||||
#[repr(i8)]
|
||||
enum MisbehaviorCode {
|
||||
@@ -197,27 +99,9 @@ pub enum MisbehaviorKind<Hash> {
|
||||
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: Encode, Number: Encode> Encode for MisbehaviorReport<Hash, Number> {
|
||||
impl<Hash: Encode> Encode for MisbehaviorKind<Hash> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.parent_hash);
|
||||
dest.push(&self.parent_number);
|
||||
dest.push(&self.target);
|
||||
|
||||
match self.misbehavior {
|
||||
match *self {
|
||||
MisbehaviorKind::BftDoublePrepare(ref round, (ref h_a, ref s_a), (ref h_b, ref s_b)) => {
|
||||
dest.push(&(MisbehaviorCode::BftDoublePrepare as i8));
|
||||
dest.push(round);
|
||||
@@ -237,14 +121,9 @@ impl<Hash: Encode, Number: Encode> Encode for MisbehaviorReport<Hash, Number> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Hash: Decode, Number: Decode> Decode for MisbehaviorReport<Hash, Number> {
|
||||
impl<Hash: Decode> Decode for MisbehaviorKind<Hash> {
|
||||
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)? {
|
||||
Some(match i8::decode(input).and_then(MisbehaviorCode::from_i8)? {
|
||||
MisbehaviorCode::BftDoublePrepare => {
|
||||
MisbehaviorKind::BftDoublePrepare(
|
||||
u32::decode(input)?,
|
||||
@@ -259,17 +138,25 @@ impl<Hash: Decode, Number: Decode> Decode for MisbehaviorReport<Hash, Number> {
|
||||
(Hash::decode(input)?, Signature::decode(input)?),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Some(MisbehaviorReport {
|
||||
parent_hash,
|
||||
parent_number,
|
||||
target,
|
||||
misbehavior,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A report of misbehavior by an authority.
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct MisbehaviorReport<Hash, Number> {
|
||||
/// The parent hash of the block where the misbehavior occurred.
|
||||
pub parent_hash: Hash,
|
||||
/// The parent number of the block where the misbehavior occurred.
|
||||
pub parent_number: Number,
|
||||
/// The authority who misbehavior.
|
||||
pub target: AuthorityId,
|
||||
/// The misbehavior kind.
|
||||
pub misbehavior: MisbehaviorKind<Hash>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
@@ -31,7 +31,7 @@ use rstd::ops;
|
||||
use bft::Justification;
|
||||
|
||||
/// Definition of something that the external world might want to say.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Extrinsic<Address, Index, Call> {
|
||||
/// Who signed it (note this is not a signature).
|
||||
@@ -42,32 +42,6 @@ pub struct Extrinsic<Address, Index, Call> {
|
||||
pub function: Call,
|
||||
}
|
||||
|
||||
impl<Address, Index, Call> Decode for Extrinsic<Address, Index, Call> where
|
||||
Address: Decode,
|
||||
Index: Decode,
|
||||
Call: Decode,
|
||||
{
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Extrinsic {
|
||||
signed: Decode::decode(input)?,
|
||||
index: Decode::decode(input)?,
|
||||
function: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Address, Index, Call> Encode for Extrinsic<Address, Index, Call> where
|
||||
Address: Encode,
|
||||
Index: Encode,
|
||||
Call: Encode,
|
||||
{
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.signed);
|
||||
dest.push(&self.index);
|
||||
dest.push(&self.function);
|
||||
}
|
||||
}
|
||||
|
||||
/// A extrinsic right from the external world. Unchecked.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
@@ -234,24 +208,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone)]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Digest<Item> {
|
||||
pub logs: Vec<Item>,
|
||||
}
|
||||
|
||||
impl<Item: Decode> Decode for Digest<Item> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Digest { logs: Decode::decode(input)? })
|
||||
}
|
||||
}
|
||||
|
||||
impl<Item: Encode> Encode for Digest<Item> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
self.logs.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Item> traits::Digest for Digest<Item> where
|
||||
Item: Member + Default + Codec
|
||||
{
|
||||
@@ -285,7 +247,7 @@ pub struct Header<Number, Hash: HashT, DigestItem> {
|
||||
// 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"))]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[derive(Deserialize)]
|
||||
struct DeserializeHeader<N, H, D> {
|
||||
parent_hash: H,
|
||||
@@ -319,6 +281,7 @@ impl<'a, Number: 'a, Hash: 'a + HashT, DigestItem: 'a> Deserialize<'a> for Heade
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [ToDr] Issue with bounds
|
||||
impl<Number, Hash, DigestItem> Decode for Header<Number, Hash, DigestItem> where
|
||||
Number: Decode,
|
||||
Hash: HashT,
|
||||
@@ -437,7 +400,7 @@ impl<Block: BlockT> fmt::Display for BlockId<Block> {
|
||||
}
|
||||
|
||||
/// Abstraction over a substrate block.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
@@ -448,22 +411,6 @@ pub struct Block<Header, Extrinsic> {
|
||||
pub extrinsics: Vec<Extrinsic>,
|
||||
}
|
||||
|
||||
impl<Header: Decode, Extrinsic: Decode> Decode for Block<Header, Extrinsic> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Block {
|
||||
header: Decode::decode(input)?,
|
||||
extrinsics: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header: Encode, Extrinsic: Encode> Encode for Block<Header, Extrinsic> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.header);
|
||||
dest.push(&self.extrinsics);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header, Extrinsic> traits::Block for Block<Header, Extrinsic>
|
||||
where
|
||||
Header: HeaderT,
|
||||
@@ -488,7 +435,7 @@ where
|
||||
}
|
||||
|
||||
/// Abstraction over a substrate block and justification.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
@@ -499,26 +446,6 @@ pub struct SignedBlock<Header, Extrinsic, Hash> {
|
||||
pub justification: Justification<Hash>,
|
||||
}
|
||||
|
||||
impl<Header: Decode, Extrinsic: Decode, Hash: Decode> Decode
|
||||
for SignedBlock<Header, Extrinsic, Hash>
|
||||
{
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(SignedBlock {
|
||||
block: Decode::decode(input)?,
|
||||
justification: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<Header: Encode, Extrinsic: Encode, Hash: Encode> Encode
|
||||
for SignedBlock<Header, Extrinsic, Hash>
|
||||
{
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.block);
|
||||
dest.push(&self.justification);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
@@ -30,6 +30,9 @@ extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
extern crate num_traits;
|
||||
extern crate integer_sqrt;
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
@@ -82,7 +85,7 @@ impl BuildStorage for StorageMap {
|
||||
}
|
||||
|
||||
/// Ed25519 signature verify.
|
||||
#[derive(Eq, PartialEq, Clone, Default)]
|
||||
#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Ed25519Signature(pub H512);
|
||||
|
||||
@@ -93,25 +96,13 @@ impl Verify for Ed25519Signature {
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Decode for Ed25519Signature {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Ed25519Signature(codec::Decode::decode(input)?,))
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Encode for Ed25519Signature {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
#[repr(u8)]
|
||||
/// Outcome of a valid extrinsic application. Capable of being sliced.
|
||||
@@ -121,22 +112,14 @@ pub enum ApplyOutcome {
|
||||
/// Failed application (extrinsic was probably a no-op other than fees).
|
||||
Fail = 1,
|
||||
}
|
||||
impl codec::Decode for ApplyOutcome {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
x if x == ApplyOutcome::Success as u8 => Some(ApplyOutcome::Success),
|
||||
x if x == ApplyOutcome::Fail as u8 => Some(ApplyOutcome::Fail),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Encode for ApplyOutcome {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(&[*self as u8])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy)]
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
#[repr(u8)]
|
||||
/// Reason why an extrinsic couldn't be applied (i.e. invalid extrinsic).
|
||||
@@ -151,18 +134,6 @@ pub enum ApplyError {
|
||||
CantPay = 3,
|
||||
}
|
||||
|
||||
impl codec::Decode for ApplyError {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
match input.read_byte()? {
|
||||
x if x == ApplyError::BadSignature as u8 => Some(ApplyError::BadSignature),
|
||||
x if x == ApplyError::Stale as u8 => Some(ApplyError::Stale),
|
||||
x if x == ApplyError::Future as u8 => Some(ApplyError::Future),
|
||||
x if x == ApplyError::CantPay as u8 => Some(ApplyError::CantPay),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl codec::Encode for ApplyError {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(&[*self as u8])
|
||||
@@ -173,7 +144,7 @@ impl codec::Encode for ApplyError {
|
||||
pub type ApplyResult = Result<ApplyOutcome, ApplyError>;
|
||||
|
||||
/// Potentially "unsigned" signature verification.
|
||||
#[derive(Eq, PartialEq, Clone, Default)]
|
||||
#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct MaybeUnsigned<T>(pub T);
|
||||
|
||||
@@ -204,18 +175,6 @@ impl<T: Verify> Verify for MaybeUnsigned<T> where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: codec::Decode> codec::Decode for MaybeUnsigned<T> {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Some(MaybeUnsigned(codec::Decode::decode(input)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: codec::Encode> codec::Encode for MaybeUnsigned<T> {
|
||||
fn encode_to<W: codec::Output>(&self, dest: &mut W) {
|
||||
self.0.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<T> for MaybeUnsigned<T> {
|
||||
fn from(t: T) -> Self {
|
||||
MaybeUnsigned(t)
|
||||
|
||||
@@ -18,29 +18,17 @@
|
||||
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
use std::fmt::Debug;
|
||||
use codec::{Decode, Encode, Codec, Input, Output};
|
||||
use codec::Codec;
|
||||
use runtime_support::AuxDispatchable;
|
||||
use traits::{self, Checkable, Applyable, BlakeTwo256};
|
||||
|
||||
pub use substrate_primitives::H256;
|
||||
|
||||
#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
|
||||
#[derive(Default, PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
|
||||
pub struct Digest {
|
||||
pub logs: Vec<u64>,
|
||||
}
|
||||
|
||||
impl Decode for Digest {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Vec::<u64>::decode(input).map(|logs| Digest { logs })
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Digest {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.logs.using_encoded(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl traits::Digest for Digest {
|
||||
type Item = u64;
|
||||
fn push(&mut self, item: Self::Item) {
|
||||
@@ -48,7 +36,7 @@ impl traits::Digest for Digest {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Header {
|
||||
@@ -59,28 +47,6 @@ pub struct Header {
|
||||
pub digest: Digest,
|
||||
}
|
||||
|
||||
impl Decode for Header {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Header {
|
||||
parent_hash: Decode::decode(input)?,
|
||||
number: Decode::decode(input)?,
|
||||
state_root: Decode::decode(input)?,
|
||||
extrinsics_root: Decode::decode(input)?,
|
||||
digest: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Header {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.parent_hash);
|
||||
dest.push(&self.number);
|
||||
dest.push(&self.state_root);
|
||||
dest.push(&self.extrinsics_root);
|
||||
dest.push(&self.digest);
|
||||
}
|
||||
}
|
||||
|
||||
impl traits::Header for Header {
|
||||
type Number = u64;
|
||||
type Hashing = BlakeTwo256;
|
||||
@@ -115,25 +81,12 @@ impl traits::Header for Header {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
|
||||
pub struct Block<Xt> {
|
||||
pub header: Header,
|
||||
pub extrinsics: Vec<Xt>,
|
||||
}
|
||||
impl<Xt: Decode> Decode for Block<Xt> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(Block {
|
||||
header: Decode::decode(input)?,
|
||||
extrinsics: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<Xt: Encode> Encode for Block<Xt> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.header);
|
||||
dest.push(&self.extrinsics);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + DeserializeOwned + Clone + Eq + Debug> traits::Block for Block<Xt> {
|
||||
type Extrinsic = Xt;
|
||||
type Header = Header;
|
||||
@@ -153,21 +106,9 @@ impl<Xt: 'static + Codec + Sized + Send + Sync + Serialize + DeserializeOwned +
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug)]
|
||||
#[derive(PartialEq, Eq, Clone, Serialize, Deserialize, Debug, Encode, Decode)]
|
||||
pub struct TestXt<Call>(pub (u64, u64, Call));
|
||||
|
||||
impl<Call: Decode> Decode for TestXt<Call> {
|
||||
fn decode<I: Input>(input: &mut I) -> Option<Self> {
|
||||
Some(TestXt(Decode::decode(input)?))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call: Encode> Encode for TestXt<Call> {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
self.0.encode_to(dest)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call: Codec + Sync + Send + Serialize + AuxDispatchable, Context> Checkable<Context> for TestXt<Call> {
|
||||
type Checked = Self;
|
||||
fn check_with(self, _: Context) -> Result<Self::Checked, &'static str> { Ok(self) }
|
||||
|
||||
@@ -7,6 +7,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
serde = { version = "1.0", default_features = false }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
substrate-codec = { path = "../../codec", default_features = false }
|
||||
substrate-codec-derive = { path = "../../codec/derive", default_features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default_features = false }
|
||||
substrate-runtime-support = { path = "../../runtime-support", default_features = false }
|
||||
|
||||
|
||||
@@ -32,14 +32,12 @@ extern crate substrate_runtime_std as rstd;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_support as runtime_support;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
use rstd::prelude::*;
|
||||
use codec::{Encode, Output};
|
||||
#[cfg(feature = "std")]
|
||||
use codec::{Decode, Input};
|
||||
#[cfg(feature = "std")]
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::fmt;
|
||||
@@ -66,25 +64,25 @@ macro_rules! ver_str {
|
||||
/// This triplet have different semantics and mis-interpretation could cause problems.
|
||||
/// In particular: bug fixes should result in an increment of `spec_version` and possibly `authoring_version`,
|
||||
/// absolutely not `impl_version` since they change the semantics of the runtime.
|
||||
#[derive(Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[derive(Clone, Encode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize, Decode))]
|
||||
pub struct RuntimeVersion {
|
||||
/// Identifies the different Substrate runtimes. There'll be at least polkadot and demo.
|
||||
/// A different on-chain spec_name to that of the native runtime would normally result
|
||||
/// in node not attempting to sync or author blocks.
|
||||
pub spec_name: VersionString,
|
||||
|
||||
|
||||
/// Name of the implementation of the spec. This is of little consequence for the node
|
||||
/// and serves only to differentiate code of different implementation teams. For this
|
||||
/// codebase, it will be parity-polkadot. If there were a non-Rust implementation of the
|
||||
/// Polkadot runtime (e.g. C++), then it would identify itself with an accordingly different
|
||||
/// `impl_name`.
|
||||
pub impl_name: VersionString,
|
||||
|
||||
|
||||
/// `authoring_version` is the version of the authorship interface. An authoring node
|
||||
/// will not attempt to author blocks unless this is equal to its native runtime.
|
||||
pub authoring_version: u32,
|
||||
|
||||
|
||||
/// Version of the runtime specification. A full-node will not attempt to use its native
|
||||
/// runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`,
|
||||
/// `spec_version` and `authoring_version` are the same between Wasm and native.
|
||||
@@ -136,29 +134,6 @@ impl RuntimeVersion {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for RuntimeVersion {
|
||||
fn encode_to<T: Output>(&self, dest: &mut T) {
|
||||
dest.push(self.spec_name.as_bytes());
|
||||
dest.push(self.impl_name.as_bytes());
|
||||
dest.push(&self.authoring_version);
|
||||
dest.push(&self.spec_version);
|
||||
dest.push(&self.impl_version);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl Decode for RuntimeVersion {
|
||||
fn decode<I: Input>(value: &mut I) -> Option<Self> {
|
||||
Some(RuntimeVersion {
|
||||
spec_name: Cow::Owned(String::from_utf8_lossy(&Vec::decode(value)?).into()),
|
||||
impl_name: Cow::Owned(String::from_utf8_lossy(&Vec::decode(value)?).into()),
|
||||
authoring_version: Decode::decode(value)?,
|
||||
spec_version: Decode::decode(value)?,
|
||||
impl_version: Decode::decode(value)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait {
|
||||
const VERSION: RuntimeVersion;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ parking_lot = "0.5"
|
||||
log = "0.4"
|
||||
substrate-primitives = { path = "../../substrate/primitives" }
|
||||
substrate-codec = { path = "../../substrate/codec" }
|
||||
substrate-codec-derive = { path = "../../substrate/codec/derive" }
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.4"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
//!
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate substrate_codec_derive;
|
||||
extern crate parking_lot;
|
||||
extern crate substrate_codec as codec;
|
||||
extern crate substrate_primitives as primitives;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
//! The changes are journaled in the DB.
|
||||
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use codec::{Decode, Encode, self};
|
||||
use codec::{Encode, Decode};
|
||||
use {CommitSet, Error, MetaDb, to_meta_key, Hash};
|
||||
|
||||
const LAST_PRUNED: &[u8] = b"last_pruned";
|
||||
@@ -43,30 +43,13 @@ struct DeathRow<BlockHash: Hash, Key: Hash> {
|
||||
deleted: HashSet<Key>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode)]
|
||||
struct JournalRecord<BlockHash: Hash, Key: Hash> {
|
||||
hash: BlockHash,
|
||||
inserted: Vec<Key>,
|
||||
deleted: Vec<Key>,
|
||||
}
|
||||
|
||||
impl<BlockHash: Hash, Key: Hash> Encode for JournalRecord<BlockHash, Key> {
|
||||
fn encode_to<T: codec::Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.hash);
|
||||
dest.push(&self.inserted);
|
||||
dest.push(&self.deleted);
|
||||
}
|
||||
}
|
||||
|
||||
impl<BlockHash: Hash, Key: Hash> Decode for JournalRecord<BlockHash, Key> {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Some(JournalRecord {
|
||||
hash: Decode::decode(input)?,
|
||||
inserted: Decode::decode(input)?,
|
||||
deleted: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn to_journal_key(block: u64) -> Vec<u8> {
|
||||
to_meta_key(PRUNING_JOURNAL, &block)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use super::{Error, DBValue, ChangeSet, CommitSet, MetaDb, Hash, to_meta_key};
|
||||
use codec::{self, Decode, Encode};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
const UNFINALIZED_JOURNAL: &[u8] = b"unfinalized_journal";
|
||||
const LAST_FINALIZED: &[u8] = b"last_finalized";
|
||||
@@ -35,6 +35,7 @@ pub struct UnfinalizedOverlay<BlockHash: Hash, Key: Hash> {
|
||||
last_finalized_overlay: HashMap<Key, DBValue>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode)]
|
||||
struct JournalRecord<BlockHash: Hash, Key: Hash> {
|
||||
hash: BlockHash,
|
||||
parent_hash: BlockHash,
|
||||
@@ -42,26 +43,6 @@ struct JournalRecord<BlockHash: Hash, Key: Hash> {
|
||||
deleted: Vec<Key>,
|
||||
}
|
||||
|
||||
impl<BlockHash: Hash, Key: Hash> Encode for JournalRecord<BlockHash, Key> {
|
||||
fn encode_to<T: codec::Output>(&self, dest: &mut T) {
|
||||
dest.push(&self.hash);
|
||||
dest.push(&self.parent_hash);
|
||||
dest.push(&self.inserted);
|
||||
dest.push(&self.deleted);
|
||||
}
|
||||
}
|
||||
|
||||
impl<BlockHash: Hash, Key: Hash> Decode for JournalRecord<BlockHash, Key> {
|
||||
fn decode<I: codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Some(JournalRecord {
|
||||
hash: Decode::decode(input)?,
|
||||
parent_hash: Decode::decode(input)?,
|
||||
inserted: Decode::decode(input)?,
|
||||
deleted: Decode::decode(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn to_journal_key(block: u64, index: u64) -> Vec<u8> {
|
||||
to_meta_key(UNFINALIZED_JOURNAL, &(block, index))
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ serde = { version = "1.0", optional = true }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
substrate-keyring = { path = "../keyring", optional = true }
|
||||
substrate-codec = { path = "../codec", default-features = false }
|
||||
substrate-codec-derive = { path = "../codec/derive", default-features = false }
|
||||
substrate-runtime-std = { path = "../runtime-std", default-features = false }
|
||||
substrate-runtime-io = { path = "../runtime-io", default-features = false }
|
||||
substrate-runtime-support = { path = "../runtime-support", default-features = false }
|
||||
|
||||
@@ -31,6 +31,13 @@ extern crate serde_derive;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_support as runtime_support;
|
||||
#[macro_use]
|
||||
extern crate substrate_codec_derive;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_version as runtime_version;
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
@@ -41,11 +48,6 @@ extern crate ed25519;
|
||||
extern crate substrate_keyring as keyring;
|
||||
#[cfg_attr(test, macro_use)]
|
||||
extern crate substrate_primitives as primitives;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_io as runtime_io;
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_version as runtime_version;
|
||||
|
||||
|
||||
#[cfg(feature = "std")] pub mod genesismap;
|
||||
pub mod system;
|
||||
@@ -72,7 +74,7 @@ fn version() -> RuntimeVersion {
|
||||
}
|
||||
|
||||
/// Calls in transactions.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Transfer {
|
||||
pub from: AccountId,
|
||||
@@ -81,42 +83,14 @@ pub struct Transfer {
|
||||
pub nonce: u64,
|
||||
}
|
||||
|
||||
impl Encode for Transfer {
|
||||
fn encode_to<T: ::codec::Output>(&self, dest: &mut T) {
|
||||
self.from.encode_to(dest);
|
||||
self.to.encode_to(dest);
|
||||
self.amount.encode_to(dest);
|
||||
self.nonce.encode_to(dest);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Transfer {
|
||||
fn decode<I: ::codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Decode::decode(input).map(|(from, to, amount, nonce)| Transfer { from, to, amount, nonce })
|
||||
}
|
||||
}
|
||||
|
||||
/// Extrinsic for test-runtime.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
pub struct Extrinsic {
|
||||
pub transfer: Transfer,
|
||||
pub signature: Ed25519Signature,
|
||||
}
|
||||
|
||||
impl Encode for Extrinsic {
|
||||
fn encode_to<T: ::codec::Output>(&self, dest: &mut T) {
|
||||
self.transfer.encode_to(dest);
|
||||
self.signature.encode_to(dest);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for Extrinsic {
|
||||
fn decode<I: ::codec::Input>(input: &mut I) -> Option<Self> {
|
||||
Decode::decode(input).map(|(transfer, signature)| Extrinsic { transfer, signature })
|
||||
}
|
||||
}
|
||||
|
||||
impl BlindCheckable for Extrinsic {
|
||||
type Checked = Self;
|
||||
|
||||
|
||||
+16
-3
@@ -603,7 +603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
[[package]]
|
||||
name = "rustc-hex"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/rphmeier/rustc-hex.git#ee2ec40b9062ac7769ccb9dc891d6dc2cc9009d7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
@@ -663,6 +663,15 @@ dependencies = [
|
||||
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-codec-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substrate-primitives"
|
||||
version = "0.1.0"
|
||||
@@ -671,10 +680,11 @@ dependencies = [
|
||||
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
"rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)",
|
||||
"rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)",
|
||||
@@ -705,6 +715,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
@@ -741,6 +752,7 @@ dependencies = [
|
||||
"serde 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.64 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-runtime-std 0.1.0",
|
||||
"substrate-runtime-support 0.1.0",
|
||||
]
|
||||
@@ -769,6 +781,7 @@ dependencies = [
|
||||
"hex-literal 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"substrate-codec 0.1.0",
|
||||
"substrate-codec-derive 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
"substrate-runtime-io 0.1.0",
|
||||
"substrate-runtime-primitives 0.1.0",
|
||||
@@ -1009,7 +1022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum rlp 0.2.1 (git+https://github.com/paritytech/parity.git)" = "<none>"
|
||||
"checksum rlp 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "89db7f8dfdd5eb7ab3ac3ece7a07fd273a680b4b224cb231181280e8996f9f0b"
|
||||
"checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e"
|
||||
"checksum rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)" = "<none>"
|
||||
"checksum rustc-hex 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b03280c2813907a030785570c577fb27d3deec8da4c18566751ade94de0ace"
|
||||
"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
|
||||
@@ -8,6 +8,7 @@ log = { version = "0.3", optional = true }
|
||||
hex-literal = { version = "0.1.0", optional = true }
|
||||
ed25519 = { path = "../../ed25519", optional = true }
|
||||
substrate-codec = { path = "../../codec", default-features = false }
|
||||
substrate-codec-derive = { path = "../../codec/derive", default-features = false }
|
||||
substrate-runtime-std = { path = "../../runtime-std", default-features = false }
|
||||
substrate-runtime-io = { path = "../../runtime-io", default-features = false }
|
||||
substrate-runtime-support = { path = "../../runtime-support", default-features = false }
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user