Merge pull request #58 from paritytech/unify-primitives

Unify primitives from polkadot-primitives and polkadot-runtime
This commit is contained in:
Gav Wood
2018-02-06 20:01:12 +01:00
committed by GitHub
100 changed files with 3004 additions and 1963 deletions
+507 -393
View File
File diff suppressed because it is too large Load Diff
+8 -6
View File
@@ -15,14 +15,16 @@ members = [
"collator", "collator",
"environmental", "environmental",
"executor", "executor",
"primitives",
"rpc",
"rpc_servers",
"native-runtime", "native-runtime",
"serializer",
"state_machine",
"validator",
"network", "network",
"primitives",
"rpc-servers",
"rpc",
"runtime-codec",
"runtime-std",
"serializer",
"state-machine",
"validator",
] ]
exclude = [ exclude = [
"wasm-runtime" "wasm-runtime"
+1 -1
View File
@@ -12,4 +12,4 @@ log = "0.3"
polkadot-client = { path = "../client", version = "0.1" } polkadot-client = { path = "../client", version = "0.1" }
polkadot-executor = { path = "../executor", version = "0.1" } polkadot-executor = { path = "../executor", version = "0.1" }
polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-rpc-servers = { path = "../rpc_servers", version = "0.1" } polkadot-rpc-servers = { path = "../rpc-servers", version = "0.1" }
+3 -1
View File
@@ -8,9 +8,11 @@ error-chain = "0.11"
log = "0.3" log = "0.3"
parking_lot = "0.4" parking_lot = "0.4"
polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-state-machine = { path = "../state_machine", version = "0.1" } polkadot-state-machine = { path = "../state-machine", version = "0.1" }
polkadot-serializer = { path = "../serializer" } polkadot-serializer = { path = "../serializer" }
polkadot-executor = { path = "../executor" } polkadot-executor = { path = "../executor" }
polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1" }
native-runtime = { path = "../native-runtime" } native-runtime = { path = "../native-runtime" }
triehash = "0.1" triehash = "0.1"
hex-literal = "0.1" hex-literal = "0.1"
ed25519 = { path = "../ed25519", version = "0.1" }
+1 -1
View File
@@ -18,7 +18,7 @@
use state_machine; use state_machine;
use error; use error;
use primitives::block; use primitives::relay::block;
use blockchain::{self, BlockId}; use blockchain::{self, BlockId};
/// Block insertion transction. Keeps hold if the inseted block state and data. /// Block insertion transction. Keeps hold if the inseted block state and data.
+1 -1
View File
@@ -17,7 +17,7 @@
//! Polkadot blockchain trait //! Polkadot blockchain trait
use std::fmt::{Display, Formatter, Error as FmtError}; use std::fmt::{Display, Formatter, Error as FmtError};
use primitives::block; use primitives::relay::block;
use error::Result; use error::Result;
/// Block indentification. /// Block indentification.
+21 -20
View File
@@ -17,17 +17,17 @@
//! Tool for creating the genesis block. //! Tool for creating the genesis block.
use std::collections::HashMap; use std::collections::HashMap;
use native_runtime::primitives::{Block, Header}; use primitives::relay::{Block, Header};
use triehash::trie_root; use triehash::trie_root;
/// Create a genesis block, given the initial storage. /// Create a genesis block, given the initial storage.
pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block { pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block {
let state_root = trie_root(storage.clone().into_iter()).0; let state_root = trie_root(storage.clone().into_iter()).0.into();
let header = Header { let header = Header {
parent_hash: Default::default(), parent_hash: Default::default(),
number: 0, number: 0,
state_root, state_root,
transaction_root: trie_root(vec![].into_iter()).0, transaction_root: trie_root(vec![].into_iter()).0.into(),
digest: Default::default(), digest: Default::default(),
}; };
Block { Block {
@@ -39,19 +39,19 @@ pub fn construct_genesis_block(storage: &HashMap<Vec<u8>, Vec<u8>>) -> Block {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use native_runtime::codec::{Slicable, Joiner}; use codec::{Slicable, Joiner};
use native_runtime::support::{one, two, Hashable}; use native_runtime::support::{one, two, Hashable};
use native_runtime::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis}; use native_runtime::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use native_runtime::primitives::{AccountID, Hash, BlockNumber, Transaction,
UncheckedTransaction, Digest, Function};
use state_machine::execute; use state_machine::execute;
use state_machine::OverlayedChanges; use state_machine::OverlayedChanges;
use state_machine::backend::InMemory; use state_machine::backend::InMemory;
use polkadot_executor::executor; use polkadot_executor::executor;
use primitives::{AccountId, Hash};
use primitives::relay::{BlockNumber, Header, Digest, UncheckedTransaction, Transaction, Function};
use primitives::contract::CallData; use primitives::contract::CallData;
use primitives::ed25519::Pair; use ed25519::Pair;
fn secret_for(who: &AccountID) -> Option<Pair> { fn secret_for(who: &AccountId) -> Option<Pair> {
match who { match who {
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
@@ -64,12 +64,12 @@ mod tests {
let transactions = txs.into_iter().map(|transaction| { let transactions = txs.into_iter().map(|transaction| {
let signature = secret_for(&transaction.signed).unwrap() let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec()) .sign(&transaction.to_vec());
.inner();
UncheckedTransaction { transaction, signature } UncheckedTransaction { transaction, signature }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0; let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into();
let mut header = Header { let mut header = Header {
parent_hash, parent_hash,
@@ -83,24 +83,26 @@ mod tests {
let mut overlay = OverlayedChanges::default(); let mut overlay = OverlayedChanges::default();
for tx in transactions.iter() { for tx in transactions.iter() {
header = Header::from_slice(&execute( let ret_data = execute(
backend, backend,
&mut overlay, &mut overlay,
&executor(), &executor(),
"execute_transaction", "execute_transaction",
&CallData(vec![].join(&header).join(tx)) &CallData(vec![].join(&header).join(tx))
).unwrap()).unwrap(); ).unwrap();
header = Header::from_slice(&mut &ret_data[..]).unwrap();
} }
header = Header::from_slice(&execute( let ret_data = execute(
backend, backend,
&mut overlay, &mut overlay,
&executor(), &executor(),
"finalise_block", "finalise_block",
&CallData(vec![].join(&header)) &CallData(vec![].join(&header))
).unwrap()).unwrap(); ).unwrap();
header = Header::from_slice(&mut &ret_data[..]).unwrap();
(vec![].join(&Block { header, transactions }), hash) (vec![].join(&Block { header, transactions }), hash.into())
} }
fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec<u8>, Hash) { fn block1(genesis_hash: Hash, backend: &InMemory) -> (Vec<u8>, Hash) {
@@ -108,12 +110,11 @@ mod tests {
backend, backend,
1, 1,
genesis_hash, genesis_hash,
hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c"), hex!("25e5b37074063ab75c889326246640729b40d0c86932edc527bc80db0e04fe5c").into(),
vec![Transaction { vec![Transaction {
signed: one(), signed: one(),
nonce: 0, nonce: 0,
function: Function::StakingTransfer, function: Function::StakingTransfer(two(), 69),
input_data: vec![].join(&two()).join(&69u64),
}] }]
) )
} }
@@ -124,7 +125,7 @@ mod tests {
vec![one(), two()], 1000 vec![one(), two()], 1000
).genesis_map(); ).genesis_map();
let block = construct_genesis_block(&storage); let block = construct_genesis_block(&storage);
let genesis_hash = block.header.blake2_256(); let genesis_hash = block.header.blake2_256().into();
storage.extend(additional_storage_with_genesis(&block).into_iter()); storage.extend(additional_storage_with_genesis(&block).into_iter());
let mut overlay = OverlayedChanges::default(); let mut overlay = OverlayedChanges::default();
+3 -3
View File
@@ -23,11 +23,11 @@ use error;
use backend; use backend;
use primitives; use primitives;
use ser; use ser;
use primitives::block::{self, HeaderHash}; use primitives::relay::block::{self, HeaderHash};
use blockchain::{self, BlockId, BlockStatus}; use blockchain::{self, BlockId, BlockStatus};
fn header_hash(header: &primitives::block::Header) -> primitives::block::HeaderHash { fn header_hash(header: &block::Header) -> block::HeaderHash {
primitives::hash(&ser::to_vec(header)) primitives::hashing::blake2_256(&ser::to_vec(header)).into()
} }
struct PendingBlock { struct PendingBlock {
+9 -4
View File
@@ -21,14 +21,19 @@
extern crate polkadot_primitives as primitives; extern crate polkadot_primitives as primitives;
extern crate polkadot_state_machine as state_machine; extern crate polkadot_state_machine as state_machine;
extern crate polkadot_serializer as ser; extern crate polkadot_serializer as ser;
extern crate polkadot_runtime_codec as codec;
extern crate polkadot_executor; extern crate polkadot_executor;
extern crate native_runtime; extern crate native_runtime;
extern crate ed25519;
extern crate triehash; extern crate triehash;
extern crate parking_lot; extern crate parking_lot;
#[macro_use] extern crate error_chain; #[macro_use] extern crate error_chain;
#[macro_use] extern crate log; #[macro_use] extern crate log;
#[macro_use] extern crate hex_literal;
#[cfg(test)]
#[macro_use]
extern crate hex_literal;
pub mod error; pub mod error;
pub mod blockchain; pub mod blockchain;
@@ -42,7 +47,7 @@ pub use genesis::construct_genesis_block;
pub use blockchain::Info as ChainInfo; pub use blockchain::Info as ChainInfo;
pub use blockchain::BlockId; pub use blockchain::BlockId;
use primitives::{block}; use primitives::relay::block;
use primitives::contract::{CallData, StorageKey, StorageData}; use primitives::contract::{CallData, StorageKey, StorageData};
use blockchain::Backend as BlockchainBackend; use blockchain::Backend as BlockchainBackend;
@@ -123,8 +128,8 @@ impl<B, E> Client<B, E> where
parent_hash: Default::default(), parent_hash: Default::default(),
number: 0, number: 0,
state_root: Default::default(), state_root: Default::default(),
parachain_activity: Default::default(), transaction_root: Default::default(),
logs: Default::default(), digest: Default::default(),
}; };
let mut tx = backend.begin_transaction(BlockId::Hash(block::HeaderHash::default()))?; let mut tx = backend.begin_transaction(BlockId::Hash(block::HeaderHash::default()))?;
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "ed25519"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ring = "0.12"
untrusted = "0.5"
polkadot-primitives = { version = "0.1", path = "../primitives" }
rustc-hex = "1.0"
@@ -16,8 +16,13 @@
//! Simple Ed25519 API. //! Simple Ed25519 API.
use untrusted; extern crate ring;
extern crate polkadot_primitives as primitives;
extern crate untrusted;
extern crate rustc_hex;
use ring::{rand, signature}; use ring::{rand, signature};
use primitives::Signature;
use rustc_hex::FromHex; use rustc_hex::FromHex;
/// Verify a message without type checking the parameters' types for the right size. /// Verify a message without type checking the parameters' types for the right size.
@@ -39,41 +44,6 @@ pub struct Public ([u8; 32]);
/// A key pair. /// A key pair.
pub struct Pair(signature::Ed25519KeyPair); pub struct Pair(signature::Ed25519KeyPair);
/// A signature.
#[derive(Clone)]
pub struct Signature ([u8; 64]);
impl Signature {
/// A new signature from the given 64-byte `data`.
pub fn from(data: [u8; 64]) -> Self {
Signature(data)
}
/// A new signature from the given slice that should be 64 bytes long.
pub fn from_slice(data: &[u8]) -> Self {
let mut r = [0u8; 64];
r.copy_from_slice(data);
Signature(r)
}
/// Get the inner part.
pub fn inner(self) -> [u8; 64] {
self.0
}
}
impl AsRef<[u8; 64]> for Signature {
fn as_ref(&self) -> &[u8; 64] {
&self.0
}
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}
impl Public { impl Public {
/// A new instance from the given 32-byte `data`. /// A new instance from the given 32-byte `data`.
pub fn from(data: [u8; 32]) -> Self { pub fn from(data: [u8; 32]) -> Self {
@@ -113,14 +83,14 @@ impl Pair {
} }
/// Make a new key pair from the raw secret. /// Make a new key pair from the raw secret.
pub fn from_secret(secret: &[u8; 32]) -> Pair { pub fn from_secret(secret: &[u8; 32]) -> Pair {
let mut pkcs8_bytes = FromHex::from_hex("302e020100300506032b657004220420").unwrap(); let mut pkcs8_bytes: Vec<_> = FromHex::from_hex("302e020100300506032b657004220420").unwrap();
pkcs8_bytes.extend_from_slice(&secret[..]); pkcs8_bytes.extend_from_slice(&secret[..]);
Pair(signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).unwrap()) Pair(signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).unwrap())
} }
/// Make a new key pair from the raw secret and public key (it will check to make sure /// Make a new key pair from the raw secret and public key (it will check to make sure
/// they correspond to each other). /// they correspond to each other).
pub fn from_both(secret_public: &[u8; 64]) -> Option<Pair> { pub fn from_both(secret_public: &[u8; 64]) -> Option<Pair> {
let mut pkcs8_bytes = FromHex::from_hex("3053020101300506032b657004220420").unwrap(); let mut pkcs8_bytes: Vec<_> = FromHex::from_hex("3053020101300506032b657004220420").unwrap();
pkcs8_bytes.extend_from_slice(&secret_public[0..32]); pkcs8_bytes.extend_from_slice(&secret_public[0..32]);
pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]); pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]);
pkcs8_bytes.extend_from_slice(&secret_public[32..64]); pkcs8_bytes.extend_from_slice(&secret_public[32..64]);
@@ -130,7 +100,7 @@ impl Pair {
pub fn sign(&self, message: &[u8]) -> Signature { pub fn sign(&self, message: &[u8]) -> Signature {
let mut r = [0u8; 64]; let mut r = [0u8; 64];
r.copy_from_slice(self.0.sign(message).as_ref()); r.copy_from_slice(self.0.sign(message).as_ref());
Signature(r) Signature::from(r)
} }
/// Get the public key. /// Get the public key.
pub fn public(&self) -> Public { pub fn public(&self) -> Public {
@@ -140,29 +110,30 @@ impl Pair {
Public(r) Public(r)
} }
} }
impl Signature {
/// Verify a message.
pub fn verify(&self, message: &[u8], public: &Public) -> bool {
let peer_public_key = untrusted::Input::from(&public.0[..]);
let msg = untrusted::Input::from(message);
let sig = untrusted::Input::from(&self.0[..]);
match signature::verify(&signature::ED25519, peer_public_key, msg, sig) { /// Verify a signature on a message.
Ok(_) => true, pub fn verify_strong(sig: &Signature, message: &[u8], pubkey: &Public) -> bool {
_ => false, let public_key = untrusted::Input::from(&pubkey.0[..]);
} let msg = untrusted::Input::from(message);
let sig = untrusted::Input::from(&sig.0[..]);
match signature::verify(&signature::ED25519, public_key, msg, sig) {
Ok(_) => true,
_ => false,
} }
} }
impl From<&'static str> for Public { impl From<&'static str> for Public {
fn from(hex: &'static str) -> Self { fn from(hex: &'static str) -> Self {
let mut r = [0u8; 32]; let mut r = [0u8; 32];
r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..32]); let v: Vec<_> = FromHex::from_hex(hex).unwrap();
r.copy_from_slice(&v[0..32]);
Public(r) Public(r)
} }
} }
impl From<&'static str> for Pair { impl From<&'static str> for Pair {
fn from(hex: &'static str) -> Self { fn from(hex: &'static str) -> Self {
let data = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good."); let data: Vec<_> = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good.");
match data.len() { match data.len() {
32 => { 32 => {
let mut r = [0u8; 32]; let mut r = [0u8; 32];
@@ -180,19 +151,6 @@ impl From<&'static str> for Pair {
} }
} }
} }
impl From<&'static str> for Signature {
fn from(hex: &'static str) -> Self {
let mut r = [0u8; 64];
r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]);
Signature(r)
}
}
impl PartialEq for Signature {
fn eq(&self, other: &Signature) -> bool {
self.0.iter().eq(other.0.iter())
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@@ -206,7 +164,7 @@ mod test {
let message = b""; let message = b"";
let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into();
assert!(&pair.sign(&message[..]) == &signature); assert!(&pair.sign(&message[..]) == &signature);
assert!(signature.verify(&message[..], &public)); assert!(verify_strong(&signature, &message[..], &public));
} }
#[test] #[test]
@@ -215,21 +173,19 @@ mod test {
let public = pair.public(); let public = pair.public();
let message = b"Something important"; let message = b"Something important";
let signature = pair.sign(&message[..]); let signature = pair.sign(&message[..]);
assert!(signature.verify(&message[..], &public)); assert!(verify_strong(&signature, &message[..], &public));
} }
#[test] #[test]
fn seeded_pair_should_work() { fn seeded_pair_should_work() {
use primitives::hexdisplay::HexDisplay;
let pair = Pair::from_seed(b"12345678901234567890123456789012"); let pair = Pair::from_seed(b"12345678901234567890123456789012");
let public = pair.public(); let public = pair.public();
assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into()); assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into());
let message = b"Something important"; let message: Vec<_> = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000002228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap();
let public = pair.public();
assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into());
let message = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000002228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap();
let signature = pair.sign(&message[..]); let signature = pair.sign(&message[..]);
use hexdisplay::HexDisplay;
println!("Correct signature: {}", HexDisplay::from(&signature.0)); println!("Correct signature: {}", HexDisplay::from(&signature.0));
assert!(signature.verify(&message[..], &public)); assert!(verify_strong(&signature, &message[..], &public));
} }
} }
+4 -2
View File
@@ -5,17 +5,19 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
error-chain = "0.11" error-chain = "0.11"
polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1" }
polkadot-runtime-std = { path = "../runtime-std", version = "0.1" }
polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-serializer = { path = "../serializer", version = "0.1" } polkadot-serializer = { path = "../serializer", version = "0.1" }
polkadot-state-machine = { path = "../state_machine" , version = "0.1" } polkadot-state-machine = { path = "../state-machine" , version = "0.1" }
serde = "1.0" serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
parity-wasm = "0.15.0" parity-wasm = "0.15.0"
byteorder = "1.1" byteorder = "1.1"
rustc-hex = "1.0.0" rustc-hex = "1.0.0"
native-runtime = { path = "../native-runtime", version = "0.1" } native-runtime = { path = "../native-runtime", version = "0.1" }
runtime-std = { path = "../native-runtime/std", version = "0.1" }
triehash = "0.1.0" triehash = "0.1.0"
ed25519 = { path = "../ed25519", version = "0.1" }
hex-literal = "0.1.0" hex-literal = "0.1.0"
log = "0.3" log = "0.3"
+4 -1
View File
@@ -27,15 +27,18 @@
#![warn(missing_docs)] #![warn(missing_docs)]
extern crate polkadot_runtime_codec as codec;
extern crate polkadot_runtime_std as runtime_std;
extern crate polkadot_primitives as primitives; extern crate polkadot_primitives as primitives;
extern crate polkadot_serializer as serializer; extern crate polkadot_serializer as serializer;
extern crate polkadot_state_machine as state_machine; extern crate polkadot_state_machine as state_machine;
extern crate ed25519;
extern crate serde; extern crate serde;
extern crate parity_wasm; extern crate parity_wasm;
extern crate byteorder; extern crate byteorder;
extern crate rustc_hex; extern crate rustc_hex;
extern crate native_runtime; extern crate native_runtime;
extern crate runtime_std;
extern crate triehash; extern crate triehash;
#[macro_use] extern crate log; #[macro_use] extern crate log;
+41 -27
View File
@@ -1,10 +1,27 @@
use std::panic::catch_unwind; // Copyright 2017 Parity Technologies (UK) Ltd.
use primitives::contract::CallData; // This file is part of Polkadot.
use state_machine::{Externalities, CodeExecutor};
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
use error::{Error, ErrorKind, Result}; use error::{Error, ErrorKind, Result};
use wasm_executor::WasmExecutor;
use native_runtime as runtime; use native_runtime as runtime;
use primitives::contract::CallData;
use runtime_std; use runtime_std;
use state_machine::{Externalities, CodeExecutor};
use wasm_executor::WasmExecutor;
use std::panic::catch_unwind;
pub struct NativeExecutor; pub struct NativeExecutor;
@@ -42,25 +59,26 @@ impl CodeExecutor for NativeExecutor {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use runtime_std::TestExternalities; use codec::{KeyedVec, Slicable, Joiner};
use native_runtime::codec::{KeyedVec, Joiner, Slicable};
use native_runtime::support::{one, two, Hashable}; use native_runtime::support::{one, two, Hashable};
use native_runtime::primitives::*;
use native_runtime::runtime::staking::balance; use native_runtime::runtime::staking::balance;
use primitives::twox_128; use state_machine::TestExternalities;
use primitives::{twox_128, Hash};
use primitives::relay::{Header, BlockNumber, Block, Digest, Transaction, UncheckedTransaction, Function};
use ed25519::Pair;
const BLOATY_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); const BLOATY_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm");
const COMPACT_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); const COMPACT_CODE: &[u8] = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm");
fn tx() -> UncheckedTransaction { fn tx() -> UncheckedTransaction {
let transaction = Transaction { let transaction = Transaction {
signed: one(), signed: one(),
nonce: 0, nonce: 0,
function: Function::StakingTransfer, function: Function::StakingTransfer(two(), 69),
input_data: two().to_vec().join(&69u64),
}; };
let signature = secret_for(&transaction.signed).unwrap() let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec()) .sign(&transaction.to_vec());
.inner();
UncheckedTransaction { transaction, signature } UncheckedTransaction { transaction, signature }
} }
@@ -146,8 +164,7 @@ mod tests {
], } ], }
} }
use primitives::ed25519::Pair; fn secret_for(who: &::primitives::AccountId) -> Option<Pair> {
fn secret_for(who: &AccountID) -> Option<Pair> {
match who { match who {
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")), x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()), x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
@@ -160,12 +177,12 @@ mod tests {
let transactions = txs.into_iter().map(|transaction| { let transactions = txs.into_iter().map(|transaction| {
let signature = secret_for(&transaction.signed).unwrap() let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec()) .sign(&transaction.to_vec());
.inner();
UncheckedTransaction { transaction, signature } UncheckedTransaction { transaction, signature }
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0; let transaction_root = ordered_trie_root(transactions.iter().map(Slicable::to_vec)).0.into();
let header = Header { let header = Header {
parent_hash, parent_hash,
@@ -176,19 +193,18 @@ mod tests {
}; };
let hash = header.blake2_256(); let hash = header.blake2_256();
(Block { header, transactions }.to_vec(), hash) (Block { header, transactions }.to_vec(), hash.into())
} }
fn block1() -> (Vec<u8>, Hash) { fn block1() -> (Vec<u8>, Hash) {
construct_block( construct_block(
1, 1,
[69u8; 32], [69u8; 32].into(),
hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"), hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db").into(),
vec![Transaction { vec![Transaction {
signed: one(), signed: one(),
nonce: 0, nonce: 0,
function: Function::StakingTransfer, function: Function::StakingTransfer(two(), 69),
input_data: vec![].join(&two()).join(&69u64),
}] }]
) )
} }
@@ -197,19 +213,17 @@ mod tests {
construct_block( construct_block(
2, 2,
block1().1, block1().1,
hex!("2e69e4405a13981224078ad5355c68401bf56d0fe3f14a3536734666e6a8a047"), hex!("e2ba57cfb94b870ea6670b012b49dc33cbb70e3aa8d36cf54dfa5e4e69cd0778").into(),
vec![ vec![
Transaction { Transaction {
signed: two(), signed: two(),
nonce: 0, nonce: 0,
function: Function::StakingTransfer, function: Function::StakingTransfer(one(), 5),
input_data: vec![].join(&one()).join(&5u64),
}, },
Transaction { Transaction {
signed: one(), signed: one(),
nonce: 1, nonce: 1,
function: Function::StakingTransfer, function: Function::StakingTransfer(two(), 15),
input_data: vec![].join(&two()).join(&15u64),
} }
] ]
) )
+29 -33
View File
@@ -27,7 +27,7 @@ use state_machine::{Externalities, CodeExecutor};
use error::{Error, ErrorKind, Result}; use error::{Error, ErrorKind, Result};
use wasm_utils::{MemoryInstance, UserDefinedElements, use wasm_utils::{MemoryInstance, UserDefinedElements,
AddModuleWithoutFullDependentInstance}; AddModuleWithoutFullDependentInstance};
use primitives::{ed25519, blake2_256, twox_128, twox_256}; use primitives::{blake2_256, twox_128, twox_256};
use primitives::hexdisplay::HexDisplay; use primitives::hexdisplay::HexDisplay;
use triehash::ordered_trie_root; use triehash::ordered_trie_root;
@@ -227,7 +227,7 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| DummyUserError)?; this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| DummyUserError)?;
let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| DummyUserError)?; let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| DummyUserError)?;
if ed25519::Signature::from(sig).verify(&msg, &ed25519::Public::from(pubkey)) { if ::ed25519::verify(&sig, &msg, &pubkey) {
0 0
} else { } else {
5 5
@@ -287,15 +287,36 @@ impl CodeExecutor for WasmExecutor {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use rustc_hex::FromHex; use rustc_hex::FromHex;
use primitives::{blake2_256, twox_128}; use codec::{KeyedVec, Slicable, Joiner};
use runtime_std::{self, TestExternalities};
use native_runtime::support::{one, two}; use native_runtime::support::{one, two};
use native_runtime::primitives::{UncheckedTransaction, AccountID, Header};
use native_runtime::codec::{Joiner, KeyedVec};
use native_runtime::runtime::staking::balance; use native_runtime::runtime::staking::balance;
use state_machine::TestExternalities;
use primitives::{twox_128, AccountId};
use primitives::relay::{Header, Transaction, UncheckedTransaction, Function};
use runtime_std;
use ed25519::Pair;
fn secret_for(who: &AccountId) -> Option<Pair> {
match who {
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
_ => None,
}
}
fn tx() -> UncheckedTransaction {
let transaction = Transaction {
signed: one(),
nonce: 0,
function: Function::StakingTransfer(two(), 69),
};
let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec());
UncheckedTransaction { transaction, signature }
}
#[test] #[test]
fn returning_should_work() { fn returning_should_work() {
@@ -382,7 +403,7 @@ mod tests {
fn ed25519_verify_should_work() { fn ed25519_verify_should_work() {
let mut ext = TestExternalities::default(); let mut ext = TestExternalities::default();
let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm"); let test_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let key = ed25519::Pair::from_seed(&blake2_256(b"test")); let key = ::ed25519::Pair::from_seed(&blake2_256(b"test"));
let sig = key.sign(b"all ok!"); let sig = key.sign(b"all ok!");
let mut calldata = vec![]; let mut calldata = vec![];
calldata.extend_from_slice(key.public().as_ref()); calldata.extend_from_slice(key.public().as_ref());
@@ -403,31 +424,6 @@ mod tests {
); );
} }
use primitives::ed25519::Pair;
fn secret_for(who: &AccountID) -> Option<Pair> {
match who {
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
_ => None,
}
}
fn tx() -> UncheckedTransaction {
use native_runtime::codec::{Joiner, Slicable};
use native_runtime::support::{one, two};
use native_runtime::primitives::*;
let transaction = Transaction {
signed: one(),
nonce: 0,
function: Function::StakingTransfer,
input_data: two().to_vec().join(&69u64),
};
let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec())
.inner();
UncheckedTransaction { transaction, signature }
}
#[test] #[test]
fn panic_execution_gives_error() { fn panic_execution_gives_error() {
let one = one(); let one = one();
+8 -7
View File
@@ -3,13 +3,14 @@ name = "native-runtime"
version = "0.1.0" version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[features]
default = ["with-std"]
with-std = []
without-std = []
[dependencies] [dependencies]
runtime-std = { path = "./std", version = "0.1" } polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1" }
polkadot-runtime-std = { path = "../runtime-std", version = "0.1" }
polkadot-primitives = { path = "../primitives", version = "0.1" }
rustc-hex = "1.0" rustc-hex = "1.0"
hex-literal = "0.1.0" hex-literal = "0.1.0"
log = "0.3" log = { version = "0.3", optional = true }
[features]
default = ["std"]
std = ["polkadot-runtime-codec/std", "polkadot-runtime-std/std", "polkadot-primitives/std", "log"]
-15
View File
@@ -1,15 +0,0 @@
[package]
name = "runtime-std"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[features]
strict = []
[dependencies]
lazy_static = "1.0.0"
parking_lot = "0.5"
polkadot-state-machine = { path = "../../state_machine" , version = "0.1" }
environmental = { path = "../../environmental", version = "0.1.0" }
polkadot-primitives = { path = "../../primitives", version = "0.1.0" }
triehash = "0.1.0"
+1 -1
View File
@@ -12,7 +12,7 @@ ethcore-network = { git = "https://github.com/paritytech/parity.git" }
ethcore-io = { git = "https://github.com/paritytech/parity.git" } ethcore-io = { git = "https://github.com/paritytech/parity.git" }
polkadot-primitives = { path = "../primitives" } polkadot-primitives = { path = "../primitives" }
polkadot-client = { path = "../client" } polkadot-client = { path = "../client" }
polkadot-state-machine = { path = "../state_machine" } polkadot-state-machine = { path = "../state-machine" }
polkadot-serializer = { path = "../serializer" } polkadot-serializer = { path = "../serializer" }
log = "0.3" log = "0.3"
env_logger = "0.4" env_logger = "0.4"
+2 -2
View File
@@ -20,7 +20,7 @@ use std::ops::Range;
use std::collections::{HashMap, BTreeMap}; use std::collections::{HashMap, BTreeMap};
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use network::PeerId; use network::PeerId;
use primitives::block::{Number as BlockNumber}; use primitives::relay::BlockNumber;
use message; use message;
const MAX_PARALLEL_DOWNLOADS: u32 = 1; const MAX_PARALLEL_DOWNLOADS: u32 = 1;
@@ -190,7 +190,7 @@ impl BlockCollection {
mod test { mod test {
use super::{BlockCollection, BlockData}; use super::{BlockCollection, BlockData};
use message; use message;
use primitives::block::{HeaderHash}; use primitives::relay::{HeaderHash};
fn is_empty(bc: &BlockCollection) -> bool { fn is_empty(bc: &BlockCollection) -> bool {
bc.blocks.is_empty() && bc.blocks.is_empty() &&
+1 -1
View File
@@ -19,7 +19,7 @@
use client::{self, Client as PolkadotClient, ImportResult, ClientInfo, BlockStatus}; use client::{self, Client as PolkadotClient, ImportResult, ClientInfo, BlockStatus};
use client::error::Error; use client::error::Error;
use state_machine; use state_machine;
use primitives::block; use primitives::relay::block;
pub trait Client : Send + Sync { pub trait Client : Send + Sync {
/// Given a hash return a header /// Given a hash return a header
+2 -2
View File
@@ -56,7 +56,7 @@ pub use protocol::{ProtocolStatus};
pub use network::{NonReservedPeerMode, ConnectionFilter, ConnectionDirection, NetworkConfiguration}; pub use network::{NonReservedPeerMode, ConnectionFilter, ConnectionDirection, NetworkConfiguration};
// TODO: move it elsewhere // TODO: move it elsewhere
fn header_hash(header: &primitives::block::Header) -> primitives::block::HeaderHash { fn header_hash(header: &primitives::relay::Header) -> primitives::relay::HeaderHash {
primitives::hash(&ser::to_vec(header)) primitives::hashing::blake2_256(&ser::to_vec(header)).into()
} }
+3 -3
View File
@@ -18,8 +18,8 @@
use std::borrow::Borrow; use std::borrow::Borrow;
use primitives::parachain::Id as ParachainId; use primitives::parachain::Id as ParachainId;
use primitives::Address; use primitives::AccountId;
use primitives::block::{Number as BlockNumber, HeaderHash, Header, Body}; use primitives::relay::{BlockNumber, HeaderHash, Header, Body};
use service::Role as RoleFlags; use service::Role as RoleFlags;
pub type RequestId = u64; pub type RequestId = u64;
@@ -150,7 +150,7 @@ pub struct Status {
/// Signatue of `best_hash` made with validator address. Required for the validator role. /// Signatue of `best_hash` made with validator address. Required for the validator role.
pub validator_signature: Option<Signature>, pub validator_signature: Option<Signature>,
/// Validator address. Required for the validator role. /// Validator address. Required for the validator role.
pub validator_id: Option<Address>, pub validator_id: Option<AccountId>,
/// Parachain id. Required for the collator role. /// Parachain id. Required for the collator role.
pub parachain_id: Option<ParachainId>, pub parachain_id: Option<ParachainId>,
} }
+1 -1
View File
@@ -20,7 +20,7 @@ use std::sync::Arc;
use parking_lot::RwLock; use parking_lot::RwLock;
use serde_json; use serde_json;
use std::time; use std::time;
use primitives::block::{HeaderHash, TransactionHash, Number as BlockNumber, Header}; use primitives::relay::{HeaderHash, TransactionHash, BlockNumber, Header};
use network::{PeerId, NodeId}; use network::{PeerId, NodeId};
use message::{self, Message}; use message::{self, Message};
+2 -2
View File
@@ -19,7 +19,7 @@ use std::collections::{BTreeMap};
use std::io; use std::io;
use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId, use network::{NetworkProtocolHandler, NetworkService, NetworkContext, HostInfo, PeerId, ProtocolId,
NetworkConfiguration , NonReservedPeerMode, ErrorKind}; NetworkConfiguration , NonReservedPeerMode, ErrorKind};
use primitives::block::{TransactionHash, Header}; use primitives::relay::{TransactionHash, Header};
use core_io::{TimerToken}; use core_io::{TimerToken};
use io::NetSyncIo; use io::NetSyncIo;
use protocol::{Protocol, ProtocolStatus, PeerInfo as ProtocolPeerInfo, TransactionStats}; use protocol::{Protocol, ProtocolStatus, PeerInfo as ProtocolPeerInfo, TransactionStats};
@@ -148,7 +148,7 @@ impl SyncProvider for Service {
}; };
Some(PeerInfo { Some(PeerInfo {
id: session_info.id.map(|id| id.hex()), id: session_info.id.map(|id| format!("{:x}", id)),
client_version: session_info.client_version, client_version: session_info.client_version,
capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(), capabilities: session_info.peer_capabilities.into_iter().map(|c| c.to_string()).collect(),
remote_address: session_info.remote_address, remote_address: session_info.remote_address,
+1 -1
View File
@@ -19,7 +19,7 @@ use io::SyncIo;
use protocol::Protocol; use protocol::Protocol;
use network::PeerId; use network::PeerId;
use client::{ImportResult, BlockStatus, ClientInfo}; use client::{ImportResult, BlockStatus, ClientInfo};
use primitives::block::{HeaderHash, Number as BlockNumber, Header}; use primitives::relay::{HeaderHash, BlockNumber, Header};
use blocks::{self, BlockCollection}; use blocks::{self, BlockCollection};
use message::{self, Message}; use message::{self, Message};
use super::header_hash; use super::header_hash;
+20 -11
View File
@@ -5,16 +5,15 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
crunchy = "0.1" crunchy = "0.1"
fixed-hash = { git = "https://github.com/paritytech/primitives.git" } fixed-hash = { git = "https://github.com/rphmeier/primitives.git", branch = "compile-for-wasm", default_features = false }
rustc-hex = "1.0" rustc-hex = { git = "https://github.com/rphmeier/rustc-hex.git", version = "2.0", default_features = false }
serde = "1.0" serde = { version = "1.0", default_features = false }
serde_derive = "1.0" serde_derive = { version = "1.0", optional = true }
uint = { git = "https://github.com/paritytech/primitives.git" } uint = { git = "https://github.com/rphmeier/primitives.git", branch = "compile-for-wasm" }
ring = "0.12" twox-hash = { version = "1.1.0", optional = true }
untrusted = "0.5" byteorder = { version = "1.1", default_features = false }
twox-hash = "1.1.0" blake2-rfc = { version = "0.2.18", optional = true }
byteorder = "1.1" polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1", default_features = false }
blake2-rfc = "0.2.18"
[dev-dependencies] [dev-dependencies]
polkadot-serializer = { path = "../serializer", version = "0.1" } polkadot-serializer = { path = "../serializer", version = "0.1" }
@@ -22,4 +21,14 @@ pretty_assertions = "0.4"
[features] [features]
default = ["std"] default = ["std"]
std = ["uint/std", "fixed-hash/std"] std = [
"uint/std",
"fixed-hash/std",
"polkadot-runtime-codec/std",
"serde/std",
"rustc-hex/std",
"twox-hash",
"blake2-rfc",
"serde_derive",
"byteorder/std"
]
-114
View File
@@ -1,114 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Block and header type definitions.
use bytes;
use hash::H256;
use parachain;
/// Used to refer to a block number.
pub type Number = u64;
/// Hash used to refer to a block hash.
pub type HeaderHash = H256;
/// Hash used to refer to a transaction hash.
pub type TransactionHash = H256;
/// Execution log (event)
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct Log(#[serde(with="bytes")] pub Vec<u8>);
/// A relay chain block header.
///
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Header {
/// Block parent's hash.
pub parent_hash: HeaderHash,
/// Block number.
pub number: Number,
/// State root after this transition.
pub state_root: H256,
/// Parachain activity bitfield
pub parachain_activity: parachain::Activity,
/// Logs (generated by execution)
pub logs: Vec<Log>,
}
/// A relay chain block body.
///
/// Included candidates should be sorted by parachain ID, and without duplicate
/// IDs.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct Body {
/// Parachain proposal blocks.
pub candidates: Vec<parachain::Candidate>,
}
#[cfg(test)]
mod tests {
use super::*;
use polkadot_serializer as ser;
#[test]
fn test_header_serialization() {
assert_eq!(ser::to_string_pretty(&Header {
parent_hash: 5.into(),
number: 67,
state_root: 3.into(),
parachain_activity: parachain::Activity(vec![0]),
logs: vec![Log(vec![1])],
}), r#"{
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"number": 67,
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
"parachainActivity": "0x00",
"logs": [
"0x01"
]
}"#);
}
#[test]
fn test_body_serialization() {
assert_eq!(ser::to_string_pretty(&Body {
candidates: vec![
parachain::Candidate {
parachain_index: 10.into(),
collator_signature: Default::default(),
unprocessed_ingress: Default::default(),
block: ::parachain::BlockData(vec![1, 3, 5, 8]),
}
],
}), r#"{
"candidates": [
{
"parachainIndex": 10,
"collatorSignature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"unprocessedIngress": [],
"block": "0x01030508"
}
]
}"#);
}
}
+35 -4
View File
@@ -14,15 +14,29 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use std::fmt; use core::fmt;
use serde::{de, Serializer, Deserializer}; use serde::{de, Serializer, Deserializer};
#[cfg(not(feature = "std"))]
mod alloc_types {
pub use ::alloc::string::String;
pub use ::alloc::vec::Vec;
}
#[cfg(feature = "std")]
mod alloc_types {
pub use ::std::vec::Vec;
pub use ::std::string::String;
}
pub use self::alloc_types::*;
/// Serializes a slice of bytes. /// Serializes a slice of bytes.
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> where
S: Serializer, S: Serializer,
{ {
let hex = ::rustc_hex::ToHex::to_hex(bytes); let hex: String = ::rustc_hex::ToHex::to_hex(bytes);
serializer.serialize_str(&format!("0x{}", hex)) serializer.serialize_str(&format!("0x{}", hex))
} }
@@ -38,7 +52,7 @@ pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
return serializer.serialize_str("0x0"); return serializer.serialize_str("0x0");
} }
let hex = ::rustc_hex::ToHex::to_hex(bytes); let hex: String = ::rustc_hex::ToHex::to_hex(bytes);
let has_leading_zero = !hex.is_empty() && &hex[0..1] == "0"; let has_leading_zero = !hex.is_empty() && &hex[0..1] == "0";
serializer.serialize_str( serializer.serialize_str(
&format!("0x{}", if has_leading_zero { &hex[1..] } else { &hex }) &format!("0x{}", if has_leading_zero { &hex[1..] } else { &hex })
@@ -49,6 +63,7 @@ pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, PartialEq, Eq)]
pub enum ExpectedLen { pub enum ExpectedLen {
/// Any length in bytes. /// Any length in bytes.
#[cfg_attr(not(feature = "std"), allow(unused))]
Any, Any,
/// Exact length in bytes. /// Exact length in bytes.
Exact(usize), Exact(usize),
@@ -67,6 +82,7 @@ impl fmt::Display for ExpectedLen {
} }
/// Deserialize into vector of bytes. /// Deserialize into vector of bytes.
#[cfg(feature = "std")]
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> where pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
@@ -111,9 +127,24 @@ pub fn deserialize_check_len<'de, D>(deserializer: D, len: ExpectedLen) -> Resul
_ => ::rustc_hex::FromHex::from_hex(&v[2..]) _ => ::rustc_hex::FromHex::from_hex(&v[2..])
}; };
bytes.map_err(|e| E::custom(&format!("invalid hex value: {:?}", e))) #[cfg(feature = "std")]
fn format_err(e: ::rustc_hex::FromHexError) -> String {
format!("invalid hex value: {:?}", e)
}
#[cfg(not(feature = "std"))]
fn format_err(e: ::rustc_hex::FromHexError) -> String {
match e {
::rustc_hex::InvalidHexLength => format!("invalid hex value: invalid length"),
::rustc_hex::InvalidHexCharacter(c, p) =>
format!("invalid hex value: invalid character {} at position {}", c, p),
}
}
bytes.map_err(|e| E::custom(format_err(e)))
} }
#[cfg(feature = "std")]
fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> { fn visit_string<E: de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v) self.visit_str(&v)
} }
+14 -8
View File
@@ -16,20 +16,26 @@
//! Contract execution data. //! Contract execution data.
#[cfg(feature = "std")]
use bytes; use bytes;
use bytes::Vec;
/// Contract call data. /// Contract call data.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct CallData(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct CallData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Contract output data. /// Contract output data.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct OutData(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct OutData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Contract storage key. /// Contract storage key.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct StorageKey(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Contract storage entry data. /// Contract storage entry data.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct StorageData(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
+13 -3
View File
@@ -34,14 +34,24 @@ macro_rules! impl_serde {
.map(|x| (&*x).into()) .map(|x| (&*x).into())
} }
} }
impl ::codec::Slicable for $name {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
<[u8; $len] as ::codec::Slicable>::from_slice(value).map($name)
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.0.as_slice_then(f)
}
}
} }
} }
impl_hash!(H160, 20); construct_hash!(H160, 20);
impl_serde!(H160, 20); impl_serde!(H160, 20);
impl_hash!(H256, 32); construct_hash!(H256, 32);
impl_serde!(H256, 32); impl_serde!(H256, 32);
impl_hash!(H512, 64); construct_hash!(H512, 64);
impl_serde!(H512, 64); impl_serde!(H512, 64);
#[cfg(test)] #[cfg(test)]
+4 -4
View File
@@ -57,7 +57,7 @@ pub fn blake2_128(data: &[u8]) -> [u8; 16] {
/// Do a XX 128-bit hash and place result in `dest`. /// Do a XX 128-bit hash and place result in `dest`.
pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) { pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
use ::std::hash::Hasher; use ::core::hash::Hasher;
let mut h0 = twox_hash::XxHash::with_seed(0); let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1); let mut h1 = twox_hash::XxHash::with_seed(1);
h0.write(data); h0.write(data);
@@ -71,14 +71,14 @@ pub fn twox_128_into(data: &[u8], dest: &mut [u8; 16]) {
/// Do a XX 128-bit hash and return result. /// Do a XX 128-bit hash and return result.
pub fn twox_128(data: &[u8]) -> [u8; 16] { pub fn twox_128(data: &[u8]) -> [u8; 16] {
let mut r: [u8; 16] = unsafe { ::std::mem::uninitialized() }; let mut r: [u8; 16] = [0; 16];
twox_128_into(data, &mut r); twox_128_into(data, &mut r);
r r
} }
/// Do a XX 256-bit hash and place result in `dest`. /// Do a XX 256-bit hash and place result in `dest`.
pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) { pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
use ::std::hash::Hasher; use ::core::hash::Hasher;
use byteorder::{ByteOrder, LittleEndian}; use byteorder::{ByteOrder, LittleEndian};
let mut h0 = twox_hash::XxHash::with_seed(0); let mut h0 = twox_hash::XxHash::with_seed(0);
let mut h1 = twox_hash::XxHash::with_seed(1); let mut h1 = twox_hash::XxHash::with_seed(1);
@@ -100,7 +100,7 @@ pub fn twox_256_into(data: &[u8], dest: &mut [u8; 32]) {
/// Do a XX 256-bit hash and return result. /// Do a XX 256-bit hash and return result.
pub fn twox_256(data: &[u8]) -> [u8; 32] { pub fn twox_256(data: &[u8]) -> [u8; 32] {
let mut r: [u8; 32] = unsafe { ::std::mem::uninitialized() }; let mut r: [u8; 32] = [0; 32];
twox_256_into(data, &mut r); twox_256_into(data, &mut r);
r r
} }
+3 -3
View File
@@ -24,8 +24,8 @@ impl<'a> HexDisplay<'a> {
pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) } pub fn from(d: &'a AsBytesRef) -> Self { HexDisplay(d.as_bytes_ref()) }
} }
impl<'a> ::std::fmt::Display for HexDisplay<'a> { impl<'a> ::core::fmt::Display for HexDisplay<'a> {
fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { fn fmt(&self, fmtr: &mut ::core::fmt::Formatter) -> Result<(), ::core::fmt::Error> {
for byte in self.0 { for byte in self.0 {
try!( fmtr.write_fmt(format_args!("{:02x}", byte))); try!( fmtr.write_fmt(format_args!("{:02x}", byte)));
} }
@@ -47,7 +47,7 @@ impl AsBytesRef for [u8] {
fn as_bytes_ref(&self) -> &[u8] { &self } fn as_bytes_ref(&self) -> &[u8] { &self }
} }
impl AsBytesRef for Vec<u8> { impl AsBytesRef for ::bytes::Vec<u8> {
fn as_bytes_ref(&self) -> &[u8] { &self } fn as_bytes_ref(&self) -> &[u8] { &self }
} }
+64 -16
View File
@@ -18,52 +18,100 @@
#![warn(missing_docs)] #![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
extern crate rustc_hex; extern crate rustc_hex;
extern crate serde; extern crate serde;
extern crate ring;
extern crate untrusted;
extern crate twox_hash;
extern crate byteorder; extern crate byteorder;
#[cfg(feature = "std")]
extern crate twox_hash;
#[cfg(feature = "std")]
extern crate blake2_rfc; extern crate blake2_rfc;
#[macro_use] #[macro_use]
extern crate crunchy; extern crate crunchy;
#[macro_use] #[macro_use]
extern crate fixed_hash; extern crate fixed_hash;
#[cfg(feature = "std")]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
#[macro_use] #[macro_use]
extern crate uint as uint_crate; extern crate uint as uint_crate;
#[cfg(feature="std")] #[cfg(feature = "std")]
extern crate core; extern crate core;
extern crate polkadot_runtime_codec as codec;
#[cfg(test)] #[cfg(test)]
extern crate polkadot_serializer; extern crate polkadot_serializer;
#[cfg(test)] #[cfg(test)]
#[macro_use] #[macro_use]
extern crate pretty_assertions; extern crate pretty_assertions;
#[cfg(not(feature = "std"))]
#[macro_use]
extern crate alloc;
// TODO: factor out to separate crate.
macro_rules! try_opt {
($e: expr) => {
match $e {
Some(x) => x,
None => return None,
}
}
}
mod bytes; mod bytes;
pub mod block;
pub mod contract; pub mod contract;
pub mod hash; pub mod hash;
pub mod hexdisplay;
pub mod parachain; pub mod parachain;
pub mod relay;
pub mod uint; pub mod uint;
pub mod validator; pub mod validator;
pub mod ed25519;
pub mod hexdisplay; #[cfg(test)]
mod tests;
#[cfg(feature = "std")]
pub mod hashing; pub mod hashing;
/// Alias to 160-bit hash when used in the context of an account address. pub use self::hash::{H160, H256};
pub type Address = hash::H160; pub use self::relay::BlockNumber;
pub use self::uint::{U256, U512};
#[cfg(feature = "std")]
pub use hashing::{blake2_256, twox_128, twox_256};
/// Virtual account ID that represents the idea of a dispatch/statement being signed by everybody
/// (who matters). Essentially this means that a majority of validators have decided it is
/// "correct".
pub const EVERYBODY: AccountId = [255u8; 32];
/// Alias to Ed25519 pubkey that identifies an account.
pub type AccountId = [u8; 32];
/// The Ed25519 pub key of an session that belongs to an authority. This is used as what the
/// external environment/consensus algorithm calls an "authority".
pub type SessionKey = AccountId;
/// Indentifier for a chain.
pub type ChainID = u64;
/// Index of a transaction.
pub type TxOrder = u64;
/// A hash of some data.
pub type Hash = hash::H256;
/// Alias to 520-bit hash when used in the context of a signature. /// Alias to 520-bit hash when used in the context of a signature.
pub type Signature = hash::H512; pub type Signature = hash::H512;
pub use self::hash::{H160, H256}; /// A balance in the staking subsystem.
pub use self::uint::{U256, U512}; pub type Balance = u64;
pub use hashing::{blake2_256, twox_128, twox_256};
/// A hash function. /// A timestamp.
pub fn hash(data: &[u8]) -> hash::H256 { pub type Timestamp = u64;
blake2_256(data).into()
}
+54 -22
View File
@@ -16,10 +16,13 @@
//! Parachain data types. //! Parachain data types.
#[cfg(feature = "std")]
use bytes; use bytes;
use bytes::Vec;
/// Unique identifier of a parachain. /// Unique identifier of a parachain.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Id(u64); pub struct Id(u64);
impl From<Id> for u64 { impl From<Id> for u64 {
@@ -30,12 +33,23 @@ impl From<u64> for Id {
fn from(x: u64) -> Self { Id(x) } fn from(x: u64) -> Self { Id(x) }
} }
impl ::codec::Slicable for Id {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
u64::from_slice(value).map(Id)
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.0.as_slice_then(f)
}
}
/// Candidate parachain block. /// Candidate parachain block.
/// ///
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#candidate-para-chain-block /// https://github.com/w3f/polkadot-spec/blob/master/spec.md#candidate-para-chain-block
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[serde(deny_unknown_fields)] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Candidate { pub struct Candidate {
/// The ID of the parachain this is a proposal for. /// The ID of the parachain this is a proposal for.
pub parachain_index: Id, pub parachain_index: Id,
@@ -50,18 +64,19 @@ pub struct Candidate {
} }
/// Candidate receipt type. /// Candidate receipt type.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
#[serde(deny_unknown_fields)] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct CandidateReceipt { pub struct CandidateReceipt {
/// The ID of the parachain this is a candidate for. /// The ID of the parachain this is a candidate for.
pub parachain_index: Id, pub parachain_index: Id,
/// The collator's account ID /// The collator's account ID
pub collator: ::Address, pub collator: ::AccountId,
/// The head-data /// The head-data
pub head_data: HeadData, pub head_data: HeadData,
/// Balance uploads to the relay chain. /// Balance uploads to the relay chain.
pub balance_uploads: Vec<(::Address, ::uint::U256)>, pub balance_uploads: Vec<(::AccountId, ::uint::U256)>,
/// Egress queue roots. /// Egress queue roots.
pub egress_queue_roots: Vec<(Id, ::hash::H256)>, pub egress_queue_roots: Vec<(Id, ::hash::H256)>,
/// Fees paid from the chain to the relay chain validators /// Fees paid from the chain to the relay chain validators
@@ -69,37 +84,54 @@ pub struct CandidateReceipt {
} }
/// Parachain ingress queue message. /// Parachain ingress queue message.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct Message(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Message(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Consolidated ingress queue data. /// Consolidated ingress queue data.
/// ///
/// This is just an ordered vector of other parachains' egress queues, /// This is just an ordered vector of other parachains' egress queues,
/// obtained according to the routing rules. /// obtained according to the routing rules.
#[derive(Debug, Default, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, Default, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ConsolidatedIngress(pub Vec<(Id, Vec<Message>)>); pub struct ConsolidatedIngress(pub Vec<(Id, Vec<Message>)>);
/// Parachain block data. /// Parachain block data.
/// ///
/// contains everything required to validate para-block, may contain block and witness data /// contains everything required to validate para-block, may contain block and witness data
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct BlockData(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BlockData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Parachain header raw bytes wrapper type. /// Parachain header raw bytes wrapper type.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct Header(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Header(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Parachain head data included in the chain. /// Parachain head data included in the chain.
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone)]
pub struct HeadData(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Parachain validation code. /// Parachain validation code.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct ValidationCode(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct ValidationCode(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Activitiy bit field /// Activitiy bit field
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct Activity(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Activity(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl ::codec::Slicable for Activity {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Vec::<u8>::from_slice(value).map(Activity)
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.0.as_slice_then(f)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
+232
View File
@@ -0,0 +1,232 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Block and header type definitions.
#[cfg(feature = "std")]
use bytes;
use bytes::Vec;
use codec::Slicable;
use hash::H256;
use parachain;
use relay::transaction::UncheckedTransaction;
/// Used to refer to a block number.
pub type Number = u64;
/// Hash used to refer to a block hash.
pub type HeaderHash = H256;
/// Hash used to refer to a transaction hash.
pub type TransactionHash = H256;
/// Execution log (event)
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Log(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
impl Slicable for Log {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Vec::<u8>::from_slice(value).map(Log)
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.0.as_slice_then(f)
}
}
impl ::codec::NonTrivialSlicable for Log { }
/// The digest of a block, useful for light-clients.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Digest {
/// All logs that have happened in the block.
pub logs: Vec<Log>,
}
impl Slicable for Digest {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Vec::<Log>::from_slice(value).map(|logs| Digest { logs })
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.logs.as_slice_then(f)
}
}
/// A Polkadot relay chain block.
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Block {
/// The block header.
pub header: Header,
/// All relay-chain transactions.
pub transactions: Vec<UncheckedTransaction>,
}
impl Slicable for Block {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Some(Block {
header: try_opt!(Slicable::from_slice(value)),
transactions: try_opt!(Slicable::from_slice(value)),
})
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
v.extend(self.header.to_vec());
v.extend(self.transactions.to_vec());
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
/// A relay chain block header.
///
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Header {
/// Block parent's hash.
pub parent_hash: HeaderHash,
/// Block number.
pub number: Number,
/// State root after this transition.
pub state_root: H256,
/// The root of the trie that represents this block's transactions, indexed by a 32-byte integer.
pub transaction_root: H256,
/// The digest of activity on the block.
pub digest: Digest,
}
impl Header {
/// Create a new instance with default fields except `number`, which is given as an argument.
pub fn from_block_number(number: Number) -> Self {
Header {
parent_hash: Default::default(),
number,
state_root: Default::default(),
transaction_root: Default::default(),
digest: Default::default(),
}
}
}
impl Slicable for Header {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Some(Header {
parent_hash: try_opt!(Slicable::from_slice(value)),
number: try_opt!(Slicable::from_slice(value)),
state_root: try_opt!(Slicable::from_slice(value)),
transaction_root: try_opt!(Slicable::from_slice(value)),
digest: try_opt!(Slicable::from_slice(value)),
})
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
self.parent_hash.as_slice_then(|s| v.extend(s));
self.number.as_slice_then(|s| v.extend(s));
self.state_root.as_slice_then(|s| v.extend(s));
self.transaction_root.as_slice_then(|s| v.extend(s));
self.digest.as_slice_then(|s| v.extend(s));
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
/// A relay chain block body.
///
/// Included candidates should be sorted by parachain ID, and without duplicate
/// IDs.
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct Body {
/// Parachain proposal blocks.
pub candidates: Vec<parachain::Candidate>,
}
#[cfg(test)]
mod tests {
use super::*;
use codec::Slicable;
use polkadot_serializer as ser;
#[test]
fn test_header_serialization() {
let header = Header {
parent_hash: 5.into(),
number: 67,
state_root: 3.into(),
transaction_root: 6.into(),
digest: Digest { logs: vec![Log(vec![1])] },
};
assert_eq!(ser::to_string_pretty(&header), r#"{
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
"number": 67,
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
"transactionRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
"digest": {
"logs": [
"0x01"
]
}
}"#);
let v = header.to_vec();
assert_eq!(Header::from_slice(&mut &v[..]).unwrap(), header);
}
#[test]
fn test_body_serialization() {
assert_eq!(ser::to_string_pretty(&Body {
candidates: vec![
parachain::Candidate {
parachain_index: 10.into(),
collator_signature: Default::default(),
unprocessed_ingress: Default::default(),
block: ::parachain::BlockData(vec![1, 3, 5, 8]),
}
],
}), r#"{
"candidates": [
{
"parachainIndex": 10,
"collatorSignature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"unprocessedIngress": [],
"block": "0x01030508"
}
]
}"#);
}
}
+9
View File
@@ -0,0 +1,9 @@
//! Relay chain primitives.
pub mod block;
pub mod transaction;
pub use self::block::*;
pub use self::transaction::*;
pub use self::block::Number as BlockNumber;
@@ -0,0 +1,389 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Transaction type.
use bytes::Vec;
use codec::Slicable;
#[cfg(feature = "std")]
use std::fmt;
#[cfg(not(feature = "std"))]
use alloc::fmt;
use relay::block::Number as BlockNumber;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[repr(u8)]
enum InternalFunctionId {
/// Set the system's code.
SystemSetCode = 0x00,
/// Set the session length.
SessionSetLength = 0x10,
/// Force a new session.
SessionForceNewSession = 0x11,
/// Set the number of sessions per era.
StakingSetSessionsPerEra = 0x20,
/// Set the minimum bonding duration for staking.
StakingSetBondingDuration = 0x21,
/// Set the validator count for staking.
StakingSetValidatorCount = 0x22,
/// Force a new staking era.
StakingForceNewEra = 0x23,
/// Set the per-mille of validator approval required for governance changes.
GovernanceSetApprovalPpmRequired = 0x30,
}
impl InternalFunctionId {
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
fn from_u8(value: u8) -> Option<InternalFunctionId> {
let functions = [
InternalFunctionId::SystemSetCode,
InternalFunctionId::SessionSetLength,
InternalFunctionId::SessionForceNewSession,
InternalFunctionId::StakingSetSessionsPerEra,
InternalFunctionId::StakingSetBondingDuration,
InternalFunctionId::StakingSetValidatorCount,
InternalFunctionId::StakingForceNewEra,
InternalFunctionId::GovernanceSetApprovalPpmRequired,
];
functions.iter().map(|&f| f).find(|&f| value == f as u8)
}
}
/// Internal functions that can be dispatched to.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum InternalFunction {
/// Set the system's code.
SystemSetCode(Vec<u8>),
/// Set the session length.
SessionSetLength(BlockNumber),
/// Force a new session.
SessionForceNewSession,
/// Set the number of sessions per era.
StakingSetSessionsPerEra(BlockNumber),
/// Set the minimum bonding duration for staking.
StakingSetBondingDuration(BlockNumber),
/// Set the validator count for staking.
StakingSetValidatorCount(u32),
/// Force a new staking era.
StakingForceNewEra,
/// Set the per-mille of validator approval required for governance changes.
GovernanceSetApprovalPpmRequired(u32),
}
/// An internal function.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Proposal {
/// The privileged function to call.
pub function: InternalFunction,
}
impl Slicable for Proposal {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
let id = try_opt!(u8::from_slice(value).and_then(InternalFunctionId::from_u8));
let function = match id {
InternalFunctionId::SystemSetCode =>
InternalFunction::SystemSetCode(try_opt!(Slicable::from_slice(value))),
InternalFunctionId::SessionSetLength =>
InternalFunction::SessionSetLength(try_opt!(Slicable::from_slice(value))),
InternalFunctionId::SessionForceNewSession => InternalFunction::SessionForceNewSession,
InternalFunctionId::StakingSetSessionsPerEra =>
InternalFunction::StakingSetSessionsPerEra(try_opt!(Slicable::from_slice(value))),
InternalFunctionId::StakingSetBondingDuration =>
InternalFunction::StakingSetBondingDuration(try_opt!(Slicable::from_slice(value))),
InternalFunctionId::StakingSetValidatorCount =>
InternalFunction::StakingSetValidatorCount(try_opt!(Slicable::from_slice(value))),
InternalFunctionId::StakingForceNewEra => InternalFunction::StakingForceNewEra,
InternalFunctionId::GovernanceSetApprovalPpmRequired =>
InternalFunction::GovernanceSetApprovalPpmRequired(try_opt!(Slicable::from_slice(value))),
};
Some(Proposal { function })
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
match self.function {
InternalFunction::SystemSetCode(ref data) => {
(InternalFunctionId::SystemSetCode as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
InternalFunction::SessionSetLength(ref data) => {
(InternalFunctionId::SessionSetLength as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
InternalFunction::SessionForceNewSession => {
(InternalFunctionId::SessionForceNewSession as u8).as_slice_then(|s| v.extend(s));
}
InternalFunction::StakingSetSessionsPerEra(ref data) => {
(InternalFunctionId::StakingSetSessionsPerEra as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
InternalFunction::StakingSetBondingDuration(ref data) => {
(InternalFunctionId::StakingSetBondingDuration as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
InternalFunction::StakingSetValidatorCount(ref data) => {
(InternalFunctionId::StakingSetValidatorCount as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
InternalFunction::StakingForceNewEra => {
(InternalFunctionId::StakingForceNewEra as u8).as_slice_then(|s| v.extend(s));
}
InternalFunction::GovernanceSetApprovalPpmRequired(ref data) => {
(InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
}
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
/// Public functions that can be dispatched to.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[repr(u8)]
enum FunctionId {
/// Set the timestamp.
TimestampSet = 0x00,
/// Set temporary session key as a validator.
SessionSetKey = 0x10,
/// Staking subsystem: begin staking.
StakingStake = 0x20,
/// Staking subsystem: stop staking.
StakingUnstake = 0x21,
/// Staking subsystem: transfer stake.
StakingTransfer = 0x22,
/// Make a proposal for the governance system.
GovernancePropose = 0x30,
/// Approve a proposal for the governance system.
GovernanceApprove = 0x31,
}
impl FunctionId {
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
fn from_u8(value: u8) -> Option<FunctionId> {
use self::*;
let functions = [FunctionId::StakingStake, FunctionId::StakingUnstake,
FunctionId::StakingTransfer, FunctionId::SessionSetKey, FunctionId::TimestampSet,
FunctionId::GovernancePropose, FunctionId::GovernanceApprove];
functions.iter().map(|&f| f).find(|&f| value == f as u8)
}
}
/// Functions on the runtime.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Function {
/// Set the timestamp.
TimestampSet(::Timestamp),
/// Set temporary session key as a validator.
SessionSetKey(::SessionKey),
/// Staking subsystem: begin staking.
StakingStake,
/// Staking subsystem: stop staking.
StakingUnstake,
/// Staking subsystem: transfer stake.
StakingTransfer(::AccountId, ::Balance),
/// Make a proposal for the governance system.
GovernancePropose(Proposal),
/// Approve a proposal for the governance system.
GovernanceApprove(BlockNumber),
}
impl Slicable for Function {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
let id = try_opt!(u8::from_slice(value).and_then(FunctionId::from_u8));
Some(match id {
FunctionId::TimestampSet =>
Function::TimestampSet(try_opt!(Slicable::from_slice(value))),
FunctionId::SessionSetKey =>
Function::SessionSetKey(try_opt!(Slicable::from_slice(value))),
FunctionId::StakingStake => Function::StakingStake,
FunctionId::StakingUnstake => Function::StakingUnstake,
FunctionId::StakingTransfer => {
let to = try_opt!(Slicable::from_slice(value));
let amount = try_opt!(Slicable::from_slice(value));
Function::StakingTransfer(to, amount)
}
FunctionId::GovernancePropose =>
Function::GovernancePropose(try_opt!(Slicable::from_slice(value))),
FunctionId::GovernanceApprove =>
Function::GovernanceApprove(try_opt!(Slicable::from_slice(value))),
})
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
match *self {
Function::TimestampSet(ref data) => {
(FunctionId::TimestampSet as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
Function::SessionSetKey(ref data) => {
(FunctionId::SessionSetKey as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
Function::StakingStake => {
(FunctionId::StakingStake as u8).as_slice_then(|s| v.extend(s));
}
Function::StakingUnstake => {
(FunctionId::StakingUnstake as u8).as_slice_then(|s| v.extend(s));
}
Function::StakingTransfer(ref to, ref amount) => {
(FunctionId::StakingTransfer as u8).as_slice_then(|s| v.extend(s));
to.as_slice_then(|s| v.extend(s));
amount.as_slice_then(|s| v.extend(s));
}
Function::GovernancePropose(ref data) => {
(FunctionId::GovernancePropose as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
Function::GovernanceApprove(ref data) => {
(FunctionId::GovernanceApprove as u8).as_slice_then(|s| v.extend(s));
data.as_slice_then(|s| v.extend(s));
}
}
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
/// A vetted and verified transaction from the external world.
#[derive(Debug, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct Transaction {
/// Who signed it (note this is not a signature).
pub signed: ::AccountId,
/// The number of transactions have come before from the same signer.
pub nonce: ::TxOrder,
/// The function that should be called.
pub function: Function,
}
impl Slicable for Transaction {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Some(Transaction {
signed: try_opt!(Slicable::from_slice(value)),
nonce: try_opt!(Slicable::from_slice(value)),
function: try_opt!(Slicable::from_slice(value)),
})
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
self.signed.as_slice_then(|s| v.extend(s));
self.nonce.as_slice_then(|s| v.extend(s));
self.function.as_slice_then(|s| v.extend(s));
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
/// A transactions right from the external world. Unchecked.
#[derive(Eq, Clone)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct UncheckedTransaction {
/// The actual transaction information.
pub transaction: Transaction,
/// The signature; should be an Ed25519 signature applied to the serialised `transaction` field.
pub signature: ::Signature,
}
impl Slicable for UncheckedTransaction {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
Some(UncheckedTransaction {
transaction: try_opt!(Transaction::from_slice(value)),
signature: try_opt!(Slicable::from_slice(value)),
})
}
fn to_vec(&self) -> Vec<u8> {
let mut v = Vec::new();
self.transaction.signed.as_slice_then(|s| v.extend(s));
self.transaction.nonce.as_slice_then(|s| v.extend(s));
self.transaction.function.as_slice_then(|s| v.extend(s));
self.signature.as_slice_then(|s| v.extend(s));
v
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(self.to_vec().as_slice())
}
}
impl ::codec::NonTrivialSlicable for UncheckedTransaction {}
impl PartialEq for UncheckedTransaction {
fn eq(&self, other: &Self) -> bool {
self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
}
}
impl fmt::Debug for UncheckedTransaction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UncheckedTransaction({:?})", self.transaction)
}
}
#[cfg(test)]
mod tests {
use ::codec::Slicable;
use super::*;
#[test]
fn serialize_unchecked() {
let tx = UncheckedTransaction {
transaction: Transaction {
signed: [1; 32],
nonce: 999u64,
function: Function::TimestampSet(135135),
},
signature: ::hash::H512([0; 64]),
};
let v = Slicable::to_vec(&tx);
assert_eq!(UncheckedTransaction::from_slice(&mut &v[..]).unwrap(), tx);
}
}
@@ -16,27 +16,27 @@
//! Tests. //! Tests.
use super::*; use codec::Slicable;
use runtime_std::prelude::*;
use codec::{Joiner, Slicable}; use ::AccountId;
use primitives::Function; use relay::block::{Block, Header, Digest, Log};
use relay::transaction::{UncheckedTransaction, Transaction, Function};
#[test] #[test]
fn serialise_transaction_works() { fn serialise_transaction_works() {
let one: AccountID = [1u8; 32]; let one: AccountId = [1u8; 32];
let two: AccountID = [2u8; 32]; let two: AccountId = [2u8; 32];
let tx = Transaction { let tx = Transaction {
signed: one.clone(), signed: one.clone(),
nonce: 69, nonce: 69,
function: Function::StakingTransfer, function: Function::StakingTransfer(two, 69),
input_data: Vec::new().join(&two).join(&69u64),
}; };
let serialised = tx.to_vec(); let serialised = tx.to_vec();
assert_eq!(serialised, vec![ assert_eq!(serialised, vec![
1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
34, 34,
40, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
69, 0, 0, 0, 0, 0, 0, 0 69, 0, 0, 0, 0, 0, 0, 0
]); ]);
@@ -44,34 +44,33 @@ fn serialise_transaction_works() {
#[test] #[test]
fn deserialise_transaction_works() { fn deserialise_transaction_works() {
let one: AccountID = [1u8; 32]; let one: AccountId = [1u8; 32];
let two: AccountID = [2u8; 32]; let two: AccountId = [2u8; 32];
let tx = Transaction { let tx = Transaction {
signed: one.clone(), signed: one.clone(),
nonce: 69, nonce: 69,
function: Function::StakingTransfer, function: Function::StakingTransfer(two, 69),
input_data: Vec::new().join(&two).join(&69u64),
}; };
let data = [ let data = [
1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
34, 34,
40, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
69, 0, 0, 0, 0, 0, 0, 0 69, 0, 0, 0, 0, 0, 0, 0
]; ];
let deserialised = Transaction::from_slice(&data).unwrap(); let deserialised = Transaction::from_slice(&mut &data[..]).unwrap();
assert_eq!(deserialised, tx); assert_eq!(deserialised, tx);
} }
#[test] #[test]
fn serialise_header_works() { fn serialise_header_works() {
let h = Header { let h = Header {
parent_hash: [4u8; 32], parent_hash: [4u8; 32].into(),
number: 42, number: 42,
state_root: [5u8; 32], state_root: [5u8; 32].into(),
transaction_root: [6u8; 32], transaction_root: [6u8; 32].into(),
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
}; };
let serialised = h.to_vec(); let serialised = h.to_vec();
assert_eq!(serialised, vec![ assert_eq!(serialised, vec![
@@ -79,7 +78,7 @@ fn serialise_header_works() {
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
26, 0, 0, 0, 2, 0, 0, 0,
7, 0, 0, 0, 7, 0, 0, 0,
111, 110, 101, 32, 108, 111, 103, 111, 110, 101, 32, 108, 111, 103,
11, 0, 0, 0, 11, 0, 0, 0,
@@ -90,55 +89,53 @@ fn serialise_header_works() {
#[test] #[test]
fn deserialise_header_works() { fn deserialise_header_works() {
let h = Header { let h = Header {
parent_hash: [4u8; 32], parent_hash: [4u8; 32].into(),
number: 42, number: 42,
state_root: [5u8; 32], state_root: [5u8; 32].into(),
transaction_root: [6u8; 32], transaction_root: [6u8; 32].into(),
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
}; };
let data = [ let data = [
4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
26, 0, 0, 0, 2, 0, 0, 0,
7, 0, 0, 0, 7, 0, 0, 0,
111, 110, 101, 32, 108, 111, 103, 111, 110, 101, 32, 108, 111, 103,
11, 0, 0, 0, 11, 0, 0, 0,
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103
]; ];
let deserialised = Header::from_slice(&data).unwrap(); let deserialised = Header::from_slice(&mut &data[..]).unwrap();
assert_eq!(deserialised, h); assert_eq!(deserialised, h);
} }
#[test] #[test]
fn serialise_block_works() { fn serialise_block_works() {
let one: AccountID = [1u8; 32]; let one: AccountId = [1u8; 32];
let two: AccountID = [2u8; 32]; let two: AccountId = [2u8; 32];
let tx1 = UncheckedTransaction { let tx1 = UncheckedTransaction {
transaction: Transaction { transaction: Transaction {
signed: one.clone(), signed: one.clone(),
nonce: 69, nonce: 69,
function: Function::StakingTransfer, function: Function::StakingTransfer(two, 69),
input_data: Vec::new().join(&two).join(&69u64),
}, },
signature: [1u8; 64], signature: [1u8; 64].into(),
}; };
let tx2 = UncheckedTransaction { let tx2 = UncheckedTransaction {
transaction: Transaction { transaction: Transaction {
signed: two.clone(), signed: two.clone(),
nonce: 42, nonce: 42,
function: Function::StakingStake, function: Function::StakingStake,
input_data: Vec::new(),
}, },
signature: [2u8; 64], signature: [2u8; 64].into(),
}; };
let h = Header { let h = Header {
parent_hash: [4u8; 32], parent_hash: [4u8; 32].into(),
number: 42, number: 42,
state_root: [5u8; 32], state_root: [5u8; 32].into(),
transaction_root: [6u8; 32], transaction_root: [6u8; 32].into(),
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
}; };
let b = Block { let b = Block {
header: h, header: h,
@@ -151,58 +148,54 @@ fn serialise_block_works() {
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
26, 0, 0, 0, 2, 0, 0, 0,
7, 0, 0, 0, 7, 0, 0, 0,
111, 110, 101, 32, 108, 111, 103, 111, 110, 101, 32, 108, 111, 103,
11, 0, 0, 0, 11, 0, 0, 0,
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
// transactions // transactions
2, 1, 0, 0, 2, 0, 0, 0,
// tx1 // tx1
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
34, 34,
40, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// tx2 // tx2
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
32, 32,
0, 0, 0, 0 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
]); ]);
} }
#[test] #[test]
fn deserialise_block_works() { fn deserialise_block_works() {
let one: AccountID = [1u8; 32]; let one: AccountId = [1u8; 32];
let two: AccountID = [2u8; 32]; let two: AccountId = [2u8; 32];
let tx1 = UncheckedTransaction { let tx1 = UncheckedTransaction {
transaction: Transaction { transaction: Transaction {
signed: one.clone(), signed: one.clone(),
nonce: 69, nonce: 69,
function: Function::StakingTransfer, function: Function::StakingTransfer(two, 69),
input_data: Vec::new().join(&two).join(&69u64),
}, },
signature: [1u8; 64], signature: [1u8; 64].into(),
}; };
let tx2 = UncheckedTransaction { let tx2 = UncheckedTransaction {
transaction: Transaction { transaction: Transaction {
signed: two.clone(), signed: two.clone(),
nonce: 42, nonce: 42,
function: Function::StakingStake, function: Function::StakingStake,
input_data: Vec::new(),
}, },
signature: [2u8; 64], signature: [2u8; 64].into(),
}; };
let h = Header { let h = Header {
parent_hash: [4u8; 32], parent_hash: [4u8; 32].into(),
number: 42, number: 42,
state_root: [5u8; 32], state_root: [5u8; 32].into(),
transaction_root: [6u8; 32], transaction_root: [6u8; 32].into(),
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], }, digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
}; };
let b = Block { let b = Block {
header: h, header: h,
@@ -214,28 +207,26 @@ fn deserialise_block_works() {
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
26, 0, 0, 0, 2, 0, 0, 0,
7, 0, 0, 0, 7, 0, 0, 0,
111, 110, 101, 32, 108, 111, 103, 111, 110, 101, 32, 108, 111, 103,
11, 0, 0, 0, 11, 0, 0, 0,
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103, 97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
// transactions // transactions
2, 1, 0, 0, 2, 0, 0, 0,
// tx1 // tx1
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
34, 34,
40, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
69, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// tx2 // tx2
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
42, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0,
32, 32,
0, 0, 0, 0 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
]; ];
let deserialised = Block::from_slice(&data).unwrap(); let deserialised = Block::from_slice(&mut &data[..]).unwrap();
assert_eq!(deserialised, b); assert_eq!(deserialised, b);
} }
+15 -29
View File
@@ -16,25 +16,31 @@
//! Validator primitives. //! Validator primitives.
#[cfg(feature = "std")]
use bytes; use bytes;
use bytes::Vec;
use parachain; use parachain;
/// Parachain outgoing message. /// Parachain outgoing message.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct EgressPost(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct EgressPost(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Balance upload. /// Balance upload.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct BalanceUpload(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BalanceUpload(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// Balance download. /// Balance download.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
pub struct BalanceDownload(#[serde(with="bytes")] pub Vec<u8>); #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub struct BalanceDownload(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
/// The result of parachain validation. /// The result of parachain validation.
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
#[serde(deny_unknown_fields)] #[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
pub struct ValidationResult { pub struct ValidationResult {
/// New head data that should be included in the relay chain state. /// New head data that should be included in the relay chain state.
pub head_data: parachain::HeadData, pub head_data: parachain::HeadData,
@@ -44,26 +50,6 @@ pub struct ValidationResult {
pub balance_uploads: Vec<BalanceUpload>, pub balance_uploads: Vec<BalanceUpload>,
} }
// TODO [ToDr] This shouldn't be here!
/// Validator logic.
pub trait Validator {
/// Validation error.
type Error: ::std::error::Error;
/// Validates if the provided proof holds given a current ingress queue.
///
/// In case of success produces egress posts.
fn validate(
&self,
code: &[u8],
// TODO [ToDr] actually consolidate
consolidated_ingress: &[(u64, Vec<parachain::Message>)],
balance_downloads: &[BalanceDownload],
block_data: &parachain::BlockData,
previous_head_data: &parachain::HeadData,
) -> Result<ValidationResult, Self::Error>;
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
+1 -1
View File
@@ -9,7 +9,7 @@ jsonrpc-core = { git="https://github.com/paritytech/jsonrpc.git" }
jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" } jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" }
polkadot-client = { path = "../client", version = "0.1" } polkadot-client = { path = "../client", version = "0.1" }
polkadot-primitives = { path = "../primitives", version = "0.1" } polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-state-machine = { path = "../state_machine", version = "0.1" } polkadot-state-machine = { path = "../state-machine", version = "0.1" }
[dev-dependencies] [dev-dependencies]
assert_matches = "1.1" assert_matches = "1.1"
+1 -1
View File
@@ -16,7 +16,7 @@
//! Polkadot blockchain API. //! Polkadot blockchain API.
use primitives::block; use primitives::relay::block;
use client; use client;
use state_machine; use state_machine;
+3 -3
View File
@@ -23,13 +23,13 @@ fn should_return_header() {
let client = client::new_in_mem(executor::executor()).unwrap(); let client = client::new_in_mem(executor::executor()).unwrap();
assert_matches!( assert_matches!(
ChainApi::header(&client, "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into()), ChainApi::header(&client, "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into()),
Ok(Some(ref x)) if x == &block::Header { Ok(Some(ref x)) if x == &block::Header {
parent_hash: 0.into(), parent_hash: 0.into(),
number: 0, number: 0,
state_root: 0.into(), state_root: 0.into(),
parachain_activity: Default::default(), transaction_root: Default::default(),
logs: vec![], digest: Default::default(),
} }
); );
+1 -1
View File
@@ -22,7 +22,7 @@ mod error;
mod tests; mod tests;
use client::{self, Client}; use client::{self, Client};
use primitives::{block}; use primitives::relay::block;
use primitives::contract::{CallData, StorageKey, StorageData}; use primitives::contract::{CallData, StorageKey, StorageData};
use state_machine; use state_machine;
+2 -2
View File
@@ -23,7 +23,7 @@ use client;
#[test] #[test]
fn should_return_storage() { fn should_return_storage() {
let client = client::new_in_mem(executor::executor()).unwrap(); let client = client::new_in_mem(executor::executor()).unwrap();
let genesis_hash = "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into(); let genesis_hash = "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into();
assert_matches!( assert_matches!(
StateApi::storage(&client, StorageKey(vec![10]), genesis_hash), StateApi::storage(&client, StorageKey(vec![10]), genesis_hash),
@@ -36,7 +36,7 @@ fn should_return_storage() {
fn should_call_contract() { fn should_call_contract() {
// TODO [ToDr] Fix test after we are able to mock state. // TODO [ToDr] Fix test after we are able to mock state.
let client = client::new_in_mem(executor::executor()).unwrap(); let client = client::new_in_mem(executor::executor()).unwrap();
let genesis_hash = "11265ce45dd2baaaf071f6df8c5a44f0ed1d85a50e71451ff2d4345e57d12e3a".into(); let genesis_hash = "af65e54217fb213853703d57b80fc5b2bb834bf923046294d7a49bff62f0a8b2".into();
assert_matches!( assert_matches!(
StateApi::call(&client, "balanceOf".into(), CallData(vec![1,2,3]), genesis_hash), StateApi::call(&client, "balanceOf".into(), CallData(vec![1,2,3]), genesis_hash),
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "polkadot-runtime-codec"
description = "Serialization and deserialization codec for runtime values"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
[features]
std = []
default = ["std"]
@@ -14,19 +14,20 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Vec<u8> serialiser. //! Trait
use runtime_std::prelude::*; use std::iter::Extend;
use super::slicable::Slicable; use super::slicable::Slicable;
/// Trait to allow itself to be serialised into a `Vec<u8>` /// Trait to allow itself to be serialised into a value which can be extended
/// by bytes.
pub trait Joiner { pub trait Joiner {
fn join<T: Slicable + Sized>(self, value: &T) -> Self; fn join<V: Slicable + Sized>(self, value: &V) -> Self;
} }
impl Joiner for Vec<u8> { impl<T> Joiner for T where T: for<'a> Extend<&'a u8> {
fn join<T: Slicable + Sized>(mut self, value: &T) -> Vec<u8> { fn join<V: Slicable + Sized>(mut self, value: &V) -> Self {
value.as_slice_then(|s| self.extend_from_slice(s)); value.as_slice_then(|s| self.extend(s));
self self
} }
} }
@@ -16,8 +16,9 @@
//! Serialiser and prepender. //! Serialiser and prepender.
use runtime_std::prelude::*; use slicable::Slicable;
use super::slicable::Slicable; use std::iter::Extend;
use std::vec::Vec;
/// Trait to allow itselg to be serialised and prepended by a given slice. /// Trait to allow itselg to be serialised and prepended by a given slice.
pub trait KeyedVec { pub trait KeyedVec {
@@ -29,7 +30,7 @@ macro_rules! impl_non_endians {
impl KeyedVec for $t { impl KeyedVec for $t {
fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> {
let mut r = prepend_key.to_vec(); let mut r = prepend_key.to_vec();
r.extend_from_slice(&self[..]); r.extend(&self[..]);
r r
} }
} }
@@ -42,7 +43,7 @@ macro_rules! impl_endians {
fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> { fn to_keyed_vec(&self, prepend_key: &[u8]) -> Vec<u8> {
self.as_slice_then(|slice| { self.as_slice_then(|slice| {
let mut r = prepend_key.to_vec(); let mut r = prepend_key.to_vec();
r.extend_from_slice(slice); r.extend(slice);
r r
}) })
} }
@@ -14,16 +14,26 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Codec utils. //! Implements the serialization and deserialization codec for polkadot runtime
//! values.
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]
mod endiansensitive; mod endiansensitive;
mod slicable; mod slicable;
mod streamreader;
mod joiner; mod joiner;
mod keyedvec; mod keyedvec;
pub use self::endiansensitive::EndianSensitive; pub use self::endiansensitive::EndianSensitive;
pub use self::slicable::{Slicable, NonTrivialSlicable}; pub use self::slicable::{Slicable, NonTrivialSlicable};
pub use self::streamreader::StreamReader;
pub use self::joiner::Joiner; pub use self::joiner::Joiner;
pub use self::keyedvec::KeyedVec; pub use self::keyedvec::KeyedVec;
#[cfg(not(feature = "std"))]
mod std {
extern crate alloc;
pub use core::*;
pub use self::alloc::vec;
}
+142
View File
@@ -0,0 +1,142 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Serialisation.
use std::{mem, slice};
use std::vec::Vec;
use super::joiner::Joiner;
use super::endiansensitive::EndianSensitive;
/// Trait that allows zero-copy read/write of value-references to/from slices in LE format.
pub trait Slicable: Sized {
/// Attempt to deserialise the value from a slice. Ignore trailing bytes and
/// set the slice's start to just after the last byte consumed.
///
/// If `None` is returned, then the slice should be unmodified.
fn from_slice(value: &mut &[u8]) -> Option<Self>;
/// Convert self to an owned vector.
fn to_vec(&self) -> Vec<u8> {
self.as_slice_then(|s| s.to_vec())
}
/// Convert self to a slice and then invoke the given closure with it.
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R;
}
/// Trait to mark that a type is not trivially (essentially "in place") serialisable.
pub trait NonTrivialSlicable: Slicable {}
impl<T: EndianSensitive> Slicable for T {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
let size = mem::size_of::<T>();
assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type.");
if value.len() >= size {
let x: T = unsafe { ::std::ptr::read(value.as_ptr() as *const T) };
*value = &value[size..];
Some(x.from_le())
} else {
None
}
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
self.as_le_then(|le| {
let size = mem::size_of::<T>();
let value_slice = unsafe {
let ptr = le as *const _ as *const u8;
if size != 0 {
slice::from_raw_parts(ptr, size)
} else {
&[]
}
};
f(value_slice)
})
}
}
impl Slicable for Vec<u8> {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
u32::from_slice(value).map(move |len| {
let len = len as usize;
let res = value[..len].to_vec();
*value = &value[len..];
res
})
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&self.to_vec())
}
fn to_vec(&self) -> Vec<u8> {
let len = self.len();
assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements.");
let mut r: Vec<u8> = Vec::new().join(&(len as u32));
r.extend_from_slice(self);
r
}
}
impl<T: Slicable> NonTrivialSlicable for Vec<T> where Vec<T>: Slicable {}
impl<T: NonTrivialSlicable> Slicable for Vec<T> {
fn from_slice(value: &mut &[u8]) -> Option<Self> {
u32::from_slice(value).and_then(move |len| {
let len = len as usize;
let mut r = Vec::with_capacity(len);
for _ in 0..len {
match T::from_slice(value) {
None => return None,
Some(v) => r.push(v),
}
}
Some(r)
})
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&self.to_vec())
}
fn to_vec(&self) -> Vec<u8> {
use std::iter::Extend;
let len = self.len();
assert!(len <= u32::max_value() as usize, "Attempted to serialize vec with too many elements.");
let mut r: Vec<u8> = Vec::new().join(&(len as u32));
for item in self {
r.extend(item.to_vec());
}
r
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vec_is_slicable() {
let v = b"Hello world".to_vec();
v.as_slice_then(|ref slice|
assert_eq!(slice, &b"\x0b\0\0\0Hello world")
);
}
}
+31
View File
@@ -0,0 +1,31 @@
[package]
name = "polkadot-runtime-std"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
build = "build.rs"
[build-dependencies]
rustc_version = "0.2"
[dependencies]
pwasm-alloc = { path = "../wasm-runtime/pwasm-alloc", version = "0.1" }
pwasm-libc = { path = "../wasm-runtime/pwasm-libc", version = "0.1" }
environmental = { path = "../environmental", version = "0.1", optional = true }
polkadot-state-machine = { path = "../state-machine", version = "0.1", optional = true }
polkadot-primitives = { path = "../primitives", version = "0.1", default_features = false }
polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1", default_features = false }
triehash = { version = "0.1", optional = true }
ed25519 = { path = "../ed25519", version = "0.1", optional = true }
[features]
default = ["std"]
std = [
"environmental",
"polkadot-state-machine",
"triehash",
"polkadot-primitives/std",
"polkadot-runtime-codec/std",
"ed25519",
]
nightly = []
strict = []
+14
View File
@@ -0,0 +1,14 @@
//! Set a nightly feature
extern crate rustc_version;
use rustc_version::{version, version_meta, Channel};
fn main() {
// Assert we haven't travelled back in time
assert!(version().unwrap().major >= 1);
// Set cfg flags depending on release channel
if let Channel::Nightly = version_meta().unwrap().channel {
println!("cargo:rustc-cfg=feature=\"nightly\"");
}
}
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(lang_items))]
#![cfg_attr(not(feature = "std"), feature(core_intrinsics))]
#![cfg_attr(not(feature = "std"), feature(alloc))]
#![cfg_attr(feature = "std", doc = "Polkadot runtime standard library as compiled when linked with Rust's standard library.")]
#![cfg_attr(not(feature = "std"), doc = "Polkadot's runtime standard library as compiled without Rust's standard library.")]
extern crate polkadot_runtime_codec as codec;
#[cfg(feature = "std")]
include!("../with_std.rs");
#[cfg(not(feature = "std"))]
include!("../without_std.rs");
/// Prelude of common useful imports.
///
/// This should include only things which are in the normal std prelude.
pub mod prelude {
pub use ::vec::Vec;
pub use ::boxed::Box;
}
/// Type definitions and helpers for transactions.
pub mod transaction {
pub use primitives::relay::{Transaction, UncheckedTransaction};
use primitives::Signature;
#[cfg(feature = "std")]
use std::ops;
#[cfg(not(feature = "std"))]
use core::ops;
/// A type-safe indicator that a transaction has been checked.
#[derive(PartialEq, Eq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct CheckedTransaction(UncheckedTransaction);
impl CheckedTransaction {
/// Get a reference to the checked signature.
pub fn signature(&self) -> &Signature {
&self.0.signature
}
}
impl ops::Deref for CheckedTransaction {
type Target = Transaction;
fn deref(&self) -> &Transaction {
&self.0.transaction
}
}
/// Check the signature on a transaction.
///
/// On failure, return the transaction back.
pub fn check(tx: UncheckedTransaction) -> Result<CheckedTransaction, UncheckedTransaction> {
let msg = ::codec::Slicable::to_vec(&tx.transaction);
if ::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) {
Ok(CheckedTransaction(tx))
} else {
Err(tx)
}
}
}
@@ -14,16 +14,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. // along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! The with-std support functions for the runtime.
#[macro_use] #[macro_use]
extern crate environmental; extern crate environmental;
extern crate polkadot_state_machine; extern crate polkadot_state_machine;
extern crate polkadot_primitives as primitives; extern crate polkadot_primitives as primitives;
extern crate triehash; extern crate triehash;
extern crate ed25519;
use std::fmt;
use primitives::ed25519;
pub use std::vec; pub use std::vec;
pub use std::rc; pub use std::rc;
@@ -32,26 +29,14 @@ pub use std::boxed;
pub use std::slice; pub use std::slice;
pub use std::mem; pub use std::mem;
/// Prelude of common useful imports. // re-export hashing functions.
/// pub use primitives::{blake2_256, twox_128, twox_256};
/// This should include only things which are in the normal std prelude.
pub mod prelude {
pub use std::vec::Vec;
pub use std::boxed::Box;
}
pub use polkadot_state_machine::{Externalities, ExternalitiesError, TestExternalities}; pub use polkadot_state_machine::{Externalities, ExternalitiesError, TestExternalities};
use primitives::hexdisplay::HexDisplay; use primitives::hexdisplay::HexDisplay;
// TODO: use the real error, not NoError. // TODO: use the real error, not NoError.
#[derive(Debug)]
/// As it says - an empty type we use for errors.
pub struct NoError;
impl fmt::Display for NoError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") }
}
environmental!(ext : trait Externalities); environmental!(ext : trait Externalities);
/// Get `key` from storage and return a `Vec`, empty if there's a problem. /// Get `key` from storage and return a `Vec`, empty if there's a problem.
@@ -105,12 +90,9 @@ pub fn enumerated_trie_root(serialised_values: &[&[u8]]) -> [u8; 32] {
triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0 triehash::ordered_trie_root(serialised_values.iter().map(|s| s.to_vec())).0
} }
/// Conduct a Keccak-256 hash of the given data.
pub use primitives::{blake2_256, twox_128, twox_256};
/// Verify a ed25519 signature. /// Verify a ed25519 signature.
pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool { pub fn ed25519_verify(sig: &[u8; 64], msg: &[u8], pubkey: &[u8; 32]) -> bool {
ed25519::verify(&sig[..], msg, &pubkey[..]) ed25519::verify(sig, msg, pubkey)
} }
/// Execute the given closure with global function available whose functionality routes into the /// Execute the given closure with global function available whose functionality routes into the
@@ -119,6 +101,7 @@ pub fn with_externalities<R, F: FnOnce() -> R>(ext: &mut Externalities, f: F) ->
ext::using(ext, f) ext::using(ext, f)
} }
/// Trait for things which can be printed.
pub trait Printable { pub trait Printable {
fn print(self); fn print(self);
} }
@@ -141,6 +124,7 @@ impl Printable for u64 {
} }
} }
/// Print a printable value.
pub fn print<T: Printable + Sized>(value: T) { pub fn print<T: Printable + Sized>(value: T) {
value.print(); value.print();
} }
@@ -151,7 +135,7 @@ macro_rules! impl_stubs {
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod std_tests {
use super::*; use super::*;
macro_rules! map { macro_rules! map {
@@ -1,13 +1,13 @@
#![no_std] #[cfg(feature = "nightly")]
#![feature(lang_items)]
#![feature(core_intrinsics)]
#![feature(alloc)]
#![cfg_attr(feature = "strict", deny(warnings))]
#[macro_use]
#[macro_export]
extern crate alloc; extern crate alloc;
#[cfg(feature = "nightly")]
extern crate pwasm_libc;
#[cfg(feature = "nightly")]
extern crate pwasm_alloc;
extern crate polkadot_primitives as primitives;
pub use alloc::vec; pub use alloc::vec;
pub use alloc::boxed; pub use alloc::boxed;
pub use alloc::rc; pub use alloc::rc;
@@ -15,17 +15,8 @@ pub use core::mem;
pub use core::slice; pub use core::slice;
pub use core::cell; pub use core::cell;
/// Common re-exports that are useful to have in scope.
pub mod prelude {
pub use alloc::vec::Vec;
pub use alloc::boxed::Box;
}
use alloc::vec::Vec; use alloc::vec::Vec;
extern crate pwasm_libc;
extern crate pwasm_alloc;
#[lang = "panic_fmt"] #[lang = "panic_fmt"]
#[no_mangle] #[no_mangle]
pub extern fn panic_fmt(_fmt: ::core::fmt::Arguments, _file: &'static str, _line: u32, _col: u32) { pub extern fn panic_fmt(_fmt: ::core::fmt::Arguments, _file: &'static str, _line: u32, _col: u32) {
@@ -53,6 +44,7 @@ extern "C" {
fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32; fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32;
} }
/// Get `key` from storage and return a `Vec`, empty if there's a problem.
pub fn storage(key: &[u8]) -> Vec<u8> { pub fn storage(key: &[u8]) -> Vec<u8> {
let mut length: u32 = 0; let mut length: u32 = 0;
unsafe { unsafe {
@@ -61,6 +53,7 @@ pub fn storage(key: &[u8]) -> Vec<u8> {
} }
} }
/// Set the storage to some particular key.
pub fn set_storage(key: &[u8], value: &[u8]) { pub fn set_storage(key: &[u8], value: &[u8]) {
unsafe { unsafe {
ext_set_storage( ext_set_storage(
@@ -70,6 +63,8 @@ pub fn set_storage(key: &[u8], value: &[u8]) {
} }
} }
/// Get `key` from storage, placing the value into `value_out` (as much as possible) and return
/// the number of bytes that the key in storage was.
pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize { pub fn read_storage(key: &[u8], value_out: &mut [u8], value_offset: usize) -> usize {
unsafe { unsafe {
ext_get_storage_into(key.as_ptr(), key.len() as u32, value_out.as_mut_ptr(), value_out.len() as u32, value_offset as u32) as usize ext_get_storage_into(key.as_ptr(), key.len() as u32, value_out.as_mut_ptr(), value_out.len() as u32, value_offset as u32) as usize
@@ -141,6 +136,7 @@ pub fn ed25519_verify(sig: &[u8], msg: &[u8], pubkey: &[u8]) -> bool {
} == 0 } == 0
} }
/// Trait for things which can be printed.
pub trait Printable { pub trait Printable {
fn print(self); fn print(self);
} }
@@ -167,6 +163,7 @@ impl Printable for u64 {
} }
} }
/// Print a printable value.
pub fn print<T: Printable + Sized>(value: T) { pub fn print<T: Printable + Sized>(value: T) {
value.print(); value.print();
} }
+1 -1
View File
@@ -4,5 +4,5 @@ version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"] authors = ["Parity Technologies <admin@parity.io>"]
[dependencies] [dependencies]
serde = "1.0" serde = { version = "1.0", default_features = false }
serde_json = "1.0" serde_json = "1.0"
@@ -17,8 +17,6 @@
//! State machine backends. These manage the code and storage of contracts. //! State machine backends. These manage the code and storage of contracts.
use std::{error, fmt}; use std::{error, fmt};
use primitives::hash::H256;
use triehash::sec_trie_root;
use super::{Update, MemoryState}; use super::{Update, MemoryState};
@@ -19,7 +19,8 @@
#![warn(missing_docs)] #![warn(missing_docs)]
extern crate polkadot_primitives as primitives; extern crate polkadot_primitives as primitives;
#[macro_use]
#[cfg_attr(test, macro_use)]
extern crate hex_literal; extern crate hex_literal;
extern crate hashdb; extern crate hashdb;
@@ -201,7 +202,6 @@ pub fn execute<B: backend::Backend, Exec: CodeExecutor>(
}; };
// make a copy. // make a copy.
let code = externalities.storage(b":code").unwrap_or(&[]).to_vec(); let code = externalities.storage(b":code").unwrap_or(&[]).to_vec();
use primitives::hexdisplay::HexDisplay;
exec.call( exec.call(
&mut externalities, &mut externalities,
+3 -5
View File
@@ -20,7 +20,7 @@ use primitives::{validator, parachain};
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serializer; use serializer;
use error::{Error, ErrorKind, Result}; use error::{ErrorKind, Result};
use parachains::{ParachainCode, ParaChain1}; use parachains::{ParachainCode, ParaChain1};
/// A dummy validator implementation. /// A dummy validator implementation.
@@ -40,10 +40,8 @@ impl Validator {
} }
} }
impl validator::Validator for Validator { impl Validator {
type Error = Error; pub fn validate(
fn validate(
&self, &self,
code: &[u8], code: &[u8],
consolidated_ingress: &[(u64, Vec<parachain::Message>)], consolidated_ingress: &[(u64, Vec<parachain::Message>)],
+835 -7
View File
@@ -1,8 +1,447 @@
[[package]]
name = "aho-corasick"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ansi_term"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayvec"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bigint"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "blake2-rfc"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "coco"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "constant_time_eq"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "crunchy"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ed25519"
version = "0.1.0"
dependencies = [
"polkadot-primitives 0.1.0",
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "elastic-array"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "environmental"
version = "0.1.0"
[[package]]
name = "ethcore-bigint"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ethcore-bytes"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ethcore-logger"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fixed-hash"
version = "0.1.3"
source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71"
dependencies = [
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gcc"
version = "0.3.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hashdb"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "heapsize"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex-literal"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hex-literal-impl"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "isatty"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "keccak-hash"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memorydb"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "odds"
version = "0.2.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "owning_ref"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "patricia-trie"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "plain_hasher"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "polkadot-primitives"
version = "0.1.0"
dependencies = [
"blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
"polkadot-runtime-codec 0.1.0",
"rustc-hex 2.0.0 (git+https://github.com/rphmeier/rustc-hex.git)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
]
[[package]]
name = "polkadot-runtime-codec"
version = "0.1.0"
[[package]]
name = "polkadot-runtime-std"
version = "0.1.0"
dependencies = [
"ed25519 0.1.0",
"environmental 0.1.0",
"polkadot-primitives 0.1.0",
"polkadot-runtime-codec 0.1.0",
"polkadot-state-machine 0.1.0",
"pwasm-alloc 0.1.0",
"pwasm-libc 0.1.0",
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "polkadot-state-machine"
version = "0.1.0"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-primitives 0.1.0",
"triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro-hack"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro-hack-impl"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "pwasm-alloc" name = "pwasm-alloc"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"pwasm-libc 0.1.0", "pwasm-libc 0.1.0",
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@@ -10,24 +449,413 @@ name = "pwasm-libc"
version = "0.1.0" version = "0.1.0"
[[package]] [[package]]
name = "runtime-polkadot" name = "quote"
version = "0.1.0" version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"runtime-std 0.1.0", "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "runtime-std" name = "rand"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ring"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rlp"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "runtime-polkadot"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"pwasm-alloc 0.1.0", "polkadot-primitives 0.1.0",
"pwasm-libc 0.1.0", "polkadot-runtime-codec 0.1.0",
"polkadot-runtime-std 0.1.0",
] ]
[[package]] [[package]]
name = "runtime-test" name = "runtime-test"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"runtime-std 0.1.0", "polkadot-runtime-std 0.1.0",
] ]
[[package]]
name = "rustc-hex"
version = "1.0.0"
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"
[[package]]
name = "rustc_version"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scopeguard"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "semver"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "stable_deref_trait"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tiny-keccak"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "triehash"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "twox-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uint"
version = "0.1.2"
source = "git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm#8dc457899afdaf968ff7f16140b03d1e37b01d71"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unreachable"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "untrusted"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "utf8-ranges"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum arrayvec 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)" = "06f59fe10306bb78facd90d28c2038ad23ffaaefa85bac43c8a434cde383334f"
"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
"checksum bigint 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5442186ef6560f30f1ee4b9c1e4c87a35a6879d3644550cc248ec2b955eb5fcd"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3"
"checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum ethcore-bigint 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcb5af77e74a8f70e9c3337e069c37bc82178ef1b459c02091f73c4ad5281eb5"
"checksum ethcore-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3977c772cd6c5c22e1c7cfa208e4c3b746bd6c3a6c8eeec0999a6b2103015ad5"
"checksum ethcore-logger 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fd5813e49546030be7d134e775088d56b8ff4ab60617b90e93d4f0513da4c5b"
"checksum fixed-hash 0.1.3 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "<none>"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
"checksum hashdb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d97be07c358c5b461268b4ce60304024c5fa5acfd4bd8cd743639f0252003cf5"
"checksum heapsize 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461"
"checksum hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd546ef520ab3745f1aae5f2cdc6de9e6498e94d1ab138b9eb3ddfbf335847fb"
"checksum hex-literal-impl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2ea76da4c7f1a54d01d54985566d3fdd960b2bbd7b970da024821c883c2d9631"
"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2"
"checksum keccak-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f300c1f149cd9ca5214eed24f6e713a597517420fb8b15499824aa916259ec1"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d"
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum memorydb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013b7e4c5e10c764936ebc6bd3662d8e3c92292d267bf6a42ef3f5cad9c793ee"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum odds 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "4eae0151b9dacf24fcc170d9995e511669a082856a91f958a2fe380bfab3fb22"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "149d8f5b97f3c1133e3cfcd8886449959e856b557ff281e292b733d7c69e005e"
"checksum parking_lot_core 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "9f35048d735bb93dd115a0030498785971aab3234d311fbe273d020084d26bd8"
"checksum patricia-trie 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e2f638d79aba5c4a71a4f373df6e3cd702250a53b7f0ed4da1e2a7be9737ae"
"checksum plain_hasher 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83ae80873992f511142c07d0ec6c44de5636628fdb7e204abd655932ea79d995"
"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c"
"checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9"
"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_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"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 serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0"
"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5"
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum tiny-keccak 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9241752647ca572f12c9b520a5d360d9099360c527770647e694001646a1d0"
"checksum triehash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9291c7f0fae44858b5e087dd462afb382354120003778f1695b44aab98c7abd7"
"checksum twox-hash 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "475352206e7a290c5fccc27624a163e8d0d115f7bb60ca18a64fc9ce056d7435"
"checksum uint 0.1.2 (git+https://github.com/rphmeier/primitives.git?branch=compile-for-wasm)" = "<none>"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+5 -4
View File
@@ -7,9 +7,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
runtime-std = { path = "../std", version = "0.1" } polkadot-runtime-codec = { path = "../../runtime-codec", version = "0.1", default-features = false }
polkadot-runtime-std = { path = "../../runtime-std", version = "0.1", default-features = false }
polkadot-primitives = { path = "../../primitives", version = "0.1", default-features = false }
[features] [features]
default = ["without-std"] default = []
with-std = [] std = ["polkadot-runtime-codec/std", "polkadot-runtime-std/std", "polkadot-primitives/std"]
without-std = []
@@ -1,149 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Serialisation.
use runtime_std::prelude::*;
use runtime_std::{mem, slice};
use super::joiner::Joiner;
use super::endiansensitive::EndianSensitive;
/// Trait that allows zero-copy read/write of value-references to/from slices in LE format.
pub trait Slicable: Sized {
fn from_slice(value: &[u8]) -> Option<Self> {
Self::set_as_slice(&|out, offset| if value.len() >= out.len() + offset {
let value = &value[offset..];
let len = out.len();
out.copy_from_slice(&value[0..len]);
true
} else {
false
})
}
fn to_vec(&self) -> Vec<u8> {
self.as_slice_then(|s| s.to_vec())
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(set_slice: &F) -> Option<Self>;
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
f(&self.to_vec())
}
fn size_of(_value: &[u8]) -> Option<usize>;
}
/// Trait to mark that a type is not trivially (essentially "in place") serialisable.
pub trait NonTrivialSlicable: Slicable {}
impl<T: EndianSensitive> Slicable for T {
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(fill_slice: &F) -> Option<Self> {
let size = mem::size_of::<T>();
assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type.");
let mut result: T = unsafe { mem::zeroed() };
let result_slice = unsafe {
let ptr = &mut result as *mut _ as *mut u8;
slice::from_raw_parts_mut(ptr, size)
};
if fill_slice(result_slice, 0) {
Some(result.from_le())
} else {
None
}
}
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
let size = mem::size_of::<Self>();
assert!(size > 0, "EndianSensitive can never be implemented for a zero-sized type.");
self.as_le_then(|le| {
let value_slice = unsafe {
let ptr = le as *const _ as *const u8;
slice::from_raw_parts(ptr, size)
};
f(value_slice)
})
}
fn size_of(_value: &[u8]) -> Option<usize> {
Some(mem::size_of::<Self>())
}
}
impl Slicable for Vec<u8> {
fn from_slice(value: &[u8]) -> Option<Self> {
Some(value[4..].to_vec())
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(fill_slice: &F) -> Option<Self> {
u32::set_as_slice(fill_slice).and_then(|len| {
let mut v = Vec::with_capacity(len as usize);
v.resize(len as usize, 0);
// unsafe { v.set_len(len as usize); }
if fill_slice(&mut v, 4) {
Some(v)
} else {
None
}
})
}
fn to_vec(&self) -> Vec<u8> {
let mut r: Vec<u8> = Vec::new().join(&(self.len() as u32));
r.extend_from_slice(&self);
r
}
fn size_of(data: &[u8]) -> Option<usize> {
u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize)
}
}
impl<T: Slicable> NonTrivialSlicable for Vec<T> where Vec<T>: Slicable {}
impl<T: NonTrivialSlicable> Slicable for Vec<T> {
fn from_slice(value: &[u8]) -> Option<Self> {
let len = Self::size_of(value)?;
let mut off = 4;
let mut r = Vec::new();
while off < len {
let element_len = T::size_of(&value[off..])?;
r.push(T::from_slice(&value[off..off + element_len])?);
off += element_len;
}
Some(r)
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(_fill_slice: &F) -> Option<Self> {
unimplemented!();
}
fn to_vec(&self) -> Vec<u8> {
let vecs = self.iter().map(Slicable::to_vec).collect::<Vec<_>>();
let len = vecs.iter().fold(0, |mut a, v| {a += v.len(); a});
let mut r = Vec::new().join(&(len as u32));
vecs.iter().for_each(|v| r.extend_from_slice(v));
r
}
fn size_of(data: &[u8]) -> Option<usize> {
u32::from_slice(&data[0..4]).map(|i| (i + 4) as usize)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vec_is_slicable() {
let v = b"Hello world".to_vec();
v.as_slice_then(|ref slice|
assert_eq!(slice, &b"\x0b\0\0\0Hello world")
);
}
}
@@ -1,74 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Deserialiser.
use super::slicable::Slicable;
/// Simple deserialiser.
pub struct StreamReader<'a> {
data: &'a [u8],
offset: usize,
}
impl<'a> StreamReader<'a> {
/// Create a new deserialiser based on the `data`.
pub fn new(data: &'a [u8]) -> Self {
StreamReader {
data: data,
offset: 0,
}
}
/// Deserialise a single item from the data stream.
pub fn read<T: Slicable>(&mut self) -> Option<T> {
let size = T::size_of(&self.data[self.offset..])?;
let new_offset = self.offset + size;
let slice = &self.data[self.offset..new_offset];
self.offset = new_offset;
Slicable::from_slice(slice)
}
}
/*
// Not in use yet
// TODO: introduce fn size_will_be(&self) -> usize; to Slicable trait and implement
struct StreamWriter<'a> {
data: &'a mut[u8],
offset: usize,
}
impl<'a> StreamWriter<'a> {
pub fn new(data: &'a mut[u8]) -> Self {
StreamWriter {
data: data,
offset: 0,
}
}
pub fn write<T: Slicable>(&mut self, value: &T) -> bool {
value.as_slice_then(|s| {
let new_offset = self.offset + s.len();
if self.data.len() <= new_offset {
let slice = &mut self.data[self.offset..new_offset];
self.offset = new_offset;
slice.copy_from_slice(s);
true
} else {
false
}
})
}
}
*/
+22 -21
View File
@@ -16,59 +16,60 @@
//! The Polkadot runtime. This can be compiled with #[no_std], ready for Wasm. //! The Polkadot runtime. This can be compiled with #[no_std], ready for Wasm.
#![cfg_attr(feature = "without-std", no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "strict", deny(warnings))]
#[macro_use] #[macro_use]
extern crate runtime_std; extern crate polkadot_runtime_std as runtime_std;
#[cfg(feature = "with-std")] #[cfg(feature = "std")]
extern crate rustc_hex; extern crate rustc_hex;
#[cfg(feature = "with-std")] #[cfg(feature = "with-std")]
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate polkadot_runtime_codec as codec;
extern crate polkadot_primitives as primitives;
#[cfg(test)] #[cfg(test)]
#[macro_use] #[macro_use]
extern crate hex_literal; extern crate hex_literal;
pub mod codec;
#[macro_use] #[macro_use]
pub mod support; pub mod support;
pub mod primitives;
pub mod runtime; pub mod runtime;
use runtime_std::prelude::*; use runtime_std::prelude::*;
use codec::{Slicable, Joiner}; use codec::Slicable;
use runtime_std::print; use primitives::relay::{Header, Block, UncheckedTransaction};
use primitives::{Block, Header, UncheckedTransaction};
/// Execute a block, with `input` being the canonical serialisation of the block. Returns the /// Execute a block, with `input` being the canonical serialisation of the block. Returns the
/// empty vector. /// empty vector.
pub fn execute_block(input: &[u8]) -> Vec<u8> { pub fn execute_block(mut input: &[u8]) -> Vec<u8> {
runtime::system::internal::execute_block(Block::from_slice(input).unwrap()); runtime::system::internal::execute_block(Block::from_slice(&mut input).unwrap());
Vec::new() Vec::new()
} }
/// Execute a given, serialised, transaction. Returns the empty vector. /// Execute a given, serialised, transaction. Returns the empty vector.
pub fn execute_transaction(input: &[u8]) -> Vec<u8> { pub fn execute_transaction(mut input: &[u8]) -> Vec<u8> {
let header = Header::from_slice(input).unwrap(); let header = Header::from_slice(&mut input).unwrap();
let utx = UncheckedTransaction::from_slice(&input[Header::size_of(input).unwrap()..]).unwrap(); let utx = UncheckedTransaction::from_slice(&mut input).unwrap();
let header = runtime::system::internal::execute_transaction(&utx, header); let header = runtime::system::internal::execute_transaction(utx, header);
Vec::new().join(&header) header.to_vec()
} }
/// Execute a given, serialised, transaction. Returns the empty vector. /// Execute a given, serialised, transaction. Returns the empty vector.
pub fn finalise_block(input: &[u8]) -> Vec<u8> { pub fn finalise_block(mut input: &[u8]) -> Vec<u8> {
let header = Header::from_slice(input).unwrap(); let header = Header::from_slice(&mut input).unwrap();
let header = runtime::system::internal::finalise_block(header); let header = runtime::system::internal::finalise_block(header);
Vec::new().join(&header) header.to_vec()
} }
/// Run whatever tests we have. /// Run whatever tests we have.
pub fn run_tests(input: &[u8]) -> Vec<u8> { pub fn run_tests(mut input: &[u8]) -> Vec<u8> {
use runtime_std::print;
print("run_tests..."); print("run_tests...");
let block = Block::from_slice(input).unwrap(); let block = Block::from_slice(&mut input).unwrap();
print("deserialised block."); print("deserialised block.");
let stxs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>(); let stxs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>();
print("reserialised transactions."); print("reserialised transactions.");
@@ -1,58 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Block type.
use runtime_std::prelude::*;
use codec::{StreamReader, Joiner, Slicable, NonTrivialSlicable};
use primitives::{Header, UncheckedTransaction};
/// A Polkadot relay chain block.
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
pub struct Block {
/// The header of the block.
pub header: Header,
/// All transactions.
pub transactions: Vec<UncheckedTransaction>,
}
impl Slicable for Block {
fn from_slice(value: &[u8]) -> Option<Self> {
let mut reader = StreamReader::new(value);
Some(Block {
header: reader.read()?,
transactions: reader.read()?,
})
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(_fill_slice: &F) -> Option<Self> {
unimplemented!();
}
fn to_vec(&self) -> Vec<u8> {
Vec::new()
.join(&self.header)
.join(&self.transactions)
}
fn size_of(data: &[u8]) -> Option<usize> {
let first_part = Header::size_of(data)?;
let second_part = <Vec<UncheckedTransaction>>::size_of(&data[first_part..])?;
Some(first_part + second_part)
}
}
impl NonTrivialSlicable for Block {}
@@ -1,27 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Digest type.
use runtime_std::prelude::*;
#[derive(Clone, Default, PartialEq)]
#[cfg_attr(feature = "with-std", derive(Debug))]
/// The digest of a block, useful for light-clients.
pub struct Digest {
/// All logs that have happened in the block.
pub logs: Vec<Vec<u8>>,
}
@@ -1,82 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Function data: This describes a function that can be called from an external transaction.
use primitives::AccountID;
use codec::StreamReader;
use runtime::{staking, session, timestamp, governance};
/// Public functions that can be dispatched to.
#[derive(Clone, Copy)]
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
#[repr(u8)]
pub enum Function {
TimestampSet = 0x00,
SessionSetKey = 0x10,
StakingStake = 0x20,
StakingUnstake = 0x21,
StakingTransfer = 0x22,
GovernancePropose = 0x30,
GovernanceApprove = 0x31,
}
impl Function {
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
pub fn from_u8(value: u8) -> Option<Function> {
use self::*;
let functions = [Function::StakingStake, Function::StakingUnstake,
Function::StakingTransfer, Function::SessionSetKey, Function::TimestampSet,
Function::GovernancePropose, Function::GovernanceApprove];
functions.iter().map(|&f| f).find(|&f| value == f as u8)
}
}
impl Function {
/// Dispatch the function.
pub fn dispatch(&self, transactor: &AccountID, data: &[u8]) {
let mut params = StreamReader::new(data);
match *self {
Function::StakingStake => {
staking::public::stake(transactor);
}
Function::StakingUnstake => {
staking::public::unstake(transactor);
}
Function::StakingTransfer => {
let dest = params.read().unwrap();
let value = params.read().unwrap();
staking::public::transfer(transactor, &dest, value);
}
Function::SessionSetKey => {
let session = params.read().unwrap();
session::public::set_key(transactor, &session);
}
Function::TimestampSet => {
let t = params.read().unwrap();
timestamp::public::set(t);
}
Function::GovernancePropose => {
let proposal = params.read().unwrap();
governance::public::propose(transactor, &proposal);
}
Function::GovernanceApprove => {
let era_index = params.read().unwrap();
governance::public::approve(transactor, era_index);
}
}
}
}
@@ -1,85 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Block header type.
use runtime_std::prelude::*;
use codec::{StreamReader, Joiner, Slicable, NonTrivialSlicable};
use runtime_std::mem;
use primitives::{BlockNumber, Hash, Digest};
#[derive(Clone)]
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
/// The header for a block.
pub struct Header {
/// The parent block's "hash" (actually the Blake2-256 hash of its serialised header).
pub parent_hash: Hash,
/// The block's number (how many ancestors does it have?).
pub number: BlockNumber,
/// The root of the trie that represents this block's final storage map.
pub state_root: Hash,
/// The root of the trie that represents this block's transactions, indexed by a 32-bit integer.
pub transaction_root: Hash,
/// The digest for this block.
pub digest: Digest,
}
impl Header {
/// Create a new instance with default fields except `number`, which is given as an argument.
pub fn from_block_number(number: BlockNumber) -> Self {
Header {
parent_hash: Default::default(),
number,
state_root: Default::default(),
transaction_root: Default::default(),
digest: Default::default(),
}
}
}
impl Slicable for Header {
fn from_slice(value: &[u8]) -> Option<Self> {
let mut reader = StreamReader::new(value);
Some(Header {
parent_hash: reader.read()?,
number: reader.read()?,
state_root: reader.read()?,
transaction_root: reader.read()?,
digest: Digest { logs: reader.read()?, },
})
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(_fill_slice: &F) -> Option<Self> {
unimplemented!();
}
fn to_vec(&self) -> Vec<u8> {
Vec::new()
.join(&self.parent_hash)
.join(&self.number)
.join(&self.state_root)
.join(&self.transaction_root)
.join(&self.digest.logs)
}
fn size_of(data: &[u8]) -> Option<usize> {
let first_part = mem::size_of::<Hash>() + mem::size_of::<BlockNumber>() + mem::size_of::<Hash>() + mem::size_of::<Hash>();
let second_part = <Vec<Vec<u8>>>::size_of(&data[first_part..])?;
Some(first_part + second_part)
}
}
impl NonTrivialSlicable for Header {}
@@ -1,41 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Miscellaneous small types.
/// The Ed25519 pubkey that identifies an account.
pub type AccountID = [u8; 32];
/// Virtual account ID that represents the idea of a dispatch/statement being signed by everybody
/// (who matters). Essentially this means that a majority of validators have decided it is
/// "correct".
pub const EVERYBODY: AccountID = [255u8; 32];
/// The Ed25519 pub key of an session that belongs to an authority. This is used as what the
/// external environment/consensus algorithm calls an "authority".
pub type SessionKey = AccountID;
/// Indentifier for a chain.
pub type ChainID = u64;
/// Index of a block in the chain.
pub type BlockNumber = u64;
/// Index of a transaction.
pub type TxOrder = u64;
/// A hash of some data.
pub type Hash = [u8; 32];
@@ -1,38 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Primitive types for the runtime.
mod misc;
mod proposal;
mod function;
mod digest;
mod header;
mod transaction;
mod uncheckedtransaction;
mod block;
#[cfg(test)]
mod tests;
pub use self::misc::{AccountID, EVERYBODY, SessionKey, ChainID, BlockNumber, TxOrder, Hash};
pub use self::proposal::{Proposal, InternalFunction};
pub use self::function::Function;
pub use self::digest::Digest;
pub use self::header::Header;
pub use self::transaction::Transaction;
pub use self::uncheckedtransaction::UncheckedTransaction;
pub use self::block::Block;
@@ -1,146 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Proposal: This describes a combination of a function ID and data that can be used to call into
//! an internal function.
use runtime_std::prelude::*;
use runtime_std::mem;
use codec::{Slicable, Joiner, StreamReader};
use runtime::{system, governance, staking, session};
/// Internal functions that can be dispatched to.
#[derive(Clone, Copy)]
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
#[repr(u8)]
pub enum InternalFunction {
SystemSetCode = 0x00,
SessionSetLength = 0x10,
SessionForceNewSession = 0x11,
StakingSetSessionsPerEra = 0x20,
StakingSetBondingDuration = 0x21,
StakingSetValidatorCount = 0x22,
StakingForceNewEra = 0x23,
GovernanceSetApprovalPpmRequired = 0x30,
}
impl InternalFunction {
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
pub fn from_u8(value: u8) -> Option<InternalFunction> {
use self::*;
let functions = [
InternalFunction::SystemSetCode,
InternalFunction::SessionSetLength,
InternalFunction::SessionForceNewSession,
InternalFunction::StakingSetSessionsPerEra,
InternalFunction::StakingSetBondingDuration,
InternalFunction::StakingSetValidatorCount,
InternalFunction::StakingForceNewEra,
InternalFunction::GovernanceSetApprovalPpmRequired,
];
functions.iter().map(|&f| f).find(|&f| value == f as u8)
}
}
/// An internal function.
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
pub struct Proposal {
/// The priviledged function to call.
pub function: InternalFunction,
/// The serialised data to call it with.
pub input_data: Vec<u8>,
}
impl Slicable for Proposal {
fn set_as_slice<F: Fn(&mut[u8], usize) -> bool>(fill_slice: &F) -> Option<Self> {
Some(Proposal {
function: InternalFunction::from_u8(Slicable::set_as_slice(fill_slice)?)?,
input_data: Slicable::set_as_slice(&|s, o| fill_slice(s, o + 1))?,
})
}
fn to_vec(&self) -> Vec<u8> {
Vec::new()
.join(&(self.function as u8))
.join(&self.input_data)
}
fn size_of(data: &[u8]) -> Option<usize> {
let first_part = mem::size_of::<u8>();
let second_part = <Vec<u8>>::size_of(&data[first_part..])?;
Some(first_part + second_part)
}
}
impl Proposal {
pub fn enact(&self) {
let mut params = StreamReader::new(&self.input_data);
match self.function {
InternalFunction::SystemSetCode => {
let code: Vec<u8> = params.read().unwrap();
system::privileged::set_code(&code);
}
InternalFunction::SessionSetLength => {
let value = params.read().unwrap();
session::privileged::set_length(value);
}
InternalFunction::SessionForceNewSession => {
session::privileged::force_new_session();
}
InternalFunction::StakingSetSessionsPerEra => {
let value = params.read().unwrap();
staking::privileged::set_sessions_per_era(value);
}
InternalFunction::StakingSetBondingDuration => {
let value = params.read().unwrap();
staking::privileged::set_bonding_duration(value);
}
InternalFunction::StakingSetValidatorCount => {
let value = params.read().unwrap();
staking::privileged::set_validator_count(value);
}
InternalFunction::StakingForceNewEra => {
staking::privileged::force_new_era();
}
InternalFunction::GovernanceSetApprovalPpmRequired => {
let value = params.read().unwrap();
governance::privileged::set_approval_ppm_required(value);
}
}
}
}
#[cfg(test)]
mod test {
use super::*;
use support::StaticHexInto;
#[test]
fn slicing_should_work() {
let p = Proposal {
function: InternalFunction::SystemSetCode,
input_data: b"Hello world".to_vec(),
};
let v = p.to_vec();
assert_eq!(v, "000b00000048656c6c6f20776f726c64".convert::<Vec<u8>>());
let o = Proposal::from_slice(&v).unwrap();
assert_eq!(p, o);
}
}
@@ -1,67 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Transaction type.
use runtime_std::prelude::*;
use codec::{StreamReader, Joiner, Slicable, NonTrivialSlicable};
use primitives::{AccountID, TxOrder, Function};
use runtime_std::mem;
/// A vetted and verified transaction from the external world.
#[cfg_attr(feature = "with-std", derive(PartialEq, Debug))]
pub struct Transaction {
/// Who signed it (note this is not a signature).
pub signed: AccountID,
/// The number of transactions have come before from the same signer.
pub nonce: TxOrder,
/// The function that should be called.
pub function: Function,
/// Serialised input data to the function.
pub input_data: Vec<u8>,
}
impl Slicable for Transaction {
fn from_slice(value: &[u8]) -> Option<Self> {
let mut reader = StreamReader::new(value);
Some(Transaction {
signed: reader.read()?,
nonce: reader.read()?,
function: Function::from_u8(reader.read()?)?,
input_data: reader.read()?,
})
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(_fill_slice: &F) -> Option<Self> {
unimplemented!();
}
fn to_vec(&self) -> Vec<u8> {
Vec::new()
.join(&self.signed)
.join(&self.nonce)
.join(&(self.function as u8))
.join(&self.input_data)
}
fn size_of(data: &[u8]) -> Option<usize> {
let first_part = mem::size_of::<AccountID>() + mem::size_of::<TxOrder>() + mem::size_of::<u8>();
let second_part = <Vec<u8>>::size_of(&data[first_part..])?;
Some(first_part + second_part)
}
}
impl NonTrivialSlicable for Transaction {}
@@ -1,83 +0,0 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Unchecked Transaction type.
use runtime_std::{mem, ed25519_verify};
use runtime_std::prelude::*;
use codec::{Slicable, NonTrivialSlicable, StreamReader, Joiner};
use primitives::Transaction;
#[cfg(feature = "with-std")]
use std::fmt;
/// A transactions right from the external world. Unchecked.
pub struct UncheckedTransaction {
/// The actual transaction information.
pub transaction: Transaction,
/// The signature; should be an Ed25519 signature applied to the serialised `transaction` field.
pub signature: [u8; 64],
}
impl UncheckedTransaction {
/// Verify the signature.
pub fn ed25519_verify(&self) -> bool {
let msg = self.transaction.to_vec();
ed25519_verify(&self.signature, &msg, &self.transaction.signed)
}
}
#[cfg(feature = "with-std")]
impl PartialEq for UncheckedTransaction {
fn eq(&self, other: &Self) -> bool {
self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
}
}
#[cfg(feature = "with-std")]
impl fmt::Debug for UncheckedTransaction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UncheckedTransaction({:?})", self.transaction)
}
}
impl Slicable for UncheckedTransaction {
fn from_slice(value: &[u8]) -> Option<Self> {
let mut reader = StreamReader::new(value);
Some(UncheckedTransaction {
signature: reader.read()?,
transaction: reader.read()?,
})
}
fn set_as_slice<F: Fn(&mut [u8], usize) -> bool>(_fill_slice: &F) -> Option<Self> {
unimplemented!();
}
fn to_vec(&self) -> Vec<u8> {
Vec::new()
.join(&self.signature)
.join(&self.transaction)
}
fn size_of(data: &[u8]) -> Option<usize> {
let first_part = mem::size_of::<[u8; 64]>();
let second_part = <Transaction>::size_of(&data[first_part..])?;
Some(first_part + second_part)
}
}
impl NonTrivialSlicable for UncheckedTransaction {}
@@ -20,14 +20,15 @@ use std::collections::HashMap;
use runtime_std::twox_128; use runtime_std::twox_128;
use codec::{KeyedVec, Joiner}; use codec::{KeyedVec, Joiner};
use support::Hashable; use support::Hashable;
use primitives::{AccountID, BlockNumber, Block}; use primitives::relay::{Number as BlockNumber, Block};
use primitives::AccountId;
use runtime::staking::Balance; use runtime::staking::Balance;
/// Configuration of a general Polkadot genesis block. /// Configuration of a general Polkadot genesis block.
pub struct GenesisConfig { pub struct GenesisConfig {
pub validators: Vec<AccountID>, pub validators: Vec<AccountId>,
pub authorities: Vec<AccountID>, pub authorities: Vec<AccountId>,
pub balances: Vec<(AccountID, Balance)>, pub balances: Vec<(AccountId, Balance)>,
pub block_time: u64, pub block_time: u64,
pub session_length: BlockNumber, pub session_length: BlockNumber,
pub sessions_per_era: BlockNumber, pub sessions_per_era: BlockNumber,
@@ -36,7 +37,7 @@ pub struct GenesisConfig {
} }
impl GenesisConfig { impl GenesisConfig {
pub fn new_simple(authorities_validators: Vec<AccountID>, balance: Balance) -> Self { pub fn new_simple(authorities_validators: Vec<AccountId>, balance: Balance) -> Self {
GenesisConfig { GenesisConfig {
validators: authorities_validators.clone(), validators: authorities_validators.clone(),
authorities: authorities_validators.clone(), authorities: authorities_validators.clone(),
@@ -28,7 +28,8 @@
use runtime_std::prelude::*; use runtime_std::prelude::*;
use codec::KeyedVec; use codec::KeyedVec;
use support::storage; use support::storage;
use primitives::{AccountID, Hash, BlockNumber, Proposal}; use primitives::{AccountId, Hash, BlockNumber};
use primitives::relay::Proposal;
use runtime::{staking, system, session}; use runtime::{staking, system, session};
const APPROVALS_REQUIRED: &[u8] = b"gov:apr"; const APPROVALS_REQUIRED: &[u8] = b"gov:apr";
@@ -52,7 +53,7 @@ pub mod public {
/// Propose a sensitive action to be taken. Any action that is enactable by `Proposal` is valid. /// Propose a sensitive action to be taken. Any action that is enactable by `Proposal` is valid.
/// Proposal is by the `transactor` and will automatically count as an approval. Transactor must /// Proposal is by the `transactor` and will automatically count as an approval. Transactor must
/// be a current validator. It is illegal to propose when there is already a proposal in effect. /// be a current validator. It is illegal to propose when there is already a proposal in effect.
pub fn propose(validator: &AccountID, proposal: &Proposal) { pub fn propose(validator: &AccountId, proposal: &Proposal) {
if storage::exists(CURRENT_PROPOSAL) { if storage::exists(CURRENT_PROPOSAL) {
panic!("there may only be one proposal per era."); panic!("there may only be one proposal per era.");
} }
@@ -62,7 +63,7 @@ pub mod public {
/// Approve the current era's proposal. Transactor must be a validator. This may not be done more /// Approve the current era's proposal. Transactor must be a validator. This may not be done more
/// than once for any validator in an era. /// than once for any validator in an era.
pub fn approve(validator: &AccountID, era_index: BlockNumber) { pub fn approve(validator: &AccountId, era_index: BlockNumber) {
if era_index != staking::current_era() { if era_index != staking::current_era() {
panic!("approval vote applied on non-current era.") panic!("approval vote applied on non-current era.")
} }
@@ -94,6 +95,7 @@ pub mod privileged {
pub mod internal { pub mod internal {
use super::*; use super::*;
use primitives::relay::{Proposal, InternalFunction};
/// Current era is ending; we should finish up any proposals. /// Current era is ending; we should finish up any proposals.
pub fn end_of_an_era() { pub fn end_of_an_era() {
@@ -105,10 +107,40 @@ pub mod internal {
.take(approvals_required as usize) .take(approvals_required as usize)
.count() as u32; .count() as u32;
if approved == approvals_required { if approved == approvals_required {
proposal.enact(); enact_proposal(proposal);
} }
} }
} }
fn enact_proposal(proposal: Proposal) {
match proposal.function {
InternalFunction::SystemSetCode(code) => {
system::privileged::set_code(&code);
}
InternalFunction::SessionSetLength(value) => {
session::privileged::set_length(value);
}
InternalFunction::SessionForceNewSession => {
session::privileged::force_new_session();
}
InternalFunction::StakingSetSessionsPerEra(value) => {
staking::privileged::set_sessions_per_era(value);
}
InternalFunction::StakingSetBondingDuration(value) => {
staking::privileged::set_bonding_duration(value);
}
InternalFunction::StakingSetValidatorCount(value) => {
staking::privileged::set_validator_count(value);
}
InternalFunction::StakingForceNewEra => {
staking::privileged::force_new_era()
}
InternalFunction::GovernanceSetApprovalPpmRequired(value) => {
self::privileged::set_approval_ppm_required(value);
}
}
}
} }
#[cfg(test)] #[cfg(test)]
@@ -117,7 +149,8 @@ mod tests {
use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime_std::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner}; use codec::{KeyedVec, Joiner};
use support::{one, two, with_env}; use support::{one, two, with_env};
use primitives::{AccountID, InternalFunction}; use primitives::AccountId;
use primitives::relay::InternalFunction;
use runtime::{staking, session}; use runtime::{staking, session};
fn new_test_ext() -> TestExternalities { fn new_test_ext() -> TestExternalities {
@@ -159,8 +192,7 @@ mod tests {
// Block 1: Make proposal. Approve it. Era length changes. // Block 1: Make proposal. Approve it. Era length changes.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::approve(&two, 1); public::approve(&two, 1);
staking::internal::check_new_era(); staking::internal::check_new_era();
@@ -185,8 +217,7 @@ mod tests {
// Block 1: Make proposal. Fail it. // Block 1: Make proposal. Fail it.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
staking::internal::check_new_era(); staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1); assert_eq!(staking::era_length(), 1);
@@ -194,8 +225,7 @@ mod tests {
// Block 2: Make proposal. Approve it. It should change era length. // Block 2: Make proposal. Approve it. It should change era length.
with_env(|e| e.block_number = 2); with_env(|e| e.block_number = 2);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::approve(&two, 2); public::approve(&two, 2);
staking::internal::check_new_era(); staking::internal::check_new_era();
@@ -220,8 +250,7 @@ mod tests {
// Block 1: Make proposal. Will have only 1 vote. No change. // Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
staking::internal::check_new_era(); staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1); assert_eq!(staking::era_length(), 1);
@@ -246,8 +275,7 @@ mod tests {
// Block 1: Make proposal. Will have only 1 vote. No change. // Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::approve(&two, 0); public::approve(&two, 0);
staking::internal::check_new_era(); staking::internal::check_new_era();
@@ -273,8 +301,7 @@ mod tests {
// Block 1: Make proposal. Will have only 1 vote. No change. // Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::approve(&two, 1); public::approve(&two, 1);
public::approve(&two, 1); public::approve(&two, 1);
@@ -301,12 +328,10 @@ mod tests {
// Block 1: Make proposal. Will have only 1 vote. No change. // Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::propose(&two, &Proposal { public::propose(&two, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
staking::internal::check_new_era(); staking::internal::check_new_era();
assert_eq!(staking::era_length(), 1); assert_eq!(staking::era_length(), 1);
@@ -355,8 +380,7 @@ mod tests {
// Block 1: Make proposal. Will have only 1 vote. No change. // Block 1: Make proposal. Will have only 1 vote. No change.
with_env(|e| e.block_number = 1); with_env(|e| e.block_number = 1);
public::propose(&one, &Proposal { public::propose(&one, &Proposal {
function: InternalFunction::StakingSetSessionsPerEra, function: InternalFunction::StakingSetSessionsPerEra(2),
input_data: vec![].join(&2u64),
}); });
public::approve(&four, 1); public::approve(&four, 1);
staking::internal::check_new_era(); staking::internal::check_new_era();
@@ -33,5 +33,5 @@ pub mod parachains;
// TODO: polkadao // TODO: polkadao
#[cfg(feature = "with-std")] #[cfg(feature = "std")]
pub mod genesismap; pub mod genesismap;
@@ -62,7 +62,7 @@ pub fn calculate_duty_roster() -> DutyRoster {
let mut roles_gua = roles_val.clone(); let mut roles_gua = roles_val.clone();
let h = with_env(|e| e.parent_hash.clone()); let h = with_env(|e| e.parent_hash.clone());
let mut seed = vec![].join(&h).join(b"validator_role_pairs").blake2_256(); let mut seed = Vec::<u8>::new().join(&h).join(b"validator_role_pairs").blake2_256();
// shuffle // shuffle
for i in 0..(validator_count - 1) { for i in 0..(validator_count - 1) {
@@ -73,8 +73,8 @@ pub fn calculate_duty_roster() -> DutyRoster {
let remaining = (validator_count - i) as usize; let remaining = (validator_count - i) as usize;
// 4 * 2 32-bit ints per 256-bit seed. // 4 * 2 32-bit ints per 256-bit seed.
let val_index = u32::from_slice(&seed[offset..offset + 4]).expect("using 4 bytes for a 32-byte quantity") as usize % remaining; let val_index = u32::from_slice(&mut &seed[offset..offset + 4]).expect("using 4 bytes for a 32-bit quantity") as usize % remaining;
let gua_index = u32::from_slice(&seed[offset + 4..offset + 8]).expect("using 4 bytes for a 32-byte quantity") as usize % remaining; let gua_index = u32::from_slice(&mut &seed[offset + 4..offset + 8]).expect("using 4 bytes for a 32-bit quantity") as usize % remaining;
if offset == 24 { if offset == 24 {
// into the last 8 bytes - rehash to gather new entropy // into the last 8 bytes - rehash to gather new entropy
@@ -98,7 +98,6 @@ mod tests {
use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime_std::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner}; use codec::{KeyedVec, Joiner};
use support::{one, two, with_env}; use support::{one, two, with_env};
use primitives::AccountID;
use runtime::{consensus, session}; use runtime::{consensus, session};
fn simple_setup() -> TestExternalities { fn simple_setup() -> TestExternalities {
@@ -123,16 +122,16 @@ mod tests {
assert_eq!(duty_roster.guarantor_duty.iter().filter(|&&j| j == Chain::Relay).count(), 2); assert_eq!(duty_roster.guarantor_duty.iter().filter(|&&j| j == Chain::Relay).count(), 2);
}; };
with_env(|e| e.parent_hash = [0u8; 32]); with_env(|e| e.parent_hash = [0u8; 32].into());
let duty_roster_0 = calculate_duty_roster(); let duty_roster_0 = calculate_duty_roster();
check_roster(&duty_roster_0); check_roster(&duty_roster_0);
with_env(|e| e.parent_hash = [1u8; 32]); with_env(|e| e.parent_hash = [1u8; 32].into());
let duty_roster_1 = calculate_duty_roster(); let duty_roster_1 = calculate_duty_roster();
check_roster(&duty_roster_1); check_roster(&duty_roster_1);
assert!(duty_roster_0 != duty_roster_1); assert!(duty_roster_0 != duty_roster_1);
with_env(|e| e.parent_hash = [2u8; 32]); with_env(|e| e.parent_hash = [2u8; 32].into());
let duty_roster_2 = calculate_duty_roster(); let duty_roster_2 = calculate_duty_roster();
check_roster(&duty_roster_2); check_roster(&duty_roster_2);
assert!(duty_roster_0 != duty_roster_2); assert!(duty_roster_0 != duty_roster_2);
@@ -20,7 +20,7 @@
use runtime_std::prelude::*; use runtime_std::prelude::*;
use codec::KeyedVec; use codec::KeyedVec;
use support::{storage, StorageVec}; use support::{storage, StorageVec};
use primitives::{AccountID, SessionKey, BlockNumber}; use primitives::{AccountId, SessionKey, BlockNumber};
use runtime::{system, staking, consensus}; use runtime::{system, staking, consensus};
const SESSION_LENGTH: &[u8] = b"ses:len"; const SESSION_LENGTH: &[u8] = b"ses:len";
@@ -31,12 +31,12 @@ const NEXT_SESSION_LENGTH: &[u8] = b"ses:nln";
struct ValidatorStorageVec {} struct ValidatorStorageVec {}
impl StorageVec for ValidatorStorageVec { impl StorageVec for ValidatorStorageVec {
type Item = AccountID; type Item = AccountId;
const PREFIX: &'static[u8] = b"ses:val:"; const PREFIX: &'static[u8] = b"ses:val:";
} }
/// Get the current set of authorities. These are the session keys. /// Get the current set of authorities. These are the session keys.
pub fn validators() -> Vec<AccountID> { pub fn validators() -> Vec<AccountId> {
ValidatorStorageVec::items() ValidatorStorageVec::items()
} }
@@ -65,7 +65,7 @@ pub mod public {
/// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next /// Sets the session key of `_validator` to `_key`. This doesn't take effect until the next
/// session. /// session.
pub fn set_key(validator: &AccountID, key: &SessionKey) { pub fn set_key(validator: &AccountId, key: &SessionKey) {
// set new value for next session // set new value for next session
storage::put(&validator.to_keyed_vec(NEXT_KEY_FOR), key); storage::put(&validator.to_keyed_vec(NEXT_KEY_FOR), key);
} }
@@ -94,7 +94,7 @@ pub mod internal {
/// ///
/// Called by staking::next_era() only. `next_session` should be called after this in order to /// Called by staking::next_era() only. `next_session` should be called after this in order to
/// update the session keys to the next validator set. /// update the session keys to the next validator set.
pub fn set_validators(new: &[AccountID]) { pub fn set_validators(new: &[AccountId]) {
ValidatorStorageVec::set_items(new); ValidatorStorageVec::set_items(new);
consensus::internal::set_authorities(new); consensus::internal::set_authorities(new);
} }
@@ -140,7 +140,7 @@ mod tests {
use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime_std::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner}; use codec::{KeyedVec, Joiner};
use support::{one, two, with_env}; use support::{one, two, with_env};
use primitives::AccountID; use primitives::AccountId;
use runtime::{consensus, session}; use runtime::{consensus, session};
fn simple_setup() -> TestExternalities { fn simple_setup() -> TestExternalities {
@@ -21,7 +21,7 @@ use runtime_std::cell::RefCell;
use runtime_std::print; use runtime_std::print;
use codec::KeyedVec; use codec::KeyedVec;
use support::{storage, StorageVec}; use support::{storage, StorageVec};
use primitives::{BlockNumber, AccountID}; use primitives::{BlockNumber, AccountId};
use runtime::{system, session, governance}; use runtime::{system, session, governance};
/// The balance of an account. /// The balance of an account.
@@ -32,7 +32,7 @@ pub type Bondage = u64;
struct IntentionStorageVec {} struct IntentionStorageVec {}
impl StorageVec for IntentionStorageVec { impl StorageVec for IntentionStorageVec {
type Item = AccountID; type Item = AccountId;
const PREFIX: &'static[u8] = b"sta:wil:"; const PREFIX: &'static[u8] = b"sta:wil:";
} }
@@ -76,12 +76,12 @@ pub fn last_era_length_change() -> BlockNumber {
} }
/// The balance of a given account. /// The balance of a given account.
pub fn balance(who: &AccountID) -> Balance { pub fn balance(who: &AccountId) -> Balance {
storage::get_or_default(&who.to_keyed_vec(BALANCE_OF)) storage::get_or_default(&who.to_keyed_vec(BALANCE_OF))
} }
/// The liquidity-state of a given account. /// The liquidity-state of a given account.
pub fn bondage(who: &AccountID) -> Bondage { pub fn bondage(who: &AccountId) -> Bondage {
storage::get_or_default(&who.to_keyed_vec(BONDAGE_OF)) storage::get_or_default(&who.to_keyed_vec(BONDAGE_OF))
} }
@@ -95,7 +95,7 @@ pub mod public {
use super::*; use super::*;
/// Transfer some unlocked staking balance to another staker. /// Transfer some unlocked staking balance to another staker.
pub fn transfer(transactor: &AccountID, dest: &AccountID, value: Balance) { pub fn transfer(transactor: &AccountId, dest: &AccountId, value: Balance) {
let from_key = transactor.to_keyed_vec(BALANCE_OF); let from_key = transactor.to_keyed_vec(BALANCE_OF);
let from_balance = storage::get_or_default::<Balance>(&from_key); let from_balance = storage::get_or_default::<Balance>(&from_key);
assert!(from_balance >= value); assert!(from_balance >= value);
@@ -110,7 +110,7 @@ pub mod public {
/// Declare the desire to stake for the transactor. /// Declare the desire to stake for the transactor.
/// ///
/// Effects will be felt at the beginning of the next era. /// Effects will be felt at the beginning of the next era.
pub fn stake(transactor: &AccountID) { pub fn stake(transactor: &AccountId) {
let mut intentions = IntentionStorageVec::items(); let mut intentions = IntentionStorageVec::items();
// can't be in the list twice. // can't be in the list twice.
assert!(intentions.iter().find(|t| *t == transactor).is_none(), "Cannot stake if already staked."); assert!(intentions.iter().find(|t| *t == transactor).is_none(), "Cannot stake if already staked.");
@@ -122,7 +122,7 @@ pub mod public {
/// Retract the desire to stake for the transactor. /// Retract the desire to stake for the transactor.
/// ///
/// Effects will be felt at the beginning of the next era. /// Effects will be felt at the beginning of the next era.
pub fn unstake(transactor: &AccountID) { pub fn unstake(transactor: &AccountId) {
let mut intentions = IntentionStorageVec::items(); let mut intentions = IntentionStorageVec::items();
if let Some(position) = intentions.iter().position(|t| t == transactor) { if let Some(position) = intentions.iter().position(|t| t == transactor) {
intentions.swap_remove(position); intentions.swap_remove(position);
@@ -148,8 +148,8 @@ pub mod privileged {
} }
/// The length of a staking era in sessions. /// The length of a staking era in sessions.
pub fn set_validator_count(new: usize) { pub fn set_validator_count(new: u32) {
storage::put(VALIDATOR_COUNT, &(new as u32)); storage::put(VALIDATOR_COUNT, &new);
} }
/// Force there to be a new era. This also forces a new session immediately after. /// Force there to be a new era. This also forces a new session immediately after.
@@ -216,7 +216,7 @@ mod tests {
use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime_std::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner}; use codec::{KeyedVec, Joiner};
use support::{one, two, with_env}; use support::{one, two, with_env};
use primitives::AccountID; use primitives::AccountId;
use runtime::{staking, session}; use runtime::{staking, session};
#[test] #[test]
@@ -21,7 +21,8 @@ use runtime_std::prelude::*;
use runtime_std::{mem, storage_root, enumerated_trie_root}; use runtime_std::{mem, storage_root, enumerated_trie_root};
use codec::{KeyedVec, Slicable}; use codec::{KeyedVec, Slicable};
use support::{Hashable, storage, with_env}; use support::{Hashable, storage, with_env};
use primitives::{Block, BlockNumber, Header, Hash, UncheckedTransaction, TxOrder}; use primitives::{AccountId, Hash, TxOrder, BlockNumber};
use primitives::relay::{Block, Header, UncheckedTransaction, Function, Log};
use runtime::{staking, session}; use runtime::{staking, session};
const NONCE_OF: &[u8] = b"sys:non:"; const NONCE_OF: &[u8] = b"sys:non:";
@@ -50,8 +51,10 @@ pub mod privileged {
pub mod internal { pub mod internal {
use super::*; use super::*;
struct CheckedTransaction(UncheckedTransaction);
/// Deposits a log and ensures it matches the blocks log data. /// Deposits a log and ensures it matches the blocks log data.
pub fn deposit_log(log: Vec<u8>) { pub fn deposit_log(log: Log) {
with_env(|e| e.digest.logs.push(log)); with_env(|e| e.digest.logs.push(log));
} }
@@ -67,8 +70,7 @@ pub mod internal {
initial_checks(&block); initial_checks(&block);
// execute transactions // execute transactions
block.transactions.iter().for_each(super::execute_transaction); block.transactions.iter().cloned().for_each(super::execute_transaction);
// post-transactional book-keeping. // post-transactional book-keeping.
staking::internal::check_new_era(); staking::internal::check_new_era();
session::internal::check_rotate_session(); session::internal::check_rotate_session();
@@ -82,7 +84,7 @@ pub mod internal {
/// Execute a transaction outside of the block execution function. /// Execute a transaction outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block. /// This doesn't attempt to validate anything regarding the block.
pub fn execute_transaction(utx: &UncheckedTransaction, mut header: Header) -> Header { pub fn execute_transaction(utx: UncheckedTransaction, mut header: Header) -> Header {
// populate environment from header. // populate environment from header.
with_env(|e| { with_env(|e| {
e.block_number = header.number; e.block_number = header.number;
@@ -104,7 +106,7 @@ pub mod internal {
staking::internal::check_new_era(); staking::internal::check_new_era();
session::internal::check_rotate_session(); session::internal::check_rotate_session();
header.state_root = storage_root(); header.state_root = storage_root().into();
with_env(|e| { with_env(|e| {
mem::swap(&mut header.digest, &mut e.digest); mem::swap(&mut header.digest, &mut e.digest);
}); });
@@ -113,13 +115,43 @@ pub mod internal {
header header
} }
/// Dispatch a function.
pub fn dispatch_function(function: &Function, transactor: &AccountId) {
match *function {
Function::StakingStake => {
::runtime::staking::public::stake(transactor);
}
Function::StakingUnstake => {
::runtime::staking::public::unstake(transactor);
}
Function::StakingTransfer(dest, value) => {
::runtime::staking::public::transfer(transactor, &dest, value);
}
Function::SessionSetKey(session) => {
::runtime::session::public::set_key(transactor, &session);
}
Function::TimestampSet(t) => {
::runtime::timestamp::public::set(t);
}
Function::GovernancePropose(ref proposal) => {
::runtime::governance::public::propose(transactor, proposal);
}
Function::GovernanceApprove(era_index) => {
::runtime::governance::public::approve(transactor, era_index);
}
}
}
} }
fn execute_transaction(utx: &UncheckedTransaction) { fn execute_transaction(utx: UncheckedTransaction) {
// Verify the signature is good. use runtime_std::transaction;
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
let ref tx = utx.transaction; // Verify the signature is good.
let tx = match transaction::check(utx) {
Ok(tx) => tx,
Err(_) => panic!("All transactions should be properly signed"),
};
// check nonce // check nonce
let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); let nonce_key = tx.signed.to_keyed_vec(NONCE_OF);
@@ -130,7 +162,7 @@ fn execute_transaction(utx: &UncheckedTransaction) {
storage::put(&nonce_key, &(expected_nonce + 1)); storage::put(&nonce_key, &(expected_nonce + 1));
// decode parameters and dispatch // decode parameters and dispatch
tx.function.dispatch(&tx.signed, &tx.input_data); internal::dispatch_function(&tx.function, &tx.signed);
} }
fn initial_checks(block: &Block) { fn initial_checks(block: &Block) {
@@ -145,7 +177,7 @@ fn initial_checks(block: &Block) {
// check transaction trie root represents the transactions. // check transaction trie root represents the transactions.
let txs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>(); let txs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>();
let txs = txs.iter().map(Vec::as_slice).collect::<Vec<_>>(); let txs = txs.iter().map(Vec::as_slice).collect::<Vec<_>>();
let txs_root = enumerated_trie_root(&txs); let txs_root = enumerated_trie_root(&txs).into();
info_expect_equal_hash(&header.transaction_root, &txs_root); info_expect_equal_hash(&header.transaction_root, &txs_root);
assert!(header.transaction_root == txs_root, "Transaction trie root must be valid."); assert!(header.transaction_root == txs_root, "Transaction trie root must be valid.");
} }
@@ -159,7 +191,7 @@ fn final_checks(block: &Block) {
}); });
// check storage root. // check storage root.
let storage_root = storage_root(); let storage_root = storage_root().into();
info_expect_equal_hash(&header.state_root, &storage_root); info_expect_equal_hash(&header.state_root, &storage_root);
assert!(header.state_root == storage_root, "Storage root must match that calculated."); assert!(header.state_root == storage_root, "Storage root must match that calculated.");
} }
@@ -189,7 +221,7 @@ mod tests {
use runtime_std::{with_externalities, twox_128, TestExternalities}; use runtime_std::{with_externalities, twox_128, TestExternalities};
use codec::{Joiner, KeyedVec, Slicable}; use codec::{Joiner, KeyedVec, Slicable};
use support::{StaticHexInto, HexDisplay, one, two}; use support::{StaticHexInto, HexDisplay, one, two};
use primitives::{UncheckedTransaction, Transaction, Function, Header, Digest}; use primitives::relay::{Header, Digest, UncheckedTransaction, Transaction, Function};
use runtime::staking; use runtime::staking;
#[test] #[test]
@@ -205,16 +237,13 @@ mod tests {
transaction: Transaction { transaction: Transaction {
signed: one.clone(), signed: one.clone(),
nonce: 0, nonce: 0,
function: Function::StakingTransfer, function: Function::StakingTransfer(two, 69),
input_data: vec![].join(&two).join(&69u64),
}, },
signature: "13590ae48241e29780407687b86c331a9f40f3ab7f2cc2441787628bcafab6645dc81863b138a358e2a1ed1ffa940a4584ba94837f022f0cd162791530320904".convert(), signature: "5f9832c5a4a39e2dd4a3a0c5b400e9836beb362cb8f7d845a8291a2ae6fe366612e080e4acd0b5a75c3d0b6ee69614a68fb63698c1e76bf1f2dcd8fa617ddf05".parse().unwrap(),
}; };
println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec()));
with_externalities(&mut t, || { with_externalities(&mut t, || {
internal::execute_transaction(&tx, Header::from_block_number(1)); internal::execute_transaction(tx, Header::from_block_number(1));
assert_eq!(staking::balance(&one), 42); assert_eq!(staking::balance(&one), 42);
assert_eq!(staking::balance(&two), 69); assert_eq!(staking::balance(&two), 69);
}); });
@@ -252,10 +281,10 @@ mod tests {
let mut t = new_test_ext(); let mut t = new_test_ext();
let h = Header { let h = Header {
parent_hash: [69u8; 32], parent_hash: [69u8; 32].into(),
number: 1, number: 1,
state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0"), state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0").into(),
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}; };
@@ -278,10 +307,10 @@ mod tests {
let mut t = new_test_ext(); let mut t = new_test_ext();
let h = Header { let h = Header {
parent_hash: [69u8; 32], parent_hash: [69u8; 32].into(),
number: 1, number: 1,
state_root: [0u8; 32], state_root: [0u8; 32].into(),
transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}; };
@@ -304,10 +333,10 @@ mod tests {
let mut t = new_test_ext(); let mut t = new_test_ext();
let h = Header { let h = Header {
parent_hash: [69u8; 32], parent_hash: [69u8; 32].into(),
number: 1, number: 1,
state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0"), state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0").into(),
transaction_root: [0u8; 32], transaction_root: [0u8; 32].into(),
digest: Digest { logs: vec![], }, digest: Digest { logs: vec![], },
}; };
@@ -17,12 +17,10 @@
//! Timestamp manager: just handles the current timestamp. //! Timestamp manager: just handles the current timestamp.
use support::storage; use support::storage;
use primitives::Timestamp;
const CURRENT_TIMESTAMP: &[u8] = b"tim:val"; const CURRENT_TIMESTAMP: &[u8] = b"tim:val";
/// Representation of a time.
pub type Timestamp = u64;
/// Get the current time. /// Get the current time.
pub fn get() -> Timestamp { pub fn get() -> Timestamp {
storage::get_or_default(CURRENT_TIMESTAMP) storage::get_or_default(CURRENT_TIMESTAMP)
@@ -21,7 +21,8 @@ use runtime_std::mem;
use runtime_std::cell::RefCell; use runtime_std::cell::RefCell;
use runtime_std::rc::Rc; use runtime_std::rc::Rc;
use primitives::{BlockNumber, Digest, Hash}; use primitives::relay::{BlockNumber, Digest};
use primitives::Hash;
#[derive(Default)] #[derive(Default)]
/// The information that can be accessed globally. /// The information that can be accessed globally.
@@ -19,16 +19,18 @@
mod environment; mod environment;
pub mod storage; pub mod storage;
mod hashable; mod hashable;
#[cfg(feature = "with-std")] #[cfg(feature = "std")]
mod statichex; mod statichex;
#[macro_use] #[macro_use]
#[cfg(feature = "with-std")] #[cfg(feature = "std")]
mod testing; mod testing;
pub use self::environment::with_env; pub use self::environment::with_env;
pub use self::storage::StorageVec; pub use self::storage::StorageVec;
pub use self::hashable::Hashable; pub use self::hashable::Hashable;
#[cfg(feature = "with-std")]
#[cfg(feature = "std")]
pub use self::statichex::{StaticHexConversion, StaticHexInto}; pub use self::statichex::{StaticHexConversion, StaticHexInto};
#[cfg(feature = "with-std")]
#[cfg(feature = "std")]
pub use self::testing::{AsBytesRef, HexDisplay, one, two}; pub use self::testing::{AsBytesRef, HexDisplay, one, two};
@@ -24,9 +24,8 @@ use codec::{Slicable, KeyedVec};
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> { pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
Slicable::set_as_slice(&|out, offset| let raw = runtime_std::storage(&twox_128(key)[..]);
runtime_std::read_storage(&twox_128(key)[..], out, offset) >= out.len() Slicable::from_slice(&mut &raw[..])
)
} }
/// Return the value of the item in storage under `key`, or the type's default if there is no /// Return the value of the item in storage under `key`, or the type's default if there is no
@@ -147,9 +146,8 @@ pub mod unhashed {
/// Return the value of the item in storage under `key`, or `None` if there is no explicit entry. /// Return the value of the item in storage under `key`, or `None` if there is no explicit entry.
pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> { pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
Slicable::set_as_slice(&|out, offset| let raw = runtime_std::storage(key);
runtime_std::read_storage(key, out, offset) >= out.len() T::from_slice(&mut &raw[..])
)
} }
/// Return the value of the item in storage under `key`, or the type's default if there is no /// Return the value of the item in storage under `key`, or the type's default if there is no
@@ -340,10 +338,12 @@ mod tests {
#[test] #[test]
fn proposals_can_be_stored() { fn proposals_can_be_stored() {
use primitives::{Proposal, InternalFunction}; use primitives::relay::{Proposal, InternalFunction};
let mut t = TestExternalities { storage: HashMap::new(), }; let mut t = TestExternalities { storage: HashMap::new(), };
with_externalities(&mut t, || { with_externalities(&mut t, || {
let x = Proposal { function: InternalFunction::StakingSetSessionsPerEra, input_data: b"Hello world".to_vec() }; let x = Proposal {
function: InternalFunction::StakingSetSessionsPerEra(25519),
};
put(b":test", &x); put(b":test", &x);
let y: Proposal = get(b":test").unwrap(); let y: Proposal = get(b":test").unwrap();
assert_eq!(x, y); assert_eq!(x, y);
@@ -16,7 +16,7 @@
//! Testing helpers. //! Testing helpers.
use primitives::AccountID; use primitives::AccountId;
use super::statichex::StaticHexInto; use super::statichex::StaticHexInto;
#[macro_export] #[macro_export]
@@ -27,11 +27,11 @@ macro_rules! map {
} }
/// One account (to which we know the secret key). /// One account (to which we know the secret key).
pub fn one() -> AccountID { pub fn one() -> AccountId {
"2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert() "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert()
} }
/// Another account (secret key known). /// Another account (secret key known).
pub fn two() -> AccountID { pub fn two() -> AccountId {
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert() "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert()
} }
@@ -10,9 +10,14 @@ documentation = "https://paritytech.github.io/pwasm-std/pwasm_std/"
description = "Parity WebAssembly standard library internal allocator" description = "Parity WebAssembly standard library internal allocator"
keywords = ["wasm", "parity", "webassembly", "blockchain"] keywords = ["wasm", "parity", "webassembly", "blockchain"]
categories = ["no-std", "embedded"] categories = ["no-std", "embedded"]
build = "build.rs"
[dependencies] [dependencies]
pwasm-libc = { path = "../pwasm-libc", version = "0.1" } pwasm-libc = { path = "../pwasm-libc", version = "0.1" }
[build-dependencies]
rustc_version = "0.2"
[features] [features]
strict = [] strict = []
nightly = []
@@ -0,0 +1,14 @@
//! Set a nightly feature
extern crate rustc_version;
use rustc_version::{version, version_meta, Channel};
fn main() {
// Assert we haven't travelled back in time
assert!(version().unwrap().major >= 1);
// Set cfg flags depending on release channel
if let Channel::Nightly = version_meta().unwrap().channel {
println!("cargo:rustc-cfg=feature=\"nightly\"");
}
}
+24 -18
View File
@@ -2,29 +2,35 @@
#![cfg_attr(feature = "strict", deny(warnings))] #![cfg_attr(feature = "strict", deny(warnings))]
#![no_std] #![no_std]
#![crate_type = "rlib"] #![crate_type = "rlib"]
#![feature(global_allocator)] #![cfg_attr(feature = "nightly", feature(global_allocator))]
#![feature(alloc)] #![cfg_attr(feature = "nightly", feature(alloc))]
#![feature(allocator_api)] #![cfg_attr(feature = "nightly", feature(allocator_api))]
//! Custom allocator crate for wasm //! Custom allocator crate for wasm
extern crate alloc;
extern crate pwasm_libc;
use alloc::heap::{Alloc, Layout, AllocErr};
/// Wasm allocator /// Wasm allocator
pub struct WasmAllocator; pub struct WasmAllocator;
unsafe impl<'a> Alloc for &'a WasmAllocator { #[cfg(feature = "nightly")]
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
Ok(pwasm_libc::malloc(layout.size()))
}
unsafe fn dealloc(&mut self, ptr: *mut u8, _layout: Layout) {
pwasm_libc::free(ptr)
}
}
#[global_allocator] #[global_allocator]
static ALLOCATOR: WasmAllocator = WasmAllocator; static ALLOCATOR: WasmAllocator = WasmAllocator;
#[cfg(feature = "nightly")]
mod __impl {
extern crate alloc;
extern crate pwasm_libc;
use self::alloc::heap::{Alloc, Layout, AllocErr};
use super::WasmAllocator;
unsafe impl<'a> Alloc for &'a WasmAllocator {
unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
Ok(pwasm_libc::malloc(layout.size()))
}
unsafe fn dealloc(&mut self, ptr: *mut u8, _layout: Layout) {
pwasm_libc::free(ptr)
}
}
}
-11
View File
@@ -1,11 +0,0 @@
[package]
name = "runtime-std"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
pwasm-libc = { path = "../pwasm-libc", version = "0.1" }
pwasm-alloc = { path = "../pwasm-alloc", version = "0.1" }
[features]
strict = []
+1 -1
View File
@@ -7,4 +7,4 @@ authors = ["Parity Technologies <admin@parity.io>"]
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
runtime-std = { path = "../std", version = "0.1" } polkadot-runtime-std = { path = "../../runtime-std", version = "0.1", default_features = false }
+5 -3
View File
@@ -7,9 +7,11 @@ extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
#[macro_use] #[macro_use]
extern crate runtime_std; extern crate polkadot_runtime_std as runtime_std;
use runtime_std::{set_storage, storage, print, blake2_256, twox_128, twox_256, ed25519_verify, use runtime_std::{
enumerated_trie_root}; set_storage, storage, print, blake2_256,
twox_128, twox_256, ed25519_verify, enumerated_trie_root
};
fn test_blake2_256(input: &[u8]) -> Vec<u8> { fn test_blake2_256(input: &[u8]) -> Vec<u8> {
blake2_256(&input).to_vec() blake2_256(&input).to_vec()