Commit 3d30b128 authored by Gav Wood's avatar Gav Wood Committed by asynchronous rob
Browse files

Additional runtime tests for the test-runtime (#69)

* Remove rustc dependency from ed25519 and refactor a little.

* Runtime support provides more extensive test-key functionality.

* Additional APIs for ed25519 stuff.

* Extensive test for test-runtime.

* Fixes for the new test key API.

* Additional convenience for tests

* Take advantage of more convenient API.

* Redo formating.

* Remove old test identities.

* Remove boilerplate, add test.

* Refactor out unneeded code.

* Clean up algo for determining authorities.

* Remove unneeded API.

* Make `to_*` consume

* Only export keyring when testing

* Fix build & warning

* Extract Keyring into separate library.

* Add tests for Keyring and a trait-based API.

* Address grumbles.
parent fe6abac2
......@@ -31,7 +31,7 @@ use client::backend::Backend;
use client::blockchain::BlockId;
use client::Client;
use polkadot_runtime::runtime;
use polkadot_executor::LocalNativeExecutionDispatch as LocalDispatch;
use polkadot_executor::Executor as LocalDispatch;
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
use primitives::{AccountId, SessionKey};
use primitives::parachain::DutyRoster;
......@@ -64,8 +64,8 @@ error_chain! {
///
/// All calls should fail when the exact runtime is unknown.
pub trait PolkadotApi {
/// Get authorities at a given block.
fn authorities(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
/// Get session keys at a given block.
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>>;
/// Get validators at a given block.
fn validators(&self, at: &BlockId) -> Result<Vec<AccountId>>;
......@@ -104,7 +104,7 @@ macro_rules! with_runtime {
impl<B: Backend> PolkadotApi for Client<B, NativeExecutor<LocalDispatch>>
where ::client::error::Error: From<<<B as Backend>::State as state_machine::backend::Backend>::Error>
{
fn authorities(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
fn session_keys(&self, at: &BlockId) -> Result<Vec<SessionKey>> {
with_runtime!(self, at, ::runtime::consensus::authorities)
}
......
......@@ -65,7 +65,7 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
init_logger(log_pattern);
// Create client
let executor = polkadot_executor::executor();
let executor = polkadot_executor::Executor::new();
let mut storage = Default::default();
let god_key = hex!["3d866ec8a9190c8343c2fc593d21d8a6d0c5c4763aaab2349de3a6111d64d124"];
......
......@@ -16,3 +16,6 @@ substrate-executor = { path = "../../substrate/executor" }
substrate-primitives = { path = "../../substrate/primitives" }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime" }
[dev-dependencies]
substrate-keyring = { path = "../../substrate/keyring" }
......@@ -18,7 +18,7 @@
//! executed is equivalent to the natively compiled code.
extern crate polkadot_runtime;
extern crate substrate_executor;
#[macro_use] extern crate substrate_executor;
extern crate substrate_codec as codec;
extern crate substrate_state_machine as state_machine;
extern crate substrate_runtime_io as runtime_io;
......@@ -27,48 +27,26 @@ extern crate polkadot_primitives as polkadot_primitives;
extern crate ed25519;
extern crate triehash;
#[cfg(test)] extern crate substrate_keyring as keyring;
#[cfg(test)] extern crate substrate_runtime_support as runtime_support;
#[cfg(test)] #[macro_use] extern crate hex_literal;
use polkadot_runtime as runtime;
use substrate_executor::error::{Error, ErrorKind};
use substrate_executor::{NativeExecutionDispatch, NativeExecutor};
use state_machine::Externalities;
/// A null struct which implements `NativeExecutionDispatch` feeding in the hard-coded runtime.
pub struct LocalNativeExecutionDispatch;
impl NativeExecutionDispatch for LocalNativeExecutionDispatch {
fn native_equivalent() -> &'static [u8] {
// WARNING!!! This assumes that the runtime was built *before* the main project. Until we
// get a proper build script, this must be strictly adhered to or things will go wrong.
include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm")
}
fn dispatch(ext: &mut Externalities, method: &str, data: &[u8]) -> Result<Vec<u8>, Error> {
::substrate_executor::with_native_environment(ext, move || runtime::api::dispatch(method, data))?
.ok_or_else(|| ErrorKind::MethodNotFound(method.to_owned()).into())
}
}
/// Creates new RustExecutor for contracts.
pub fn executor() -> NativeExecutor<LocalNativeExecutionDispatch> {
NativeExecutor { _dummy: ::std::marker::PhantomData }
}
native_executor_instance!(pub Executor, polkadot_runtime::api::dispatch, include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm"));
#[cfg(test)]
mod tests {
use runtime_io;
use super::*;
use super::Executor;
use substrate_executor::WasmExecutor;
use codec::{KeyedVec, Slicable, Joiner};
use runtime_support::{one, two, Hashable};
use keyring::Keyring;
use runtime_support::Hashable;
use polkadot_runtime::runtime::staking::balance;
use state_machine::{CodeExecutor, TestExternalities};
use primitives::twox_128;
use polkadot_primitives::{Hash, Header, BlockNumber, Block, Digest, Transaction,
UncheckedTransaction, Function, AccountId};
use ed25519::Pair;
UncheckedTransaction, Function};
use ed25519::{Public, Pair};
const BLOATY_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.wasm");
const COMPACT_CODE: &[u8] = include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/polkadot_runtime.compact.wasm");
......@@ -82,11 +60,11 @@ mod tests {
fn tx() -> UncheckedTransaction {
let transaction = Transaction {
signed: one(),
signed: Keyring::One.to_raw_public(),
nonce: 0,
function: Function::StakingTransfer(two(), 69),
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 69),
};
let signature = secret_for(&transaction.signed).unwrap()
let signature = Keyring::from_raw_public(transaction.signed).unwrap()
.sign(&transaction.encode());
UncheckedTransaction { transaction, signature }
......@@ -94,36 +72,36 @@ mod tests {
#[test]
fn panic_execution_with_foreign_code_gives_error() {
let one = one();
let one = Keyring::One.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
], };
let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
assert!(r.is_err());
}
#[test]
fn panic_execution_with_native_equivalent_code_gives_error() {
let one = one();
let one = Keyring::One.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
], };
let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
assert!(r.is_err());
}
#[test]
fn successful_execution_with_native_equivalent_code_gives_ok() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], };
let r = executor().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, COMPACT_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
......@@ -134,14 +112,14 @@ mod tests {
#[test]
fn successful_execution_with_foreign_code_gives_ok() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
], };
let r = executor().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
let r = Executor::new().call(&mut t, BLOATY_CODE, "execute_transaction", &vec![].and(&Header::from_block_number(1u64)).and(&tx()));
assert!(r.is_ok());
runtime_io::with_externalities(&mut t, || {
......@@ -151,8 +129,8 @@ mod tests {
}
fn new_test_ext() -> TestExternalities {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
TestExternalities { storage: map![
......@@ -174,19 +152,11 @@ mod tests {
], }
}
fn secret_for(who: &AccountId) -> Option<Pair> {
match who {
x if *x == one() => Some(Pair::from_seed(b"12345678901234567890123456789012")),
x if *x == two() => Some("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into()),
_ => None,
}
}
fn construct_block(number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
use triehash::ordered_trie_root;
let transactions = txs.into_iter().map(|transaction| {
let signature = secret_for(&transaction.signed).unwrap()
let signature = Pair::from(Keyring::from_public(Public::from_raw(transaction.signed)).unwrap())
.sign(&transaction.encode());
UncheckedTransaction { transaction, signature }
......@@ -212,9 +182,9 @@ mod tests {
[69u8; 32].into(),
hex!("2481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29db").into(),
vec![Transaction {
signed: one(),
signed: Keyring::One.to_raw_public(),
nonce: 0,
function: Function::StakingTransfer(two(), 69),
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 69),
}]
)
}
......@@ -226,14 +196,14 @@ mod tests {
hex!("1feb4d3a2e587079e6ce1685fa79994efd995e33cb289d39cded67aac1bb46a9").into(),
vec![
Transaction {
signed: two(),
signed: Keyring::Two.to_raw_public(),
nonce: 0,
function: Function::StakingTransfer(one(), 5),
function: Function::StakingTransfer(Keyring::One.to_raw_public(), 5),
},
Transaction {
signed: one(),
signed: Keyring::One.to_raw_public(),
nonce: 1,
function: Function::StakingTransfer(two(), 15),
function: Function::StakingTransfer(Keyring::Two.to_raw_public(), 15),
}
]
)
......@@ -243,18 +213,18 @@ mod tests {
fn full_native_block_import_works() {
let mut t = new_test_ext();
executor().call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(balance(&one()), 42);
assert_eq!(balance(&two()), 69);
assert_eq!(balance(&Keyring::One.to_raw_public()), 42);
assert_eq!(balance(&Keyring::Two.to_raw_public()), 69);
});
executor().call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
Executor::new().call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(balance(&one()), 32);
assert_eq!(balance(&two()), 79);
assert_eq!(balance(&Keyring::One.to_raw_public()), 32);
assert_eq!(balance(&Keyring::Two.to_raw_public()), 79);
});
}
......@@ -265,21 +235,21 @@ mod tests {
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block1().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(balance(&one()), 42);
assert_eq!(balance(&two()), 69);
assert_eq!(balance(&Keyring::One.to_raw_public()), 42);
assert_eq!(balance(&Keyring::Two.to_raw_public()), 69);
});
WasmExecutor.call(&mut t, COMPACT_CODE, "execute_block", &block2().0).unwrap();
runtime_io::with_externalities(&mut t, || {
assert_eq!(balance(&one()), 32);
assert_eq!(balance(&two()), 79);
assert_eq!(balance(&Keyring::One.to_raw_public()), 32);
assert_eq!(balance(&Keyring::Two.to_raw_public()), 79);
});
}
#[test]
fn panic_execution_gives_error() {
let one = one();
let one = Keyring::One.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![68u8, 0, 0, 0, 0, 0, 0, 0]
], };
......@@ -291,8 +261,8 @@ mod tests {
#[test]
fn successful_execution_gives_ok() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
......
......@@ -14,6 +14,9 @@ substrate-runtime-support = { path = "../../substrate/runtime-support" }
substrate-primitives = { path = "../../substrate/primitives" }
polkadot-primitives = { path = "../primitives" }
[dev-dependencies]
substrate-keyring = { path = "../../substrate/keyring" }
[features]
default = ["std"]
std = [
......
......@@ -21,6 +21,7 @@
extern crate substrate_runtime_std as rstd;
#[macro_use] extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_support as runtime_support;
#[cfg(all(feature = "std", test))] extern crate substrate_keyring as keyring;
#[cfg(feature = "std")] extern crate rustc_hex;
......
......@@ -147,14 +147,14 @@ mod tests {
use super::*;
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use runtime_support::{one, two};
use keyring::Keyring;
use environment::with_env;
use polkadot_primitives::{AccountId, Proposal};
use runtime::{staking, session};
fn new_test_ext() -> TestExternalities {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
TestExternalities { storage: map![
......@@ -176,8 +176,8 @@ mod tests {
#[test]
fn majority_voting_should_work() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -199,8 +199,8 @@ mod tests {
#[test]
fn majority_voting_should_work_after_unsuccessful_previous() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -228,8 +228,8 @@ mod tests {
#[test]
fn minority_voting_should_not_succeed() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -251,8 +251,8 @@ mod tests {
#[test]
#[should_panic]
fn old_voting_should_be_illegal() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -275,8 +275,8 @@ mod tests {
#[test]
#[should_panic]
fn double_voting_should_be_illegal() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -300,8 +300,8 @@ mod tests {
#[test]
#[should_panic]
fn over_proposing_should_be_illegal() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -324,8 +324,8 @@ mod tests {
#[test]
#[should_panic]
fn approving_without_proposal_should_be_illegal() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let mut t = new_test_ext();
......@@ -347,8 +347,8 @@ mod tests {
#[test]
#[should_panic]
fn non_validator_approving_should_be_illegal() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let four = [4u8; 32];
let mut t = new_test_ext();
......
......@@ -79,7 +79,7 @@ mod tests {
use super::*;
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use runtime_support::{one, two};
use keyring::Keyring;
use runtime::{consensus, session};
fn simple_setup() -> TestExternalities {
......
......@@ -139,7 +139,7 @@ mod tests {
use super::internal::*;
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use runtime_support::{one, two};
use keyring::Keyring;
use environment::with_env;
use polkadot_primitives::AccountId;
use runtime::{consensus, session};
......
......@@ -215,15 +215,15 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{KeyedVec, Joiner};
use runtime_support::{one, two};
use keyring::Keyring;
use environment::with_env;
use polkadot_primitives::AccountId;
use runtime::{staking, session};
#[test]
fn staking_should_work() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
let four = [4u8; 32];
......@@ -360,8 +360,8 @@ mod tests {
#[test]
fn staking_balance_works() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&42u64)
......@@ -375,8 +375,8 @@ mod tests {
#[test]
fn staking_balance_transfer_works() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
......@@ -392,8 +392,8 @@ mod tests {
#[test]
#[should_panic]
fn staking_balance_transfer_when_bonded_doesnt_work() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(BALANCE_OF)).to_vec() => vec![].and(&111u64)
......
......@@ -236,7 +236,7 @@ mod tests {
use runtime_io::{with_externalities, twox_128, TestExternalities};
use codec::{Joiner, KeyedVec, Slicable};
use runtime_support::{one, two};
use keyring::Keyring;
use environment::with_env;
use primitives::hexdisplay::HexDisplay;
use polkadot_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function};
......@@ -244,8 +244,8 @@ mod tests {
#[test]
fn staking_balance_transfer_dispatch_works() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = TestExternalities { storage: map![
twox_128(&one.to_keyed_vec(b"sta:bal:")).to_vec() => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
......@@ -268,8 +268,8 @@ mod tests {
}
fn new_test_ext() -> TestExternalities {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let three = [3u8; 32];
TestExternalities { storage: map![
......@@ -293,8 +293,8 @@ mod tests {
#[test]
fn block_import_works() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
......@@ -319,8 +319,8 @@ mod tests {
#[test]
#[should_panic]
fn block_import_of_bad_state_root_fails() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
......@@ -345,8 +345,8 @@ mod tests {
#[test]
#[should_panic]
fn block_import_of_bad_transaction_root_fails() {
let one = one();
let two = two();
let one = Keyring::One.to_raw_public();
let two = Keyring::Two.to_raw_public();
let mut t = new_test_ext();
......
......@@ -92,8 +92,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "ed25519"
version = "0.1.0"
dependencies = [
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-primitives 0.1.0",
"untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -643,6 +643,7 @@ dependencies = [
name = "substrate-runtime-support"
version = "0.1.0"
dependencies = [
"ed25519 0.1.0",
"environmental 0.1.0",
"hex-literal 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"substrate-codec 0.1.0",
......
Supports Markdown
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