Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test environment with four TS servers #1029

Merged
merged 20 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
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
9 changes: 9 additions & 0 deletions crates/testing-utils/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ lazy_static! {
hex!["2cbc68e8bf0fbc1c28c282d1263fc9d29267dc12a1044fb730e8b65abc37524c"].into(),
// Charlie - from DEFAULT_CHARLIE_MNEMONIC in entropy_tss::helpers::launch
hex!["946140d3d5ddb980c74ffa1bb64353b5523d2d77cdf3dc617fd63de9d3b66338"].into(),
// Dave - from DEFAULT_DAVE_MNEMONIC in entropy_tss::helpers::launch
hex!["0a9054ef6b6b8ad0dd2c89895b2515583f2fbf1edced68e7328ae456d86b9402"].into(),
];

// See entropy_tss::helpers::validator::get_signer_and_x25519_secret for how these are derived
Expand All @@ -57,6 +59,13 @@ lazy_static! {
]
.try_into()
.unwrap(),
// Dave - from DEFAULT_DAVE_MNEMONIC in entropy_tss::helpers::launch
vec![
165, 202, 97, 104, 222, 190, 168, 183, 231, 63, 209, 233, 19, 185, 187, 200, 10, 29, 102,
240, 39, 50, 140, 15, 124, 112, 94, 121, 44, 182, 40, 71
]
.try_into()
.unwrap()
];
}

Expand Down
54 changes: 54 additions & 0 deletions crates/testing-utils/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (C) 2023 Entropy Cryptography Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::{
chain_api::{get_api, get_rpc, EntropyConfig},
spawn_testing_validators,
substrate_context::{test_context_stationary, test_node_process_testing_state},
ChainSpecType,
};
use entropy_protocol::PartyId;
use subxt::{backend::legacy::LegacyRpcMethods, OnlineClient};

/// A helper for setting up tests which starts both a set of TS servers and a chain node and returns
/// the chain API as well as IP addresses and PartyId of the started validators
pub async fn spawn_tss_nodes_and_start_chain(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't strictly related to this PR, but since adding a way to specify which chainspec you want to use, i also added this helper which could slightly reduce boilerplate in our tests.

So this would go at the beginning of most of our tests. I haven't actually called this anywhere yet though - i wanted to run it by yous first.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this for sure 👍

add_parent_key: bool,
chain_spec_type: ChainSpecType,
) -> (OnlineClient<EntropyConfig>, LegacyRpcMethods<EntropyConfig>, Vec<String>, Vec<PartyId>) {
let (validator_ips, validator_ids) =
spawn_testing_validators(add_parent_key, chain_spec_type.clone()).await;

let (api, rpc) = match chain_spec_type {
ChainSpecType::Development => {
let substrate_context = test_context_stationary().await;
(
get_api(&substrate_context.node_proc.ws_url).await.unwrap(),
get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(),
)
},
ChainSpecType::Integration => {
// Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be
// able to get our chain in the right state to be jump started.
let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
(
get_api(&substrate_context.ws_url).await.unwrap(),
get_rpc(&substrate_context.ws_url).await.unwrap(),
)
},
};
(api, rpc, validator_ips, validator_ids)
}
3 changes: 2 additions & 1 deletion crates/testing-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ extern crate lazy_static;
pub use entropy_tss::chain_api;
pub mod constants;
pub mod create_test_keyshares;
pub mod helpers;
mod node_proc;
pub mod substrate_context;
pub use entropy_tss::helpers::tests::{
jump_start_network_with_signer as jump_start_network, spawn_testing_validators,
jump_start_network_with_signer as jump_start_network, spawn_testing_validators, ChainSpecType,
};
pub use node_proc::TestNodeProcess;
pub use substrate_context::*;
6 changes: 4 additions & 2 deletions crates/threshold-signature-server/src/attestation/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
chain_api::{entropy, get_api, get_rpc},
helpers::{
substrate::query_chain,
tests::{initialize_test_logger, run_to_block, spawn_testing_validators},
tests::{initialize_test_logger, run_to_block, spawn_testing_validators, ChainSpecType},
},
};
use entropy_kvdb::clean_tests;
Expand All @@ -32,7 +32,9 @@ async fn test_attest() {
clean_tests();

let cxt = test_node_process_stationary().await;
let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(false, ChainSpecType::Integration).await;

let api = get_api(&cxt.ws_url).await.unwrap();
let rpc = get_rpc(&cxt.ws_url).await.unwrap();

Expand Down
46 changes: 41 additions & 5 deletions crates/threshold-signature-server/src/helpers/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ use entropy_kvdb::{encrypted_sled::PasswordMethod, get_db_path, kv_manager::KvMa
use entropy_protocol::PartyId;
use entropy_shared::{DAVE_VERIFYING_KEY, EVE_VERIFYING_KEY, NETWORK_PARENT_KEY};
use std::time::Duration;

use subxt::{
backend::legacy::LegacyRpcMethods, ext::sp_core::sr25519, tx::PairSigner,
utils::AccountId32 as SubxtAccountId32, Config, OnlineClient,
Expand Down Expand Up @@ -119,10 +118,29 @@ pub async fn create_clients(
(app, kv_store)
}

/// Spawn 3 TSS nodes with pre-stored keyshares
pub async fn spawn_testing_validators(add_parent_key: bool) -> (Vec<String>, Vec<PartyId>) {
/// A way to specify which chainspec to use in testing
#[derive(Clone, PartialEq)]
pub enum ChainSpecType {
/// The development chainspec, which has 3 TSS nodes
Development,
/// The integration test chainspec, which has 4 TSS nodes
Integration,
}

/// Spawn either 3 or 4 TSS nodes depending on chain configuration, adding pre-stored keyshares if
/// desired
pub async fn spawn_testing_validators(
add_parent_key: bool,
chain_spec_type: ChainSpecType,
) -> (Vec<String>, Vec<PartyId>) {
let add_fourth_server = chain_spec_type == ChainSpecType::Integration;

// spawn threshold servers
let ports = [3001i64, 3002, 3003];
let mut ports = vec![3001i64, 3002, 3003];

if add_fourth_server {
ports.push(3004);
}

let (alice_axum, alice_kv) =
create_clients("validator1".to_string(), vec![], vec![], &Some(ValidatorName::Alice)).await;
Expand All @@ -143,11 +161,12 @@ pub async fn spawn_testing_validators(add_parent_key: bool) -> (Vec<String>, Vec
*get_signer(&charlie_kv).await.unwrap().account_id().clone().as_ref(),
));

let ids = vec![alice_id, bob_id, charlie_id];
let mut ids = vec![alice_id, bob_id, charlie_id];

put_keyshares_in_db("alice", alice_kv, add_parent_key).await;
put_keyshares_in_db("bob", bob_kv, add_parent_key).await;
put_keyshares_in_db("charlie", charlie_kv, add_parent_key).await;
// Don't give dave keyshares as dave is not initially in the signing committee

let listener_alice = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", ports[0]))
.await
Expand All @@ -170,6 +189,23 @@ pub async fn spawn_testing_validators(add_parent_key: bool) -> (Vec<String>, Vec
axum::serve(listener_charlie, charlie_axum).await.unwrap();
});

if add_fourth_server {
let (dave_axum, dave_kv) =
create_clients("validator4".to_string(), vec![], vec![], &Some(ValidatorName::Dave))
.await;

let listener_dave = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", ports[3]))
.await
.expect("Unable to bind to given server address.");
tokio::spawn(async move {
axum::serve(listener_dave, dave_axum).await.unwrap();
});
let dave_id = PartyId::new(SubxtAccountId32(
*get_signer(&dave_kv).await.unwrap().account_id().clone().as_ref(),
));
ids.push(dave_id);
}

tokio::time::sleep(Duration::from_secs(1)).await;

let ips = ports.iter().map(|port| format!("127.0.0.1:{port}")).collect();
Expand Down
11 changes: 6 additions & 5 deletions crates/threshold-signature-server/src/signing_client/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
launch::LATEST_BLOCK_NUMBER_PROACTIVE_REFRESH,
tests::{
initialize_test_logger, run_to_block, setup_client, spawn_testing_validators,
unsafe_get,
unsafe_get, ChainSpecType,
},
},
};
Expand All @@ -45,7 +45,8 @@ async fn test_proactive_refresh() {
clean_tests();
let _cxt = test_node_process_testing_state(false).await;

let (validator_ips, _ids) = spawn_testing_validators(false).await;
let (validator_ips, _ids) = spawn_testing_validators(false, ChainSpecType::Integration).await;
let signing_committee_ips = &validator_ips[..3].to_vec();

let client = reqwest::Client::new();

Expand Down Expand Up @@ -78,14 +79,14 @@ async fn test_proactive_refresh() {
};

let test_fail_incorrect_data =
submit_transaction_requests(validator_ips.clone(), ocw_message.clone()).await;
submit_transaction_requests(signing_committee_ips.clone(), ocw_message.clone()).await;

for res in test_fail_incorrect_data {
assert_eq!(res.unwrap().text().await.unwrap(), "Proactive Refresh data incorrect");
}
ocw_message.validators_info[0].x25519_public_key = X25519_PUBLIC_KEYS[0];
let test_user_res =
submit_transaction_requests(validator_ips.clone(), ocw_message.clone()).await;
submit_transaction_requests(signing_committee_ips.clone(), ocw_message.clone()).await;

for res in test_user_res {
assert_eq!(res.unwrap().text().await.unwrap(), "");
Expand All @@ -104,7 +105,7 @@ async fn test_proactive_refresh() {
ocw_message.validators_info[2].tss_account = alice.public().encode();

let test_user_res_not_in_group =
submit_transaction_requests(validator_ips.clone(), ocw_message.clone()).await;
submit_transaction_requests(signing_committee_ips.clone(), ocw_message.clone()).await;
for res in test_user_res_not_in_group {
assert_eq!(
res.unwrap().text().await.unwrap(),
Expand Down
35 changes: 23 additions & 12 deletions crates/threshold-signature-server/src/user/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ use crate::{
substrate::{get_oracle_data, query_chain, submit_transaction},
tests::{
create_clients, initialize_test_logger, jump_start_network_with_signer, remove_program,
run_to_block, setup_client, spawn_testing_validators, unsafe_get,
run_to_block, setup_client, spawn_testing_validators, unsafe_get, ChainSpecType,
},
user::compute_hash,
validator::get_signer_and_x25519_secret_from_mnemonic,
Expand Down Expand Up @@ -169,7 +169,8 @@ async fn test_signature_requests_fail_on_different_conditions() {
let two = AccountKeyring::Two;

let add_parent_key_to_kvdb = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key_to_kvdb, ChainSpecType::Integration).await;

// Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be
// able to get our chain in the right state to be jump started.
Expand Down Expand Up @@ -326,7 +327,8 @@ async fn signature_request_with_derived_account_works() {
let charlie = AccountKeyring::Charlie;

let add_parent_key_to_kvdb = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key_to_kvdb, ChainSpecType::Integration).await;

// Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be
// able to get our chain in the right state to be jump started.
Expand Down Expand Up @@ -396,7 +398,8 @@ async fn test_signing_fails_if_wrong_participants_are_used() {
let one = AccountKeyring::Dave;

let add_parent_key = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key, ChainSpecType::Integration).await;

let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
Expand Down Expand Up @@ -470,7 +473,8 @@ async fn test_request_limit_are_updated_during_signing() {
let two = AccountKeyring::Two;

let add_parent_key = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key, ChainSpecType::Integration).await;

let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
Expand Down Expand Up @@ -592,7 +596,8 @@ async fn test_fails_to_sign_if_non_signing_group_participants_are_used() {
let two = AccountKeyring::Two;

let add_parent_key = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key, ChainSpecType::Integration).await;

let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
Expand Down Expand Up @@ -703,7 +708,8 @@ async fn test_program_with_config() {
let two = AccountKeyring::Two;

let add_parent_key = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key, ChainSpecType::Integration).await;

let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
Expand Down Expand Up @@ -790,7 +796,8 @@ async fn test_jumpstart_network() {
let alice = AccountKeyring::Alice;

let cxt = test_context_stationary().await;
let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(false, ChainSpecType::Development).await;
let api = get_api(&cxt.node_proc.ws_url).await.unwrap();
let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap();

Expand Down Expand Up @@ -1002,7 +1009,8 @@ async fn test_fail_infinite_program() {
let two = AccountKeyring::Two;

let add_parent_key = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key, ChainSpecType::Integration).await;

let force_authoring = true;
let substrate_context = test_node_process_testing_state(force_authoring).await;
Expand Down Expand Up @@ -1085,7 +1093,8 @@ async fn test_device_key_proxy() {
let two = AccountKeyring::Two;

let add_parent_key_to_kvdb = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key_to_kvdb, ChainSpecType::Integration).await;

// Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be
// able to get our chain in the right state to be jump started.
Expand Down Expand Up @@ -1223,7 +1232,8 @@ async fn test_faucet() {
let two = AccountKeyring::Eve;
let alice = AccountKeyring::Alice;

let (validator_ips, _validator_ids) = spawn_testing_validators(false).await;
let (validator_ips, _validator_ids) =
spawn_testing_validators(false, ChainSpecType::Development).await;
let substrate_context = test_node_process_testing_state(true).await;
let entropy_api = get_api(&substrate_context.ws_url).await.unwrap();
let rpc = get_rpc(&substrate_context.ws_url).await.unwrap();
Expand Down Expand Up @@ -1395,7 +1405,8 @@ async fn test_new_registration_flow() {
let charlie = AccountKeyring::Charlie;

let add_parent_key_to_kvdb = true;
let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await;
let (_validator_ips, _validator_ids) =
spawn_testing_validators(add_parent_key_to_kvdb, ChainSpecType::Integration).await;

// Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be
// able to get our chain in the right state to be jump started.
Expand Down
Loading
Loading