Skip to content
Snippets Groups Projects
Commit 8628a67e authored by Gav's avatar Gav
Browse files

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

parent e0c1d13b
No related merge requests found
......@@ -50,7 +50,7 @@ mod tests {
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");
fn tx() -> Vec<u8> {
fn tx() -> UncheckedTransaction {
let transaction = Transaction {
signed: one(),
nonce: 0,
......@@ -60,7 +60,7 @@ mod tests {
let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec())
.inner();
UncheckedTransaction { transaction, signature }.to_vec()
UncheckedTransaction { transaction, signature }
}
#[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]
], };
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());
}
......@@ -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]
], };
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());
}
......@@ -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]
], };
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());
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]
], };
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());
runtime_std::with_externalities(&mut t, || {
......
......@@ -292,9 +292,9 @@ mod tests {
use rustc_hex::FromHex;
use primitives::{blake2_256, twox_128};
use runtime_std::{self, TestExternalities};
use native_runtime::support::{one, two, StaticHexInto};
use native_runtime::primitives::AccountID;
use native_runtime::codec::KeyedVec;
use native_runtime::support::{one, two};
use native_runtime::primitives::{UncheckedTransaction, AccountID};
use native_runtime::codec::{Joiner, KeyedVec};
use native_runtime::runtime::staking::balance;
#[test]
......@@ -412,7 +412,7 @@ mod tests {
}
}
fn tx() -> Vec<u8> {
fn tx() -> UncheckedTransaction {
use native_runtime::codec::{Joiner, Slicable};
use native_runtime::support::{one, two};
use native_runtime::primitives::*;
......@@ -425,7 +425,7 @@ mod tests {
let signature = secret_for(&transaction.signed).unwrap()
.sign(&transaction.to_vec())
.inner();
UncheckedTransaction { transaction, signature }.to_vec()
UncheckedTransaction { transaction, signature }
}
#[test]
......@@ -436,7 +436,7 @@ mod tests {
], };
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());
}
......@@ -450,7 +450,7 @@ mod tests {
], };
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());
runtime_std::with_externalities(&mut t, || {
......
......@@ -38,7 +38,7 @@ pub mod runtime;
use runtime_std::prelude::*;
use codec::Slicable;
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
/// empty vector.
......@@ -49,8 +49,9 @@ pub fn execute_block(input: &[u8]) -> Vec<u8> {
/// 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);
let number = BlockNumber::from_slice(&input[0..8]).unwrap();
let utx = UncheckedTransaction::from_slice(&input[8..]).unwrap();
runtime::system::internal::execute_transaction(&utx, Header::from_block_number(number));
Vec::new()
}
......
......@@ -37,6 +37,18 @@ pub struct Header {
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 {
fn from_slice(value: &[u8]) -> Option<Self> {
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(&1u32.to_keyed_vec(ValidatorStorageVec::PREFIX)).to_vec() => vec![20; 32],
// initial session keys (11, 21, ...)
twox_128(b"con:aut:len").to_vec() => vec![].join(&2u32),
twox_128(&0u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![11; 32],
twox_128(&1u32.to_keyed_vec(b"con:aut:")).to_vec() => vec![21; 32]
b"con:aut:len".to_vec() => vec![].join(&2u32),
0u32.to_keyed_vec(b"con:aut:") => vec![11; 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 codec::{KeyedVec, Slicable};
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};
const NONCE_OF: &[u8] = b"sys:non:";
......@@ -84,7 +84,7 @@ pub mod internal {
// execute transactions
for tx in &block.transactions {
execute_transaction(tx);
super::execute_transaction(tx);
}
staking::internal::check_new_era();
......@@ -98,29 +98,34 @@ pub mod internal {
debug_assert_hash(&header.state_root, &storage_root);
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
// cyclic dependency.
let header_hash_key = header.number.to_keyed_vec(BLOCK_HASH_AT);
storage::put(&header_hash_key, &header.blake2_256());
// any stuff that we do after taking the storage root.
post_finalise(header);
}
/// 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");
/// Execute a transaction outside of the block execution function.
/// This doesn't attempt to validate anything regarding the block.
pub fn execute_transaction(utx: &UncheckedTransaction, mut header: Header) {
// 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);
}
/// Finalise the block - it is up the caller to ensure that all header fields are valid
/// except state-root.
pub fn finalise_block(mut header: Header) -> Header {
staking::internal::check_new_era();
session::internal::check_rotate_session();
// 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");
header.state_root = storage_root();
// increment nonce in storage
storage::put(&nonce_key, &(expected_nonce + 1));
post_finalise(&header);
// decode parameters and dispatch
tx.function.dispatch(&tx.signed, &tx.input_data);
header
}
#[cfg(feature = "with-std")]
......@@ -135,12 +140,36 @@ pub mod internal {
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) {
with_env(|e| {
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)]
mod tests {
use super::*;
......@@ -174,7 +203,7 @@ mod tests {
println!("tx is {}", HexDisplay::from(&tx.transaction.to_vec()));
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(&two), 69);
});
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment