Fix most tests, introduce split-block processing tools for authoring.

This commit is contained in:
Gav
2018-02-04 14:35:00 +01:00
parent e0c1d13be6
commit 8628a67e1f
6 changed files with 81 additions and 39 deletions
+6 -6
View File
@@ -50,7 +50,7 @@ mod tests {
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() -> Vec<u8> { fn tx() -> UncheckedTransaction {
let transaction = Transaction { let transaction = Transaction {
signed: one(), signed: one(),
nonce: 0, nonce: 0,
@@ -60,7 +60,7 @@ mod tests {
let signature = secret_for(&transaction.signed).unwrap() let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec()) .sign(&transaction.to_vec())
.inner(); .inner();
UncheckedTransaction { transaction, signature }.to_vec() UncheckedTransaction { transaction, signature }
} }
#[test] #[test]
@@ -70,7 +70,7 @@ mod tests {
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
], }; ], };
let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(tx())); let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_err()); assert!(r.is_err());
} }
@@ -81,7 +81,7 @@ mod tests {
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0] twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
], }; ], };
let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(tx())); let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_err()); assert!(r.is_err());
} }
@@ -94,7 +94,7 @@ mod tests {
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], }; ], };
let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(tx())); let r = NativeExecutor.call(&mut t, COMPACT_CODE, "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_ok()); assert!(r.is_ok());
runtime_std::with_externalities(&mut t, || { runtime_std::with_externalities(&mut t, || {
@@ -112,7 +112,7 @@ mod tests {
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0] twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], }; ], };
let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(tx())); let r = NativeExecutor.call(&mut t, BLOATY_CODE, "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_ok()); assert!(r.is_ok());
runtime_std::with_externalities(&mut t, || { runtime_std::with_externalities(&mut t, || {
+7 -7
View File
@@ -292,9 +292,9 @@ mod tests {
use rustc_hex::FromHex; use rustc_hex::FromHex;
use primitives::{blake2_256, twox_128}; use primitives::{blake2_256, twox_128};
use runtime_std::{self, TestExternalities}; use runtime_std::{self, TestExternalities};
use native_runtime::support::{one, two, StaticHexInto}; use native_runtime::support::{one, two};
use native_runtime::primitives::AccountID; use native_runtime::primitives::{UncheckedTransaction, AccountID};
use native_runtime::codec::KeyedVec; use native_runtime::codec::{Joiner, KeyedVec};
use native_runtime::runtime::staking::balance; use native_runtime::runtime::staking::balance;
#[test] #[test]
@@ -412,7 +412,7 @@ mod tests {
} }
} }
fn tx() -> Vec<u8> { fn tx() -> UncheckedTransaction {
use native_runtime::codec::{Joiner, Slicable}; use native_runtime::codec::{Joiner, Slicable};
use native_runtime::support::{one, two}; use native_runtime::support::{one, two};
use native_runtime::primitives::*; use native_runtime::primitives::*;
@@ -425,7 +425,7 @@ mod tests {
let signature = secret_for(&transaction.signed).unwrap() let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec()) .sign(&transaction.to_vec())
.inner(); .inner();
UncheckedTransaction { transaction, signature }.to_vec() UncheckedTransaction { transaction, signature }
} }
#[test] #[test]
@@ -436,7 +436,7 @@ mod tests {
], }; ], };
let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm"); let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.wasm");
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_err()); assert!(r.is_err());
} }
@@ -450,7 +450,7 @@ mod tests {
], }; ], };
let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm"); let foreign_code = include_bytes!("../../wasm-runtime/target/wasm32-unknown-unknown/release/runtime_polkadot.compact.wasm");
let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(tx())); let r = WasmExecutor.call(&mut t, &foreign_code[..], "execute_transaction", &CallData(vec![].join(&1u64).join(&tx())));
assert!(r.is_ok()); assert!(r.is_ok());
runtime_std::with_externalities(&mut t, || { runtime_std::with_externalities(&mut t, || {
+4 -3
View File
@@ -38,7 +38,7 @@ pub mod runtime;
use runtime_std::prelude::*; use runtime_std::prelude::*;
use codec::Slicable; use codec::Slicable;
use runtime_std::print; use runtime_std::print;
use primitives::{Block, UncheckedTransaction}; use primitives::{Block, Header, BlockNumber, 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.
@@ -49,8 +49,9 @@ pub fn execute_block(input: &[u8]) -> Vec<u8> {
/// 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(input: &[u8]) -> Vec<u8> {
let utx = UncheckedTransaction::from_slice(input).unwrap(); let number = BlockNumber::from_slice(&input[0..8]).unwrap();
runtime::system::internal::execute_transaction(&utx); let utx = UncheckedTransaction::from_slice(&input[8..]).unwrap();
runtime::system::internal::execute_transaction(&utx, Header::from_block_number(number));
Vec::new() Vec::new()
} }
@@ -37,6 +37,18 @@ pub struct Header {
pub digest: Digest, pub digest: Digest,
} }
impl Header {
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 { impl Slicable for Header {
fn from_slice(value: &[u8]) -> Option<Self> { fn from_slice(value: &[u8]) -> Option<Self> {
let mut reader = StreamReader::new(value); let mut reader = StreamReader::new(value);
@@ -151,9 +151,9 @@ mod tests {
twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32], twox_128(&0u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![10; 32],
twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32], twox_128(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32],
// initial session keys (11, 21, ...) // initial session keys (11, 21, ...)
twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32), b"con:aut:len".to_vec() => vec![].join(&2u32),
twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32], 0u32.to_keyed_vec(b"con:aut:") => vec![11; 32],
twox_128(&1u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![21; 32] 1u32.to_keyed_vec(b"con:aut:") => vec![21; 32]
], } ], }
} }
@@ -21,7 +21,7 @@ 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, Hash, UncheckedTransaction, TxOrder}; use primitives::{Block, BlockNumber, Header, Hash, UncheckedTransaction, TxOrder};
use runtime::{staking, session}; use runtime::{staking, session};
const NONCE_OF: &[u8] = b"sys:non:"; const NONCE_OF: &[u8] = b"sys:non:";
@@ -84,7 +84,7 @@ pub mod internal {
// execute transactions // execute transactions
for tx in &block.transactions { for tx in &block.transactions {
execute_transaction(tx); super::execute_transaction(tx);
} }
staking::internal::check_new_era(); staking::internal::check_new_era();
@@ -98,29 +98,34 @@ pub mod internal {
debug_assert_hash(&header.state_root, &storage_root); debug_assert_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.");
// store the header hash in storage; we can't do it before otherwise there would be a // any stuff that we do after taking the storage root.
// cyclic dependency. post_finalise(header);
let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT);
storage::put(&header_hash_key, &header.blake2_256());
} }
/// Execute a given transaction. /// Execute a transaction outside of the block execution function.
pub fn execute_transaction(utx: &UncheckedTransaction) { /// This doesn't attempt to validate anything regarding the block.
// Verify the signature is good. pub fn execute_transaction(utx: &UncheckedTransaction, mut header: Header) {
assert!(utx.ed25519_verify(), "All transactions should be properly signed"); // populate environment from header.
with_env(|e| {
e.block_number = header.number;
mem::swap(&mut e.digest, &mut header.digest);
e.next_log_index = 0;
});
let ref tx = utx.transaction; super::execute_transaction(utx);
}
// check nonce /// Finalise the block - it is up the caller to ensure that all header fields are valid
let nonce_key = tx.signed.to_keyed_vec(NONCE_OF); /// except state-root.
let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0); pub fn finalise_block(mut header: Header) -> Header {
assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce"); staking::internal::check_new_era();
session::internal::check_rotate_session();
// increment nonce in storage header.state_root = storage_root();
storage::put(&nonce_key, &(expected_nonce + 1));
// decode parameters and dispatch post_finalise(&header);
tx.function.dispatch(&tx.signed, &tx.input_data);
header
} }
#[cfg(feature = "with-std")] #[cfg(feature = "with-std")]
@@ -135,12 +140,36 @@ pub mod internal {
fn debug_assert_hash(_given: &Hash, _expected: &Hash) {} fn debug_assert_hash(_given: &Hash, _expected: &Hash) {}
} }
fn execute_transaction(utx: &UncheckedTransaction) {
// Verify the signature is good.
assert!(utx.ed25519_verify(), "All transactions should be properly signed");
let ref tx = utx.transaction;
// check nonce
let nonce_key = tx.signed.to_keyed_vec(NONCE_OF);
let expected_nonce: TxOrder = storage::get_or(&nonce_key, 0);
assert!(tx.nonce == expected_nonce, "All transactions should have the correct nonce");
// increment nonce in storage
storage::put(&nonce_key, &(expected_nonce + 1));
// decode parameters and dispatch
tx.function.dispatch(&tx.signed, &tx.input_data);
}
fn final_checks(_block: &Block) { fn final_checks(_block: &Block) {
with_env(|e| { with_env(|e| {
assert_eq!(e.next_log_index, e.digest.logs.len()); assert_eq!(e.next_log_index, e.digest.logs.len());
}); });
} }
fn post_finalise(header: &Header) {
// store the header hash in storage; we can't do it before otherwise there would be a
// cyclic dependency.
storage::put(&header.number.to_keyed_vec(BLOCK_HASH_AT), &header.blake2_256());
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -174,7 +203,7 @@ mod tests {
println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec())); println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec()));
with_externalities(&mut t, || { with_externalities(&mut t, || {
execute_transaction(&tx); 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);
}); });