mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-25 19:57:56 +00:00
integrate new primitives with native-runtime
This commit is contained in:
Generated
+2
@@ -817,6 +817,7 @@ name = "native-runtime"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"polkadot-primitives 0.1.0",
|
||||
"polkadot-runtime-codec 0.1.0",
|
||||
"polkadot-runtime-std 0.1.0",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1100,6 +1101,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"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",
|
||||
|
||||
@@ -115,8 +115,8 @@ impl<B, E> Client<B, E> where
|
||||
parent_hash: Default::default(),
|
||||
number: 0,
|
||||
state_root: Default::default(),
|
||||
parachain_activity: Default::default(),
|
||||
logs: Default::default(),
|
||||
transaction_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
};
|
||||
|
||||
let mut tx = backend.begin_transaction(BlockId::Hash(block::HeaderHash::default()))?;
|
||||
|
||||
@@ -6,9 +6,10 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
||||
[dependencies]
|
||||
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"
|
||||
hex-literal = "0.1.0"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["polkadot-runtime-codec/std", "polkadot-runtime-std/std"]
|
||||
std = ["polkadot-runtime-codec/std", "polkadot-runtime-std/std", "polkadot-primitives/std"]
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use primitives::parachain::Id as ParachainId;
|
||||
use primitives::Address;
|
||||
use primitives::AccountId;
|
||||
use primitives::block::{Number as BlockNumber, HeaderHash, Header, Body};
|
||||
use service::Role as RoleFlags;
|
||||
|
||||
@@ -150,7 +150,7 @@ pub struct Status {
|
||||
/// Signatue of `best_hash` made with validator address. Required for the validator role.
|
||||
pub validator_signature: Option<Signature>,
|
||||
/// Validator address. Required for the validator role.
|
||||
pub validator_id: Option<Address>,
|
||||
pub validator_id: Option<AccountId>,
|
||||
/// Parachain id. Required for the collator role.
|
||||
pub parachain_id: Option<ParachainId>,
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ mod test {
|
||||
let pair = Pair::from_seed(b"12345678901234567890123456789012");
|
||||
let public = pair.public();
|
||||
assert_eq!(public, "2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".into());
|
||||
let message: Vec<u8> = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap();
|
||||
let message: Vec<u8> = FromHex::from_hex("2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee000000000000000002d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000").unwrap();
|
||||
let signature = pair.sign(&message[..]);
|
||||
assert!(signature.verify(&message[..], &public));
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ pub type BlockNumber = u64;
|
||||
pub type TxOrder = u64;
|
||||
|
||||
/// A hash of some data.
|
||||
pub type Hash = [u8; 32];
|
||||
pub type Hash = hash::H256;
|
||||
|
||||
/// Alias to 520-bit hash when used in the context of a signature.
|
||||
pub type Signature = hash::H512;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Transaction type.
|
||||
|
||||
use bytes::{self, Vec};
|
||||
use bytes::Vec;
|
||||
use codec::Slicable;
|
||||
use runtime_function::Function;
|
||||
|
||||
@@ -35,9 +35,30 @@ pub struct Transaction {
|
||||
pub nonce: ::TxOrder,
|
||||
/// The function that should be called.
|
||||
pub function: Function,
|
||||
/// Serialised input data to the function.
|
||||
#[serde(with = "bytes")]
|
||||
pub input_data: Vec<u8>,
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -52,12 +73,7 @@ pub struct UncheckedTransaction {
|
||||
impl Slicable for UncheckedTransaction {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: try_opt!(Slicable::from_slice(value)),
|
||||
nonce: try_opt!(Slicable::from_slice(value)),
|
||||
function: try_opt!(Slicable::from_slice(value)),
|
||||
input_data: try_opt!(Slicable::from_slice(value)),
|
||||
},
|
||||
transaction: try_opt!(Transaction::from_slice(value)),
|
||||
signature: try_opt!(Slicable::from_slice(value)),
|
||||
})
|
||||
}
|
||||
@@ -68,7 +84,6 @@ impl Slicable for UncheckedTransaction {
|
||||
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.transaction.input_data.as_slice_then(|s| v.extend(s));
|
||||
self.signature.as_slice_then(|s| v.extend(s));
|
||||
|
||||
v
|
||||
@@ -92,3 +107,25 @@ impl fmt::Debug for UncheckedTransaction {
|
||||
write!(f, "UncheckedTransaction({:?})", self.transaction)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ::codec::Slicable;
|
||||
use runtime_function::Function;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ fn should_return_header() {
|
||||
parent_hash: 0.into(),
|
||||
number: 0,
|
||||
state_root: 0.into(),
|
||||
parachain_activity: Default::default(),
|
||||
logs: vec![],
|
||||
transaction_root: Default::default(),
|
||||
digest: Default::default(),
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -13,10 +13,11 @@ 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 }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["environmental", "polkadot-state-machine", "triehash", "polkadot-primitives/std"]
|
||||
std = ["environmental", "polkadot-state-machine", "triehash", "polkadot-primitives/std", "polkadot-runtime-codec/std"]
|
||||
nightly = []
|
||||
strict = []
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#![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");
|
||||
|
||||
@@ -39,6 +41,7 @@ pub mod prelude {
|
||||
/// Type definitions and helpers for transactions.
|
||||
pub mod transaction {
|
||||
pub use primitives::transaction::{Transaction, UncheckedTransaction};
|
||||
use primitives::Signature;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::ops;
|
||||
@@ -52,7 +55,7 @@ pub mod transaction {
|
||||
|
||||
impl CheckedTransaction {
|
||||
/// Get a reference to the checked signature.
|
||||
pub fn signature(&self) -> &[u8; 64] {
|
||||
pub fn signature(&self) -> &Signature {
|
||||
&self.0.signature
|
||||
}
|
||||
}
|
||||
@@ -69,15 +72,12 @@ pub mod transaction {
|
||||
///
|
||||
/// On failure, return the transaction back.
|
||||
pub fn check(tx: UncheckedTransaction) -> Result<CheckedTransaction, UncheckedTransaction> {
|
||||
// TODO: requires canonical serialization of transaction.
|
||||
let msg = unimplemented!();
|
||||
if ed25519_verify(&tx.signature, &msg, &tx.transaction.signed) {
|
||||
let msg = ::codec::Slicable::to_vec(&tx.transaction);
|
||||
if ::ed25519_verify(&tx.signature.0, &msg, &tx.transaction.signed) {
|
||||
Ok(CheckedTransaction(tx))
|
||||
} else {
|
||||
Err(tx)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Check a transaction
|
||||
pub struct CheckedTransaction(primitives::UncheckedTransaction);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ extern crate polkadot_state_machine;
|
||||
extern crate polkadot_primitives as primitives;
|
||||
extern crate triehash;
|
||||
|
||||
use std::fmt;
|
||||
use primitives::ed25519;
|
||||
|
||||
pub use std::vec;
|
||||
|
||||
@@ -20,7 +20,7 @@ use primitives::{validator, parachain};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serializer;
|
||||
|
||||
use error::{Error, ErrorKind, Result};
|
||||
use error::{ErrorKind, Result};
|
||||
use parachains::{ParachainCode, ParaChain1};
|
||||
|
||||
/// A dummy validator implementation.
|
||||
@@ -40,10 +40,8 @@ impl Validator {
|
||||
}
|
||||
}
|
||||
|
||||
impl validator::Validator for Validator {
|
||||
type Error = Error;
|
||||
|
||||
fn validate(
|
||||
impl Validator {
|
||||
pub fn validate(
|
||||
&self,
|
||||
code: &[u8],
|
||||
consolidated_ingress: &[(u64, Vec<parachain::Message>)],
|
||||
|
||||
@@ -25,6 +25,7 @@ extern crate polkadot_runtime_std as runtime_std;
|
||||
extern crate rustc_hex;
|
||||
|
||||
extern crate polkadot_runtime_codec as codec;
|
||||
extern crate polkadot_primitives as primitives;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
@@ -32,24 +33,24 @@ extern crate hex_literal;
|
||||
|
||||
#[macro_use]
|
||||
pub mod support;
|
||||
pub mod primitives;
|
||||
pub mod runtime;
|
||||
|
||||
use runtime_std::prelude::*;
|
||||
use codec::Slicable;
|
||||
use primitives::{Block, UncheckedTransaction};
|
||||
use primitives::transaction::UncheckedTransaction;
|
||||
use primitives::block::Block;
|
||||
|
||||
/// Execute a block, with `input` being the canonical serialisation of the block. Returns the
|
||||
/// empty vector.
|
||||
pub fn execute_block(input: &[u8]) -> Vec<u8> {
|
||||
runtime::system::internal::execute_block(Block::from_slice(input).unwrap());
|
||||
pub fn execute_block(mut input: &[u8]) -> Vec<u8> {
|
||||
runtime::system::internal::execute_block(Block::from_slice(&mut input).unwrap());
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// Execute a given, serialised, transaction. Returns the empty vector.
|
||||
pub fn execute_transaction(input: &[u8]) -> Vec<u8> {
|
||||
let utx = UncheckedTransaction::from_slice(input).unwrap();
|
||||
runtime::system::internal::execute_transaction(&utx);
|
||||
pub fn execute_transaction(mut input: &[u8]) -> Vec<u8> {
|
||||
let utx = UncheckedTransaction::from_slice(&mut input).unwrap();
|
||||
runtime::system::internal::execute_transaction(utx);
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = "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::*;
|
||||
|
||||
/// The digest of a block, useful for light-clients.
|
||||
#[derive(Clone, Default)]
|
||||
#[cfg_attr(feature = "std", derive(PartialEq, Debug))]
|
||||
pub struct Digest {
|
||||
/// All logs that have happened in the block.
|
||||
pub logs: Vec<Vec<u8>>,
|
||||
}
|
||||
@@ -1,86 +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 = "std", derive(PartialEq, Debug))]
|
||||
#[repr(u8)]
|
||||
pub enum Function {
|
||||
StakingStake = 0,
|
||||
StakingUnstake = 1,
|
||||
StakingTransfer = 2,
|
||||
SessionSetKey = 3,
|
||||
TimestampSet = 4,
|
||||
GovernancePropose = 5,
|
||||
GovernanceApprove = 6,
|
||||
}
|
||||
|
||||
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];
|
||||
if (value as usize) < functions.len() {
|
||||
Some(functions[value as usize])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,72 +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 = "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 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,105 +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 = "std", derive(PartialEq, Debug))]
|
||||
#[repr(u8)]
|
||||
pub enum InternalFunction {
|
||||
SystemSetCode = 0,
|
||||
StakingSetSessionsPerEra = 1,
|
||||
StakingSetBondingDuration = 2,
|
||||
StakingSetValidatorCount = 3,
|
||||
GovernanceSetApprovalPpmRequired = 4,
|
||||
SessionSetLength = 5,
|
||||
}
|
||||
|
||||
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::StakingSetSessionsPerEra,
|
||||
InternalFunction::StakingSetBondingDuration,
|
||||
InternalFunction::StakingSetValidatorCount,
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired,
|
||||
InternalFunction::SessionSetLength
|
||||
];
|
||||
if (value as usize) < functions.len() {
|
||||
Some(functions[value as usize])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An internal function.
|
||||
#[cfg_attr(feature = "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)
|
||||
}
|
||||
}
|
||||
|
||||
#[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,241 +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/>.
|
||||
|
||||
//! Tests.
|
||||
|
||||
use super::*;
|
||||
use runtime_std::prelude::*;
|
||||
use codec::{Joiner, Slicable};
|
||||
use primitives::Function;
|
||||
|
||||
#[test]
|
||||
fn serialise_transaction_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
};
|
||||
let serialised = tx.to_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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_transaction_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
};
|
||||
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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0
|
||||
];
|
||||
let deserialised = Transaction::from_slice(&data).unwrap();
|
||||
assert_eq!(deserialised, tx);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialise_header_works() {
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
number: 42,
|
||||
state_root: [5u8; 32],
|
||||
transaction_root: [6u8; 32],
|
||||
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], },
|
||||
};
|
||||
let serialised = h.to_vec();
|
||||
assert_eq!(serialised, vec![
|
||||
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,
|
||||
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,
|
||||
26, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_header_works() {
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
number: 42,
|
||||
state_root: [5u8; 32],
|
||||
transaction_root: [6u8; 32],
|
||||
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], },
|
||||
};
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103
|
||||
];
|
||||
let deserialised = Header::from_slice(&data).unwrap();
|
||||
assert_eq!(deserialised, h);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialise_block_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
},
|
||||
signature: [1u8; 64],
|
||||
};
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
},
|
||||
signature: [2u8; 64],
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
number: 42,
|
||||
state_root: [5u8; 32],
|
||||
transaction_root: [6u8; 32],
|
||||
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], },
|
||||
};
|
||||
let b = Block {
|
||||
header: h,
|
||||
transactions: vec![tx1, tx2],
|
||||
};
|
||||
let serialised = b.to_vec();
|
||||
assert_eq!(serialised, vec![
|
||||
// header
|
||||
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,
|
||||
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,
|
||||
26, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
2, 1, 0, 0,
|
||||
// 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
// 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,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_block_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
},
|
||||
signature: [1u8; 64],
|
||||
};
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
},
|
||||
signature: [2u8; 64],
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
number: 42,
|
||||
state_root: [5u8; 32],
|
||||
transaction_root: [6u8; 32],
|
||||
digest: Digest { logs: vec![ b"one log".to_vec(), b"another log".to_vec() ], },
|
||||
};
|
||||
let b = Block {
|
||||
header: h,
|
||||
transactions: vec![tx1, tx2],
|
||||
};
|
||||
let data = [
|
||||
// header
|
||||
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,
|
||||
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,
|
||||
26, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
2, 1, 0, 0,
|
||||
// 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
// 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,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0
|
||||
];
|
||||
let deserialised = Block::from_slice(&data).unwrap();
|
||||
assert_eq!(deserialised, b);
|
||||
}
|
||||
@@ -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 = "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 = "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 = "std")]
|
||||
impl PartialEq for UncheckedTransaction {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "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 {}
|
||||
@@ -28,7 +28,8 @@
|
||||
use runtime_std::prelude::*;
|
||||
use codec::KeyedVec;
|
||||
use support::storage;
|
||||
use primitives::{AccountID, Hash, BlockNumber, Proposal};
|
||||
use primitives::{AccountId, Hash, BlockNumber};
|
||||
use primitives::proposal::Proposal;
|
||||
use runtime::{staking, system, session};
|
||||
|
||||
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.
|
||||
/// 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.
|
||||
pub fn propose(validator: &AccountID, proposal: &Proposal) {
|
||||
pub fn propose(validator: &AccountId, proposal: &Proposal) {
|
||||
if storage::exists(CURRENT_PROPOSAL) {
|
||||
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
|
||||
/// 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() {
|
||||
panic!("approval vote applied on non-current era.")
|
||||
}
|
||||
@@ -94,6 +95,7 @@ pub mod privileged {
|
||||
|
||||
pub mod internal {
|
||||
use super::*;
|
||||
use primitives::proposal::{Proposal, InternalFunction};
|
||||
|
||||
/// Current era is ending; we should finish up any proposals.
|
||||
pub fn end_of_an_era() {
|
||||
@@ -105,36 +107,29 @@ pub mod internal {
|
||||
.take(approvals_required as usize)
|
||||
.count() as u32;
|
||||
if approved == approvals_required {
|
||||
proposal.enact();
|
||||
enact_proposal(proposal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enact_proposal(proposal: Proposal) {
|
||||
let mut params = StreamReader::new(&self.input_data);
|
||||
match self.function {
|
||||
InternalFunction::SystemSetCode => {
|
||||
let code: Vec<u8> = params.read().unwrap();
|
||||
match proposal.function {
|
||||
InternalFunction::SystemSetCode(code) => {
|
||||
system::privileged::set_code(&code);
|
||||
}
|
||||
InternalFunction::StakingSetSessionsPerEra => {
|
||||
let value = params.read().unwrap();
|
||||
InternalFunction::StakingSetSessionsPerEra(value) => {
|
||||
staking::privileged::set_sessions_per_era(value);
|
||||
}
|
||||
InternalFunction::StakingSetBondingDuration => {
|
||||
let value = params.read().unwrap();
|
||||
InternalFunction::StakingSetBondingDuration(value) => {
|
||||
staking::privileged::set_bonding_duration(value);
|
||||
}
|
||||
InternalFunction::StakingSetValidatorCount => {
|
||||
let value = params.read().unwrap();
|
||||
InternalFunction::StakingSetValidatorCount(value) => {
|
||||
staking::privileged::set_validator_count(value);
|
||||
}
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired => {
|
||||
let value = params.read().unwrap();
|
||||
governance::privileged::set_approval_ppm_required(value);
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired(value) => {
|
||||
self::privileged::set_approval_ppm_required(value);
|
||||
}
|
||||
InternalFunction::SessionSetLength => {
|
||||
let value = params.read().unwrap();
|
||||
InternalFunction::SessionSetLength(value) => {
|
||||
session::privileged::set_length(value);
|
||||
}
|
||||
}
|
||||
@@ -147,7 +142,8 @@ mod tests {
|
||||
use runtime_std::{with_externalities, twox_128, TestExternalities};
|
||||
use codec::{KeyedVec, Joiner};
|
||||
use support::{one, two, with_env};
|
||||
use primitives::{AccountID, InternalFunction};
|
||||
use primitives::AccountId;
|
||||
use primitives::proposal::InternalFunction;
|
||||
use runtime::{staking, session};
|
||||
|
||||
fn new_test_ext() -> TestExternalities {
|
||||
@@ -189,8 +185,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Approve it. Era length changes.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::approve(&two, 1);
|
||||
staking::internal::check_new_era();
|
||||
@@ -215,8 +210,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Fail it.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
staking::internal::check_new_era();
|
||||
assert_eq!(staking::era_length(), 1);
|
||||
@@ -224,8 +218,7 @@ mod tests {
|
||||
// Block 2: Make proposal. Approve it. It should change era length.
|
||||
with_env(|e| e.block_number = 2);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::approve(&two, 2);
|
||||
staking::internal::check_new_era();
|
||||
@@ -250,8 +243,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Will have only 1 vote. No change.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
staking::internal::check_new_era();
|
||||
assert_eq!(staking::era_length(), 1);
|
||||
@@ -276,8 +268,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Will have only 1 vote. No change.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::approve(&two, 0);
|
||||
staking::internal::check_new_era();
|
||||
@@ -303,8 +294,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Will have only 1 vote. No change.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::approve(&two, 1);
|
||||
public::approve(&two, 1);
|
||||
@@ -331,12 +321,10 @@ mod tests {
|
||||
// Block 1: Make proposal. Will have only 1 vote. No change.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::propose(&two, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
staking::internal::check_new_era();
|
||||
assert_eq!(staking::era_length(), 1);
|
||||
@@ -385,8 +373,7 @@ mod tests {
|
||||
// Block 1: Make proposal. Will have only 1 vote. No change.
|
||||
with_env(|e| e.block_number = 1);
|
||||
public::propose(&one, &Proposal {
|
||||
function: InternalFunction::StakingSetSessionsPerEra,
|
||||
input_data: vec![].join(&2u64),
|
||||
function: InternalFunction::StakingSetSessionsPerEra(2),
|
||||
});
|
||||
public::approve(&four, 1);
|
||||
staking::internal::check_new_era();
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
use runtime_std::prelude::*;
|
||||
use codec::KeyedVec;
|
||||
use support::{storage, StorageVec};
|
||||
use primitives::{AccountID, SessionKey, BlockNumber};
|
||||
use primitives::{AccountId, SessionKey, BlockNumber};
|
||||
use runtime::{system, staking, consensus};
|
||||
|
||||
const SESSION_LENGTH: &[u8] = b"ses:len";
|
||||
@@ -31,12 +31,12 @@ const NEXT_SESSION_LENGTH: &[u8] = b"ses:nln";
|
||||
|
||||
struct ValidatorStorageVec {}
|
||||
impl StorageVec for ValidatorStorageVec {
|
||||
type Item = AccountID;
|
||||
type Item = AccountId;
|
||||
const PREFIX: &'static[u8] = b"ses:val:";
|
||||
}
|
||||
|
||||
/// Get the current set of authorities. These are the session keys.
|
||||
pub fn validators() -> Vec<AccountID> {
|
||||
pub fn validators() -> Vec<AccountId> {
|
||||
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
|
||||
/// session.
|
||||
pub fn set_key(validator: &AccountID, key: &SessionKey) {
|
||||
pub fn set_key(validator: &AccountId, key: &SessionKey) {
|
||||
// set new value for next session
|
||||
storage::put(&validator.to_keyed_vec(NEXT_KEY_FOR), key);
|
||||
}
|
||||
@@ -89,7 +89,7 @@ pub mod internal {
|
||||
///
|
||||
/// 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.
|
||||
pub fn set_validators(new: &[AccountID]) {
|
||||
pub fn set_validators(new: &[AccountId]) {
|
||||
ValidatorStorageVec::set_items(new);
|
||||
consensus::internal::set_authorities(new);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ mod tests {
|
||||
use runtime_std::{with_externalities, twox_128, TestExternalities};
|
||||
use codec::{KeyedVec, Joiner};
|
||||
use support::{one, two, with_env};
|
||||
use primitives::AccountID;
|
||||
use primitives::AccountId;
|
||||
use runtime::{consensus, session};
|
||||
|
||||
fn simple_setup() -> TestExternalities {
|
||||
|
||||
@@ -20,7 +20,7 @@ use runtime_std::prelude::*;
|
||||
use runtime_std::cell::RefCell;
|
||||
use codec::KeyedVec;
|
||||
use support::{storage, StorageVec};
|
||||
use primitives::{BlockNumber, AccountID};
|
||||
use primitives::{BlockNumber, AccountId};
|
||||
use runtime::{system, session, governance};
|
||||
|
||||
/// The balance of an account.
|
||||
@@ -31,7 +31,7 @@ pub type Bondage = u64;
|
||||
|
||||
struct IntentionStorageVec {}
|
||||
impl StorageVec for IntentionStorageVec {
|
||||
type Item = AccountID;
|
||||
type Item = AccountId;
|
||||
const PREFIX: &'static[u8] = b"sta:wil:";
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ pub fn last_era_length_change() -> BlockNumber {
|
||||
}
|
||||
|
||||
/// 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))
|
||||
}
|
||||
|
||||
/// 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))
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ pub mod public {
|
||||
use super::*;
|
||||
|
||||
/// 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_balance = storage::get_or_default::<Balance>(&from_key);
|
||||
assert!(from_balance >= value);
|
||||
@@ -109,7 +109,7 @@ pub mod public {
|
||||
/// Declare the desire to stake for the transactor.
|
||||
///
|
||||
/// 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();
|
||||
// can't be in the list twice.
|
||||
assert!(intentions.iter().find(|t| *t == transactor).is_none(), "Cannot stake if already staked.");
|
||||
@@ -121,7 +121,7 @@ pub mod public {
|
||||
/// Retract the desire to stake for the transactor.
|
||||
///
|
||||
/// 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();
|
||||
if let Some(position) = intentions.iter().position(|t| t == transactor) {
|
||||
intentions.swap_remove(position);
|
||||
@@ -147,8 +147,8 @@ pub mod privileged {
|
||||
}
|
||||
|
||||
/// The length of a staking era in sessions.
|
||||
pub fn set_validator_count(new: usize) {
|
||||
storage::put(VALIDATOR_COUNT, &(new as u32));
|
||||
pub fn set_validator_count(new: u32) {
|
||||
storage::put(VALIDATOR_COUNT, &new);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ mod tests {
|
||||
use runtime_std::{with_externalities, twox_128, TestExternalities};
|
||||
use codec::{KeyedVec, Joiner};
|
||||
use support::{one, two, with_env};
|
||||
use primitives::AccountID;
|
||||
use primitives::AccountId;
|
||||
use runtime::{staking, session};
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -21,7 +21,10 @@ use runtime_std::prelude::*;
|
||||
use runtime_std::{mem, print, storage_root, enumerated_trie_root};
|
||||
use codec::{KeyedVec, Slicable};
|
||||
use support::{Hashable, storage, with_env};
|
||||
use primitives::{Block, BlockNumber, Hash, UncheckedTransaction, TxOrder};
|
||||
use primitives::{AccountId, Hash, TxOrder};
|
||||
use primitives::block::{Block, Number as BlockNumber};
|
||||
use primitives::transaction::UncheckedTransaction;
|
||||
use primitives::runtime_function::Function;
|
||||
use runtime::{staking, session};
|
||||
|
||||
const BLOCK_HASH_AT: &[u8] = b"sys:old:";
|
||||
@@ -54,7 +57,7 @@ pub mod internal {
|
||||
/// Deposits a log and ensures it matches the blocks log data.
|
||||
pub fn deposit_log(log: &[u8]) {
|
||||
with_env(|e| {
|
||||
assert_eq!(log, &e.digest.logs[e.next_log_index][..]);
|
||||
assert_eq!(log, &e.digest.logs[e.next_log_index].0[..]);
|
||||
e.next_log_index += 1;
|
||||
});
|
||||
}
|
||||
@@ -79,11 +82,10 @@ pub mod internal {
|
||||
// check transaction trie root represents the transactions.
|
||||
let txs = block.transactions.iter().map(Slicable::to_vec).collect::<Vec<_>>();
|
||||
let txs_root = enumerated_trie_root(&txs.iter().map(Vec::as_slice).collect::<Vec<_>>());
|
||||
// println!("TR: {}", ::support::HexDisplay::from(&txs_root));
|
||||
assert!(header.transaction_root == txs_root, "Transaction trie root must be valid.");
|
||||
assert!(header.transaction_root.0 == txs_root, "Transaction trie root must be valid.");
|
||||
|
||||
// execute transactions
|
||||
block.transactions.iter().for_each(execute_transaction);
|
||||
block.transactions.iter().cloned().for_each(execute_transaction);
|
||||
|
||||
staking::internal::check_new_era();
|
||||
session::internal::check_rotate_session();
|
||||
@@ -93,7 +95,7 @@ pub mod internal {
|
||||
|
||||
|
||||
// check storage root.
|
||||
assert!(header.state_root == storage_root(), "Storage root must match that calculated.");
|
||||
assert!(header.state_root.0 == storage_root(), "Storage root must match that calculated.");
|
||||
|
||||
// store the header hash in storage; we can't do it before otherwise there would be a
|
||||
// cyclic dependency.
|
||||
@@ -102,11 +104,14 @@ pub mod internal {
|
||||
}
|
||||
|
||||
/// Execute a given transaction.
|
||||
pub fn execute_transaction(utx: &UncheckedTransaction) {
|
||||
// Verify the signature is good.
|
||||
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
|
||||
pub fn execute_transaction(utx: UncheckedTransaction) {
|
||||
use runtime_std::transaction;
|
||||
|
||||
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
|
||||
let nonce_key = tx.signed.to_keyed_vec(b"sys:non:");
|
||||
@@ -117,38 +122,31 @@ pub mod internal {
|
||||
storage::put(&nonce_key, &(expected_nonce + 1));
|
||||
|
||||
// decode parameters and dispatch
|
||||
dispatch_function(&tx.function, &tx.signed, &tx.input_data);
|
||||
dispatch_function(&tx.function, &tx.signed);
|
||||
}
|
||||
|
||||
fn dispatch_function(function: &Function, transactor: &AccountId, data: &[u8]) {
|
||||
let mut params = ::runtime_codec::StreamReader::new(data);
|
||||
match *self {
|
||||
fn dispatch_function(function: &Function, transactor: &AccountId) {
|
||||
match *function {
|
||||
Function::StakingStake => {
|
||||
staking::public::stake(transactor);
|
||||
::runtime::staking::public::stake(transactor);
|
||||
}
|
||||
Function::StakingUnstake => {
|
||||
staking::public::unstake(transactor);
|
||||
::runtime::staking::public::unstake(transactor);
|
||||
}
|
||||
Function::StakingTransfer => {
|
||||
let dest = params.read().unwrap();
|
||||
let value = params.read().unwrap();
|
||||
staking::public::transfer(transactor, &dest, value);
|
||||
Function::StakingTransfer(dest, value) => {
|
||||
::runtime::staking::public::transfer(transactor, &dest, value);
|
||||
}
|
||||
Function::SessionSetKey => {
|
||||
let session = params.read().unwrap();
|
||||
session::public::set_key(transactor, &session);
|
||||
Function::SessionSetKey(session) => {
|
||||
::runtime::session::public::set_key(transactor, &session);
|
||||
}
|
||||
Function::TimestampSet => {
|
||||
let t = params.read().unwrap();
|
||||
timestamp::public::set(t);
|
||||
Function::TimestampSet(t) => {
|
||||
::runtime::timestamp::public::set(t);
|
||||
}
|
||||
Function::GovernancePropose => {
|
||||
let proposal = params.read().unwrap();
|
||||
governance::public::propose(transactor, &proposal);
|
||||
Function::GovernancePropose(ref proposal) => {
|
||||
::runtime::governance::public::propose(transactor, proposal);
|
||||
}
|
||||
Function::GovernanceApprove => {
|
||||
let era_index = params.read().unwrap();
|
||||
governance::public::approve(transactor, era_index);
|
||||
Function::GovernanceApprove(era_index) => {
|
||||
::runtime::governance::public::approve(transactor, era_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +166,10 @@ mod tests {
|
||||
use runtime_std::{with_externalities, twox_128, TestExternalities};
|
||||
use codec::{Joiner, KeyedVec, Slicable};
|
||||
use support::{StaticHexInto, HexDisplay, one, two};
|
||||
use primitives::{UncheckedTransaction, Transaction, Function, Header, Digest};
|
||||
use primitives::transaction::{UncheckedTransaction, Transaction};
|
||||
use primitives::runtime_function::Function;
|
||||
use primitives::block::{Header, Digest};
|
||||
use primitives::hash::{H256, H512};
|
||||
use runtime::staking;
|
||||
|
||||
#[test]
|
||||
@@ -184,18 +185,15 @@ mod tests {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 0,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: vec![].join(&two).join(&69u64),
|
||||
function: Function::StakingTransfer(two, 69),
|
||||
},
|
||||
signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(),
|
||||
signature: "b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".parse().unwrap(),
|
||||
};
|
||||
// tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000
|
||||
// sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a
|
||||
|
||||
println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec()));
|
||||
// sig: b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
execute_transaction(&tx);
|
||||
execute_transaction(tx);
|
||||
assert_eq!(staking::balance(&one), 42);
|
||||
assert_eq!(staking::balance(&two), 69);
|
||||
});
|
||||
@@ -236,17 +234,16 @@ mod tests {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 0,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: vec![].join(&two).join(&69u64),
|
||||
function: Function::StakingTransfer(two, 69),
|
||||
},
|
||||
signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(),
|
||||
signature: "b543b41e4b7a0270eddf57ed6c435df04bb63f71c79f6ae2530ab26c734bb4e8cd57b1c190c41d5791bcdea66a16c7339b1e883e5d0538ea2d9acea800d60a00".parse().unwrap(),
|
||||
};
|
||||
|
||||
let h = Header {
|
||||
parent_hash: [69u8; 32],
|
||||
parent_hash: H256([69u8; 32]),
|
||||
number: 1,
|
||||
state_root: hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db"),
|
||||
transaction_root: hex!("91fab88ad8c30a6d05ad8e0cf9ab139bf1b8cdddc69abd51cdfa6d2699038af1"),
|
||||
state_root: H256(hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db")),
|
||||
transaction_root: H256(hex!("c4b361b976b3aa90f9f0cdd32f4afc80dd96f200145a687196388a00363c2235")),
|
||||
digest: Digest { logs: vec![], },
|
||||
};
|
||||
|
||||
@@ -274,19 +271,18 @@ mod tests {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 0,
|
||||
function: Function::StakingTransfer,
|
||||
input_data: vec![].join(&two).join(&69u64),
|
||||
function: Function::StakingTransfer(two, 69),
|
||||
},
|
||||
signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".convert(),
|
||||
signature: "679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a".parse().unwrap(),
|
||||
};
|
||||
// tx: 2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee00000000000000000228000000d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a4500000000000000
|
||||
// sig: 679fcf0a846b4224c84ecad7d91a26241c46d00cb53d6480a363274e8965ee34b0b80b4b2e3836d3d8f8f12c0c1aef7350af587d9aee3883561d11726068ac0a
|
||||
|
||||
let h = Header {
|
||||
parent_hash: [69u8; 32],
|
||||
parent_hash: H256([69u8; 32]),
|
||||
number: 1,
|
||||
state_root: [0u8; 32],
|
||||
transaction_root: [0u8; 32], // Unchecked currently.
|
||||
state_root: H256([0u8; 32]),
|
||||
transaction_root: H256([0u8; 32]), // Unchecked currently.
|
||||
digest: Digest { logs: vec![], },
|
||||
};
|
||||
|
||||
|
||||
@@ -17,12 +17,10 @@
|
||||
//! Timestamp manager: just handles the current timestamp.
|
||||
|
||||
use support::storage;
|
||||
use primitives::Timestamp;
|
||||
|
||||
const CURRENT_TIMESTAMP: &[u8] = b"tim:val";
|
||||
|
||||
/// Representation of a time.
|
||||
pub type Timestamp = u64;
|
||||
|
||||
/// Get the current time.
|
||||
pub fn get() -> Timestamp {
|
||||
storage::get_or_default(CURRENT_TIMESTAMP)
|
||||
|
||||
@@ -21,7 +21,7 @@ use runtime_std::mem;
|
||||
use runtime_std::cell::RefCell;
|
||||
use runtime_std::rc::Rc;
|
||||
|
||||
use primitives::{BlockNumber, Digest};
|
||||
use primitives::block::{Number as BlockNumber, Digest};
|
||||
|
||||
#[derive(Default)]
|
||||
/// The information that can be accessed globally.
|
||||
|
||||
@@ -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.
|
||||
pub fn get<T: Slicable + Sized>(key: &[u8]) -> Option<T> {
|
||||
Slicable::set_as_slice(|out, offset|
|
||||
runtime_std::read_storage(&twox_128(key)[..], out, offset) >= out.len()
|
||||
)
|
||||
let raw = runtime_std::storage(&twox_128(key)[..]);
|
||||
Slicable::from_slice(&mut &raw[..])
|
||||
}
|
||||
|
||||
/// Return the value of the item in storage under `key`, or the type's default if there is no
|
||||
@@ -216,10 +215,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn proposals_can_be_stored() {
|
||||
use primitives::{Proposal, InternalFunction};
|
||||
use primitives::proposal::{Proposal, InternalFunction};
|
||||
let mut t = TestExternalities { storage: HashMap::new(), };
|
||||
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);
|
||||
let y: Proposal = get(b":test").unwrap();
|
||||
assert_eq!(x, y);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Testing helpers.
|
||||
|
||||
use primitives::AccountID;
|
||||
use primitives::AccountId;
|
||||
use super::statichex::StaticHexInto;
|
||||
|
||||
#[macro_export]
|
||||
@@ -27,11 +27,11 @@ macro_rules! map {
|
||||
}
|
||||
|
||||
/// One account (to which we know the secret key).
|
||||
pub fn one() -> AccountID {
|
||||
pub fn one() -> AccountId {
|
||||
"2f8c6129d816cf51c374bc7f08c3e63ed156cf78aefb4a6550d97b87997977ee".convert()
|
||||
}
|
||||
/// Another account (secret key known).
|
||||
pub fn two() -> AccountID {
|
||||
pub fn two() -> AccountId {
|
||||
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".convert()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user