Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Substrate test client crate & chain subscription test (#139)
Browse files Browse the repository at this point in the history
* Test client used in RPC tests.

* Use test-client for network tests.

* Expose BlockOrigin and clean up the API.
  • Loading branch information
tomusdrw authored and rphmeier committed May 1, 2018
1 parent 57eb390 commit 4861923
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 222 deletions.
33 changes: 23 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion substrate/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ substrate-state-machine = { path = "../state-machine" }
substrate-keyring = { path = "../../substrate/keyring" }

[dev-dependencies]
substrate-test-runtime = { path = "../test-runtime" }
substrate-test-client = { path = "../test-client" }
1 change: 0 additions & 1 deletion substrate/client/src/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use primitives::block::{self, Id as BlockId};
use primitives;
use error::Result;


/// Blockchain database backend. Does not perform any validation.
pub trait Backend: Send + Sync {
/// Get block header. Returns `None` if block is not found.
Expand Down
101 changes: 10 additions & 91 deletions substrate/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,62 +447,15 @@ mod tests {
use super::*;
use codec::Slicable;
use keyring::Keyring;
use {primitives, genesis};
use primitives::block::Extrinsic as PrimitiveExtrinsic;
use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use test_runtime::{UncheckedTransaction, Transaction};
use test_runtime;

native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));

fn genesis_config() -> GenesisConfig {
GenesisConfig::new_simple(vec![
Keyring::Alice.to_raw_public(),
Keyring::Bob.to_raw_public(),
Keyring::Charlie.to_raw_public()
], 1000)
}

fn prepare_genesis() -> (primitives::block::Header, Vec<(Vec<u8>, Vec<u8>)>) {
let mut storage = genesis_config().genesis_map();
let block = genesis::construct_genesis_block(&storage);
storage.extend(additional_storage_with_genesis(&block));
(primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect())
}

// since we are in the client module we can create falsely justified
// headers.
// TODO: remove this in favor of custom verification pipelines for the
// client
fn justify(header: &block::Header) -> bft::UncheckedJustification {
let hash = header.blake2_256().into();
let authorities = vec![
Keyring::Alice.into(),
Keyring::Bob.into(),
Keyring::Charlie.into(),
];

bft::UncheckedJustification {
digest: hash,
signatures: authorities.iter().map(|key| {
let msg = bft::sign_message(
bft::generic::Vote::Commit(1, hash).into(),
key,
header.parent_hash
);

match msg {
bft::generic::LocalizedMessage::Vote(vote) => vote.signature,
_ => panic!("signing vote leads to signed vote"),
}
}).collect(),
round_number: 1,
}
}
use test_client::{self, TestClient};
use test_client::client::BlockOrigin;
use test_client::runtime as test_runtime;
use test_client::runtime::{UncheckedTransaction, Transaction};

#[test]
fn client_initialises_from_genesis_ok() {
let client = new_in_mem(Executor::new(), prepare_genesis).unwrap();
let client = test_client::new();
let genesis_hash = client.block_hash(0).unwrap().unwrap();

assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), genesis_hash);
Expand All @@ -512,15 +465,7 @@ mod tests {

#[test]
fn authorities_call_works() {
let genesis_config = genesis_config();

let prepare_genesis = || {
let mut storage = genesis_config.genesis_map();
let block = genesis::construct_genesis_block(&storage);
storage.extend(additional_storage_with_genesis(&block));
(primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect())
};
let client = new_in_mem(Executor::new(), prepare_genesis).unwrap();
let client = test_client::new();

assert_eq!(client.info().unwrap().chain.best_number, 0);
assert_eq!(client.authorities_at(&BlockId::Number(0)).unwrap(), vec![
Expand All @@ -532,22 +477,11 @@ mod tests {

#[test]
fn block_builder_works_with_no_transactions() {
let genesis_config = genesis_config();

let prepare_genesis = || {
let mut storage = genesis_config.genesis_map();
let block = genesis::construct_genesis_block(&storage);
storage.extend(additional_storage_with_genesis(&block));
(primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect())
};
let client = new_in_mem(Executor::new(), prepare_genesis).unwrap();
let client = test_client::new();

let builder = client.new_block().unwrap();
let block = builder.bake().unwrap();

let justification = justify(&block.header);
let justified = client.check_justification(block.header, justification).unwrap();
client.import_block(BlockOrigin::Own, justified, Some(block.transactions)).unwrap();
client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap();

assert_eq!(client.info().unwrap().chain.best_number, 1);
assert_eq!(client.using_environment(|| test_runtime::system::latest_block_hash()).unwrap(), client.block_hash(1).unwrap().unwrap());
Expand All @@ -565,19 +499,7 @@ mod tests {

#[test]
fn block_builder_works_with_transactions() {
let genesis_config = GenesisConfig::new_simple(vec![
Keyring::Alice.to_raw_public(),
Keyring::Bob.to_raw_public(),
Keyring::Charlie.to_raw_public()
], 1000);

let prepare_genesis = || {
let mut storage = genesis_config.genesis_map();
let block = genesis::construct_genesis_block(&storage);
storage.extend(additional_storage_with_genesis(&block));
(primitives::block::Header::decode(&mut block.header.encode().as_ref()).expect("to_vec() always gives a valid serialisation; qed"), storage.into_iter().collect())
};
let client = new_in_mem(Executor::new(), prepare_genesis).unwrap();
let client = test_client::new();

let mut builder = client.new_block().unwrap();

Expand All @@ -587,11 +509,8 @@ mod tests {
amount: 42,
nonce: 0
}.signed()).unwrap();
let block = builder.bake().unwrap();

let justification = justify(&block.header);
let justified = client.check_justification(block.header, justification).unwrap();
client.import_block(BlockOrigin::Own, justified, Some(block.transactions)).unwrap();
client.justify_and_import(BlockOrigin::Own, builder.bake().unwrap()).unwrap();

assert_eq!(client.info().unwrap().chain.best_number, 1);
assert!(client.state_at(&BlockId::Number(1)).unwrap() != client.state_at(&BlockId::Number(0)).unwrap());
Expand Down
7 changes: 4 additions & 3 deletions substrate/client/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,16 @@ mod tests {
use codec::{Slicable, Joiner};
use runtime_support::Hashable;
use keyring::Keyring;
use test_runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use executor::WasmExecutor;
use state_machine::{execute, OverlayedChanges};
use state_machine::backend::InMemory;
use test_runtime::{self, Hash, Block, BlockNumber, Header, Digest, Transaction,
use test_client;
use test_client::runtime::genesismap::{GenesisConfig, additional_storage_with_genesis};
use test_client::runtime::{Hash, Block, BlockNumber, Header, Digest, Transaction,
UncheckedTransaction};
use ed25519::{Public, Pair};

native_executor_instance!(Executor, test_runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));
native_executor_instance!(Executor, test_client::runtime::api::dispatch, include_bytes!("../../test-runtime/wasm/target/wasm32-unknown-unknown/release/substrate_test_runtime.compact.wasm"));

fn construct_block(backend: &InMemory, number: BlockNumber, parent_hash: Hash, state_root: Hash, txs: Vec<Transaction>) -> (Vec<u8>, Hash) {
use triehash::ordered_trie_root;
Expand Down
27 changes: 16 additions & 11 deletions substrate/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,23 @@
#![warn(missing_docs)]

extern crate substrate_bft as bft;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_codec as codec;
extern crate substrate_primitives as primitives;
extern crate substrate_runtime_io as runtime_io;
extern crate substrate_runtime_support as runtime_support;
extern crate substrate_state_machine as state_machine;
extern crate substrate_codec as codec;
#[cfg(test)] #[macro_use] extern crate substrate_executor as executor;
extern crate ed25519;
#[cfg(test)] extern crate substrate_test_runtime as test_runtime;
#[cfg(test)] extern crate substrate_keyring as keyring;
#[cfg(test)] extern crate substrate_test_client as test_client;

extern crate triehash;
extern crate parking_lot;
extern crate ed25519;
extern crate futures;
#[cfg(test)] #[macro_use] extern crate hex_literal;
extern crate parking_lot;
extern crate triehash;

#[macro_use] extern crate error_chain;
#[macro_use] extern crate log;
#[cfg(test)] #[macro_use] extern crate substrate_executor as executor;
#[cfg(test)] #[macro_use] extern crate hex_literal;

pub mod error;
pub mod blockchain;
Expand All @@ -44,6 +45,10 @@ pub mod genesis;
pub mod block_builder;
mod client;

pub use client::{Client, ClientInfo, CallResult, ImportResult, ChainHead,
BlockStatus, BlockOrigin, new_in_mem, BlockchainEventStream, BlockchainEvents};
pub use client::{
new_in_mem,
BlockStatus, BlockOrigin, BlockchainEventStream, BlockchainEvents,
Client, ClientInfo, CallResult, ChainHead,
ImportResult,
};
pub use blockchain::Info as ChainInfo;
8 changes: 3 additions & 5 deletions substrate/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ substrate-runtime-support = { path = "../../substrate/runtime-support" }
substrate-bft = { path = "../../substrate/bft" }

[dev-dependencies]
substrate-test-runtime = { path = "../test-runtime" }
substrate-executor = { path = "../../substrate/executor" }
substrate-keyring = { path = "../../substrate/keyring" }
substrate-codec = { path = "../../substrate/codec" }
substrate-bft = { path = "../bft" }
env_logger = "0.4"
substrate-codec = { path = "../../substrate/codec" }
substrate-keyring = { path = "../../substrate/keyring" }
substrate-test-client = { path = "../../substrate/test-client" }
6 changes: 2 additions & 4 deletions substrate/network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ extern crate ed25519;
#[macro_use] extern crate error_chain;

#[cfg(test)] extern crate env_logger;
#[cfg(test)] extern crate substrate_test_runtime as test_runtime;
#[cfg(test)] extern crate substrate_keyring as keyring;
#[cfg(test)] #[macro_use] extern crate substrate_executor as executor;
#[cfg(test)] extern crate substrate_codec as codec;
#[cfg(test)] extern crate substrate_bft as bft;
#[cfg(test)] extern crate substrate_keyring as keyring;
#[cfg(test)] extern crate substrate_test_client as test_client;

mod service;
mod sync;
Expand Down
Loading

0 comments on commit 4861923

Please sign in to comment.