Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 60 additions & 89 deletions core/rpc/src/author/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use std::sync::Arc;
use assert_matches::assert_matches;
use codec::Encode;
use primitives::{
H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, ed25519,
H256, blake2_256, hexdisplay::HexDisplay, testing::{ED25519, SR25519, KeyStore}, traits::BareCryptoStorePtr, ed25519,
crypto::Pair,
};
use rpc::futures::Stream as _;
use test_client::{
self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys}, DefaultTestClientBuilderExt,
TestClientBuilderExt,
self, AccountKeyring, runtime::{Extrinsic, Transfer, SessionKeys, RuntimeApi, Block}, DefaultTestClientBuilderExt,
TestClientBuilderExt, Backend, Client, Executor
};
use transaction_pool::{
txpool::Pool,
Expand All @@ -44,17 +44,41 @@ fn uxt(sender: AccountKeyring, nonce: u64) -> Extrinsic {
tx.into_signed_tx()
}

struct TestSetup {
pub runtime: runtime::Runtime,
pub client: Arc<Client<Backend>>,
pub keystore: BareCryptoStorePtr,
pub pool: Arc<Pool<FullChainApi<Client<Backend>, Block>>>,
}

impl Default for TestSetup {
fn default() -> Self {
let keystore = KeyStore::new();
let client = Arc::new(test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build());
let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone())));
TestSetup {
runtime: runtime::Runtime::new().expect("Failed to create runtime in test setup"),
client,
keystore,
pool,
}
}
}

impl TestSetup {
fn author(&self) -> Author<Backend, Executor, FullChainApi<Client<Backend>, Block>, RuntimeApi> {
Author {
client: self.client.clone(),
pool: self.pool.clone(),
subscriptions: Subscriptions::new(Arc::new(self.runtime.executor())),
keystore: self.keystore.clone(),
}
}
}

#[test]
fn submit_transaction_should_not_cause_error() {
let runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let keystore = KeyStore::new();
let p = Author {
client: client.clone(),
pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let p = TestSetup::default().author();
let xt = uxt(AccountKeyring::Alice, 1).encode();
let h: H256 = blake2_256(&xt).into();

Expand All @@ -69,15 +93,7 @@ fn submit_transaction_should_not_cause_error() {

#[test]
fn submit_rich_transaction_should_not_cause_error() {
let runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let keystore = KeyStore::new();
let p = Author {
client: client.clone(),
pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone()))),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let p = TestSetup::default().author();
let xt = uxt(AccountKeyring::Alice, 0).encode();
let h: H256 = blake2_256(&xt).into();

Expand All @@ -93,23 +109,16 @@ fn submit_rich_transaction_should_not_cause_error() {
#[test]
fn should_watch_extrinsic() {
//given
let mut runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone())));
let keystore = KeyStore::new();
let p = Author {
client,
pool: pool.clone(),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let mut setup = TestSetup::default();
let p = setup.author();

let (subscriber, id_rx, data) = jsonrpc_pubsub::typed::Subscriber::new_test("test");

// when
p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 0).encode().into());

// then
assert_eq!(runtime.block_on(id_rx), Ok(Ok(1.into())));
assert_eq!(setup.runtime.block_on(id_rx), Ok(Ok(1.into())));
// check notifications
let replacement = {
let tx = Transfer {
Expand All @@ -121,53 +130,38 @@ fn should_watch_extrinsic() {
tx.into_signed_tx()
};
AuthorApi::submit_extrinsic(&p, replacement.encode().into()).wait().unwrap();
let (res, data) = runtime.block_on(data.into_future()).unwrap();
let (res, data) = setup.runtime.block_on(data.into_future()).unwrap();
assert_eq!(
res,
Some(r#"{"jsonrpc":"2.0","method":"test","params":{"result":"ready","subscription":1}}"#.into())
);
let h = blake2_256(&replacement.encode());
assert_eq!(
runtime.block_on(data.into_future()).unwrap().0,
setup.runtime.block_on(data.into_future()).unwrap().0,
Some(format!(r#"{{"jsonrpc":"2.0","method":"test","params":{{"result":{{"usurped":"0x{}"}},"subscription":1}}}}"#, HexDisplay::from(&h)))
);
}

#[test]
fn should_return_watch_validation_error() {
//given
let mut runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone())));
let keystore = KeyStore::new();
let p = Author {
client,
pool: pool.clone(),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let mut setup = TestSetup::default();
let p = setup.author();

let (subscriber, id_rx, _data) = jsonrpc_pubsub::typed::Subscriber::new_test("test");

// when
p.watch_extrinsic(Default::default(), subscriber, uxt(AccountKeyring::Alice, 179).encode().into());

// then
let res = runtime.block_on(id_rx).unwrap();
let res = setup.runtime.block_on(id_rx).unwrap();
assert!(res.is_err(), "Expected the transaction to be rejected as invalid.");
}

#[test]
fn should_return_pending_extrinsics() {
let runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone())));
let keystore = KeyStore::new();
let p = Author {
client,
pool: pool.clone(),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let p = TestSetup::default().author();

let ex = uxt(AccountKeyring::Alice, 0);
AuthorApi::submit_extrinsic(&p, ex.encode().into()).wait().unwrap();
assert_matches!(
Expand All @@ -178,23 +172,16 @@ fn should_return_pending_extrinsics() {

#[test]
fn should_remove_extrinsics() {
let runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let pool = Arc::new(Pool::new(Default::default(), FullChainApi::new(client.clone())));
let keystore = KeyStore::new();
let p = Author {
client,
pool: pool.clone(),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let setup = TestSetup::default();
let p = setup.author();

let ex1 = uxt(AccountKeyring::Alice, 0);
p.submit_extrinsic(ex1.encode().into()).wait().unwrap();
let ex2 = uxt(AccountKeyring::Alice, 1);
p.submit_extrinsic(ex2.encode().into()).wait().unwrap();
let ex3 = uxt(AccountKeyring::Bob, 0);
let hash3 = p.submit_extrinsic(ex3.encode().into()).wait().unwrap();
assert_eq!(pool.status().ready, 3);
assert_eq!(setup.pool.status().ready, 3);

// now remove all 3
let removed = p.remove_extrinsic(vec![
Expand All @@ -208,15 +195,8 @@ fn should_remove_extrinsics() {

#[test]
fn should_insert_key() {
let runtime = runtime::Runtime::new().unwrap();
let client = Arc::new(test_client::new());
let keystore = KeyStore::new();
let p = Author {
client: client.clone(),
pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let setup = TestSetup::default();
let p = setup.author();

let suri = "//Alice";
let key_pair = ed25519::Pair::from_string(suri, None).expect("Generates keypair");
Expand All @@ -226,37 +206,28 @@ fn should_insert_key() {
key_pair.public().0.to_vec().into(),
).expect("Insert key");

let store_key_pair = keystore.read()
let store_key_pair = setup.keystore.read()
.ed25519_key_pair(ED25519, &key_pair.public()).expect("Key exists in store");

assert_eq!(key_pair.public(), store_key_pair.public());
}

#[test]
fn should_rotate_keys() {
let runtime = runtime::Runtime::new().unwrap();
let keystore = KeyStore::new();
let client = Arc::new(
test_client::TestClientBuilder::new().set_keystore(keystore.clone()).build(),
);
let p = Author {
client: client.clone(),
pool: Arc::new(Pool::new(Default::default(), FullChainApi::new(client))),
subscriptions: Subscriptions::new(Arc::new(runtime.executor())),
keystore: keystore.clone(),
};
let setup = TestSetup::default();
let p = setup.author();

let new_public_keys = p.rotate_keys().expect("Rotates the keys");

let session_keys = SessionKeys::decode(&mut &new_public_keys[..])
.expect("SessionKeys decode successfully");

let ed25519_key_pair = keystore.read().ed25519_key_pair(
let ed25519_key_pair = setup.keystore.read().ed25519_key_pair(
ED25519,
&session_keys.ed25519.clone().into(),
).expect("ed25519 key exists in store");

let sr25519_key_pair = keystore.read().sr25519_key_pair(
let sr25519_key_pair = setup.keystore.read().sr25519_key_pair(
SR25519,
&session_keys.sr25519.clone().into(),
).expect("sr25519 key exists in store");
Expand Down