mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +00:00
Migrate VC tests to tokio::test
This commit is contained in:
@@ -25,9 +25,8 @@ use std::marker::PhantomData;
|
|||||||
use std::net::{IpAddr, Ipv4Addr};
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use task_executor::TaskExecutor;
|
use task_executor::test_utils::TestRuntime;
|
||||||
use tempfile::{tempdir, TempDir};
|
use tempfile::{tempdir, TempDir};
|
||||||
use tokio::runtime::Runtime;
|
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
pub const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
|
pub const PASSWORD_BYTES: &[u8] = &[42, 50, 37];
|
||||||
@@ -57,23 +56,13 @@ pub struct ApiTester {
|
|||||||
pub initialized_validators: Arc<RwLock<InitializedValidators>>,
|
pub initialized_validators: Arc<RwLock<InitializedValidators>>,
|
||||||
pub validator_store: Arc<ValidatorStore<TestingSlotClock, E>>,
|
pub validator_store: Arc<ValidatorStore<TestingSlotClock, E>>,
|
||||||
pub url: SensitiveUrl,
|
pub url: SensitiveUrl,
|
||||||
|
pub test_runtime: TestRuntime,
|
||||||
pub _server_shutdown: oneshot::Sender<()>,
|
pub _server_shutdown: oneshot::Sender<()>,
|
||||||
pub _validator_dir: TempDir,
|
pub _validator_dir: TempDir,
|
||||||
pub _runtime_shutdown: exit_future::Signal,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builds a runtime to be used in the testing configuration.
|
|
||||||
pub fn build_runtime() -> Arc<Runtime> {
|
|
||||||
Arc::new(
|
|
||||||
tokio::runtime::Builder::new_multi_thread()
|
|
||||||
.enable_all()
|
|
||||||
.build()
|
|
||||||
.expect("Should be able to build a testing runtime"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiTester {
|
impl ApiTester {
|
||||||
pub async fn new(runtime: std::sync::Weak<Runtime>) -> Self {
|
pub async fn new() -> Self {
|
||||||
let log = test_logger();
|
let log = test_logger();
|
||||||
|
|
||||||
let validator_dir = tempdir().unwrap();
|
let validator_dir = tempdir().unwrap();
|
||||||
@@ -105,9 +94,7 @@ impl ApiTester {
|
|||||||
let slot_clock =
|
let slot_clock =
|
||||||
TestingSlotClock::new(Slot::new(0), Duration::from_secs(0), Duration::from_secs(1));
|
TestingSlotClock::new(Slot::new(0), Duration::from_secs(0), Duration::from_secs(1));
|
||||||
|
|
||||||
let (runtime_shutdown, exit) = exit_future::signal();
|
let test_runtime = TestRuntime::default();
|
||||||
let (shutdown_tx, _) = futures::channel::mpsc::channel(1);
|
|
||||||
let executor = TaskExecutor::new(runtime.clone(), exit, log.clone(), shutdown_tx);
|
|
||||||
|
|
||||||
let validator_store = Arc::new(ValidatorStore::<_, E>::new(
|
let validator_store = Arc::new(ValidatorStore::<_, E>::new(
|
||||||
initialized_validators,
|
initialized_validators,
|
||||||
@@ -117,7 +104,7 @@ impl ApiTester {
|
|||||||
Some(Arc::new(DoppelgangerService::new(log.clone()))),
|
Some(Arc::new(DoppelgangerService::new(log.clone()))),
|
||||||
slot_clock,
|
slot_clock,
|
||||||
&config,
|
&config,
|
||||||
executor.clone(),
|
test_runtime.task_executor.clone(),
|
||||||
log.clone(),
|
log.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -128,7 +115,7 @@ impl ApiTester {
|
|||||||
let initialized_validators = validator_store.initialized_validators();
|
let initialized_validators = validator_store.initialized_validators();
|
||||||
|
|
||||||
let context = Arc::new(Context {
|
let context = Arc::new(Context {
|
||||||
task_executor: executor,
|
task_executor: test_runtime.task_executor.clone(),
|
||||||
api_secret,
|
api_secret,
|
||||||
validator_dir: Some(validator_dir.path().into()),
|
validator_dir: Some(validator_dir.path().into()),
|
||||||
validator_store: Some(validator_store.clone()),
|
validator_store: Some(validator_store.clone()),
|
||||||
@@ -166,9 +153,9 @@ impl ApiTester {
|
|||||||
initialized_validators,
|
initialized_validators,
|
||||||
validator_store,
|
validator_store,
|
||||||
url,
|
url,
|
||||||
|
test_runtime,
|
||||||
_server_shutdown: shutdown_tx,
|
_server_shutdown: shutdown_tx,
|
||||||
_validator_dir: validator_dir,
|
_validator_dir: validator_dir,
|
||||||
_runtime_shutdown: runtime_shutdown,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,337 +1,298 @@
|
|||||||
#![cfg(test)]
|
#![cfg(test)]
|
||||||
#![cfg(not(debug_assertions))]
|
// #![cfg(not(debug_assertions))]
|
||||||
|
|
||||||
mod keystores;
|
mod keystores;
|
||||||
|
|
||||||
use crate::http_api::test_utils::{
|
use crate::http_api::test_utils::{
|
||||||
build_runtime, ApiTester, HdValidatorScenario, KeystoreValidatorScenario,
|
ApiTester, HdValidatorScenario, KeystoreValidatorScenario, Web3SignerValidatorScenario,
|
||||||
Web3SignerValidatorScenario, TEST_DEFAULT_FEE_RECIPIENT,
|
TEST_DEFAULT_FEE_RECIPIENT,
|
||||||
};
|
};
|
||||||
use account_utils::{random_password, random_password_string, ZeroizeString};
|
use account_utils::{random_password, random_password_string, ZeroizeString};
|
||||||
use eth2::lighthouse_vc::types::*;
|
use eth2::lighthouse_vc::types::*;
|
||||||
use eth2_keystore::KeystoreBuilder;
|
use eth2_keystore::KeystoreBuilder;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
type E = MainnetEthSpec;
|
type E = MainnetEthSpec;
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn invalid_pubkey() {
|
async fn invalid_pubkey() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.invalidate_api_token()
|
||||||
ApiTester::new(weak_runtime)
|
.test_get_lighthouse_version_invalid()
|
||||||
.await
|
.await;
|
||||||
.invalidate_api_token()
|
|
||||||
.test_get_lighthouse_version_invalid()
|
|
||||||
.await;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn routes_with_invalid_auth() {
|
async fn routes_with_invalid_auth() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.test_with_invalid_auth(|client| async move { client.get_lighthouse_version().await })
|
||||||
ApiTester::new(weak_runtime)
|
.await
|
||||||
.await
|
.test_with_invalid_auth(|client| async move { client.get_lighthouse_health().await })
|
||||||
.test_with_invalid_auth(|client| async move { client.get_lighthouse_version().await })
|
.await
|
||||||
.await
|
.test_with_invalid_auth(|client| async move {
|
||||||
.test_with_invalid_auth(|client| async move { client.get_lighthouse_health().await })
|
client.get_lighthouse_spec::<types::Config>().await
|
||||||
.await
|
})
|
||||||
.test_with_invalid_auth(|client| async move {
|
.await
|
||||||
client.get_lighthouse_spec::<types::Config>().await
|
.test_with_invalid_auth(|client| async move { client.get_lighthouse_validators().await })
|
||||||
})
|
.await
|
||||||
.await
|
.test_with_invalid_auth(|client| async move {
|
||||||
.test_with_invalid_auth(
|
client
|
||||||
|client| async move { client.get_lighthouse_validators().await },
|
.get_lighthouse_validators_pubkey(&PublicKeyBytes::empty())
|
||||||
)
|
.await
|
||||||
.await
|
})
|
||||||
.test_with_invalid_auth(|client| async move {
|
.await
|
||||||
client
|
.test_with_invalid_auth(|client| async move {
|
||||||
.get_lighthouse_validators_pubkey(&PublicKeyBytes::empty())
|
client
|
||||||
.await
|
.post_lighthouse_validators(vec![ValidatorRequest {
|
||||||
})
|
enable: <_>::default(),
|
||||||
.await
|
description: <_>::default(),
|
||||||
.test_with_invalid_auth(|client| async move {
|
graffiti: <_>::default(),
|
||||||
client
|
suggested_fee_recipient: <_>::default(),
|
||||||
.post_lighthouse_validators(vec![ValidatorRequest {
|
gas_limit: <_>::default(),
|
||||||
enable: <_>::default(),
|
builder_proposals: <_>::default(),
|
||||||
description: <_>::default(),
|
deposit_gwei: <_>::default(),
|
||||||
graffiti: <_>::default(),
|
}])
|
||||||
suggested_fee_recipient: <_>::default(),
|
.await
|
||||||
gas_limit: <_>::default(),
|
})
|
||||||
builder_proposals: <_>::default(),
|
.await
|
||||||
deposit_gwei: <_>::default(),
|
.test_with_invalid_auth(|client| async move {
|
||||||
}])
|
client
|
||||||
.await
|
.post_lighthouse_validators_mnemonic(&CreateValidatorsMnemonicRequest {
|
||||||
})
|
mnemonic: String::default().into(),
|
||||||
.await
|
key_derivation_path_offset: <_>::default(),
|
||||||
.test_with_invalid_auth(|client| async move {
|
validators: <_>::default(),
|
||||||
client
|
})
|
||||||
.post_lighthouse_validators_mnemonic(&CreateValidatorsMnemonicRequest {
|
.await
|
||||||
mnemonic: String::default().into(),
|
})
|
||||||
key_derivation_path_offset: <_>::default(),
|
.await
|
||||||
validators: <_>::default(),
|
.test_with_invalid_auth(|client| async move {
|
||||||
})
|
let password = random_password();
|
||||||
.await
|
let keypair = Keypair::random();
|
||||||
})
|
let keystore = KeystoreBuilder::new(&keypair, password.as_bytes(), String::new())
|
||||||
.await
|
.unwrap()
|
||||||
.test_with_invalid_auth(|client| async move {
|
.build()
|
||||||
let password = random_password();
|
.unwrap();
|
||||||
let keypair = Keypair::random();
|
client
|
||||||
let keystore = KeystoreBuilder::new(&keypair, password.as_bytes(), String::new())
|
.post_lighthouse_validators_keystore(&KeystoreValidatorsPostRequest {
|
||||||
.unwrap()
|
password: String::default().into(),
|
||||||
.build()
|
enable: <_>::default(),
|
||||||
.unwrap();
|
keystore,
|
||||||
client
|
graffiti: <_>::default(),
|
||||||
.post_lighthouse_validators_keystore(&KeystoreValidatorsPostRequest {
|
suggested_fee_recipient: <_>::default(),
|
||||||
password: String::default().into(),
|
gas_limit: <_>::default(),
|
||||||
enable: <_>::default(),
|
builder_proposals: <_>::default(),
|
||||||
keystore,
|
})
|
||||||
graffiti: <_>::default(),
|
.await
|
||||||
suggested_fee_recipient: <_>::default(),
|
})
|
||||||
gas_limit: <_>::default(),
|
.await
|
||||||
builder_proposals: <_>::default(),
|
.test_with_invalid_auth(|client| async move {
|
||||||
})
|
client
|
||||||
.await
|
.patch_lighthouse_validators(&PublicKeyBytes::empty(), Some(false), None, None)
|
||||||
})
|
.await
|
||||||
.await
|
})
|
||||||
.test_with_invalid_auth(|client| async move {
|
.await
|
||||||
client
|
.test_with_invalid_auth(|client| async move { client.get_keystores().await })
|
||||||
.patch_lighthouse_validators(&PublicKeyBytes::empty(), Some(false), None, None)
|
.await
|
||||||
.await
|
.test_with_invalid_auth(|client| async move {
|
||||||
})
|
let password = random_password_string();
|
||||||
.await
|
let keypair = Keypair::random();
|
||||||
.test_with_invalid_auth(|client| async move { client.get_keystores().await })
|
let keystore = KeystoreBuilder::new(&keypair, password.as_ref(), String::new())
|
||||||
.await
|
.unwrap()
|
||||||
.test_with_invalid_auth(|client| async move {
|
.build()
|
||||||
let password = random_password_string();
|
.map(KeystoreJsonStr)
|
||||||
let keypair = Keypair::random();
|
.unwrap();
|
||||||
let keystore = KeystoreBuilder::new(&keypair, password.as_ref(), String::new())
|
client
|
||||||
.unwrap()
|
.post_keystores(&ImportKeystoresRequest {
|
||||||
.build()
|
keystores: vec![keystore],
|
||||||
.map(KeystoreJsonStr)
|
passwords: vec![password],
|
||||||
.unwrap();
|
slashing_protection: None,
|
||||||
client
|
})
|
||||||
.post_keystores(&ImportKeystoresRequest {
|
.await
|
||||||
keystores: vec![keystore],
|
})
|
||||||
passwords: vec![password],
|
.await
|
||||||
slashing_protection: None,
|
.test_with_invalid_auth(|client| async move {
|
||||||
})
|
let keypair = Keypair::random();
|
||||||
.await
|
client
|
||||||
})
|
.delete_keystores(&DeleteKeystoresRequest {
|
||||||
.await
|
pubkeys: vec![keypair.pk.compress()],
|
||||||
.test_with_invalid_auth(|client| async move {
|
})
|
||||||
let keypair = Keypair::random();
|
.await
|
||||||
client
|
})
|
||||||
.delete_keystores(&DeleteKeystoresRequest {
|
.await;
|
||||||
pubkeys: vec![keypair.pk.compress()],
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn simple_getters() {
|
async fn simple_getters() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.test_get_lighthouse_version()
|
||||||
ApiTester::new(weak_runtime)
|
.await
|
||||||
.await
|
.test_get_lighthouse_health()
|
||||||
.test_get_lighthouse_version()
|
.await
|
||||||
.await
|
.test_get_lighthouse_spec()
|
||||||
.test_get_lighthouse_health()
|
.await;
|
||||||
.await
|
|
||||||
.test_get_lighthouse_spec()
|
|
||||||
.await;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn hd_validator_creation() {
|
async fn hd_validator_creation() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.assert_enabled_validators_count(0)
|
||||||
ApiTester::new(weak_runtime)
|
.assert_validators_count(0)
|
||||||
.await
|
.create_hd_validators(HdValidatorScenario {
|
||||||
.assert_enabled_validators_count(0)
|
count: 2,
|
||||||
.assert_validators_count(0)
|
specify_mnemonic: true,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 0,
|
||||||
count: 2,
|
disabled: vec![],
|
||||||
specify_mnemonic: true,
|
})
|
||||||
key_derivation_path_offset: 0,
|
.await
|
||||||
disabled: vec![],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(2)
|
||||||
.await
|
.create_hd_validators(HdValidatorScenario {
|
||||||
.assert_enabled_validators_count(2)
|
count: 1,
|
||||||
.assert_validators_count(2)
|
specify_mnemonic: false,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 0,
|
||||||
count: 1,
|
disabled: vec![0],
|
||||||
specify_mnemonic: false,
|
})
|
||||||
key_derivation_path_offset: 0,
|
.await
|
||||||
disabled: vec![0],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(3)
|
||||||
.await
|
.create_hd_validators(HdValidatorScenario {
|
||||||
.assert_enabled_validators_count(2)
|
count: 0,
|
||||||
.assert_validators_count(3)
|
specify_mnemonic: true,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 4,
|
||||||
count: 0,
|
disabled: vec![],
|
||||||
specify_mnemonic: true,
|
})
|
||||||
key_derivation_path_offset: 4,
|
.await
|
||||||
disabled: vec![],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(3);
|
||||||
.await
|
|
||||||
.assert_enabled_validators_count(2)
|
|
||||||
.assert_validators_count(3);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn validator_enabling() {
|
async fn validator_enabling() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.create_hd_validators(HdValidatorScenario {
|
||||||
ApiTester::new(weak_runtime)
|
count: 2,
|
||||||
.await
|
specify_mnemonic: false,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 0,
|
||||||
count: 2,
|
disabled: vec![],
|
||||||
specify_mnemonic: false,
|
})
|
||||||
key_derivation_path_offset: 0,
|
.await
|
||||||
disabled: vec![],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(2)
|
||||||
.await
|
.set_validator_enabled(0, false)
|
||||||
.assert_enabled_validators_count(2)
|
.await
|
||||||
.assert_validators_count(2)
|
.assert_enabled_validators_count(1)
|
||||||
.set_validator_enabled(0, false)
|
.assert_validators_count(2)
|
||||||
.await
|
.set_validator_enabled(0, true)
|
||||||
.assert_enabled_validators_count(1)
|
.await
|
||||||
.assert_validators_count(2)
|
.assert_enabled_validators_count(2)
|
||||||
.set_validator_enabled(0, true)
|
.assert_validators_count(2);
|
||||||
.await
|
|
||||||
.assert_enabled_validators_count(2)
|
|
||||||
.assert_validators_count(2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn validator_gas_limit() {
|
async fn validator_gas_limit() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.create_hd_validators(HdValidatorScenario {
|
||||||
ApiTester::new(weak_runtime)
|
count: 2,
|
||||||
.await
|
specify_mnemonic: false,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 0,
|
||||||
count: 2,
|
disabled: vec![],
|
||||||
specify_mnemonic: false,
|
})
|
||||||
key_derivation_path_offset: 0,
|
.await
|
||||||
disabled: vec![],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(2)
|
||||||
.await
|
.set_gas_limit(0, 500)
|
||||||
.assert_enabled_validators_count(2)
|
.await
|
||||||
.assert_validators_count(2)
|
.assert_gas_limit(0, 500)
|
||||||
.set_gas_limit(0, 500)
|
.await
|
||||||
.await
|
// Update gas limit while validator is disabled.
|
||||||
.assert_gas_limit(0, 500)
|
.set_validator_enabled(0, false)
|
||||||
.await
|
.await
|
||||||
// Update gas limit while validator is disabled.
|
.assert_enabled_validators_count(1)
|
||||||
.set_validator_enabled(0, false)
|
.assert_validators_count(2)
|
||||||
.await
|
.set_gas_limit(0, 1000)
|
||||||
.assert_enabled_validators_count(1)
|
.await
|
||||||
.assert_validators_count(2)
|
.set_validator_enabled(0, true)
|
||||||
.set_gas_limit(0, 1000)
|
.await
|
||||||
.await
|
.assert_enabled_validators_count(2)
|
||||||
.set_validator_enabled(0, true)
|
.assert_gas_limit(0, 1000)
|
||||||
.await
|
.await;
|
||||||
.assert_enabled_validators_count(2)
|
|
||||||
.assert_gas_limit(0, 1000)
|
|
||||||
.await
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn validator_builder_proposals() {
|
async fn validator_builder_proposals() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.create_hd_validators(HdValidatorScenario {
|
||||||
ApiTester::new(weak_runtime)
|
count: 2,
|
||||||
.await
|
specify_mnemonic: false,
|
||||||
.create_hd_validators(HdValidatorScenario {
|
key_derivation_path_offset: 0,
|
||||||
count: 2,
|
disabled: vec![],
|
||||||
specify_mnemonic: false,
|
})
|
||||||
key_derivation_path_offset: 0,
|
.await
|
||||||
disabled: vec![],
|
.assert_enabled_validators_count(2)
|
||||||
})
|
.assert_validators_count(2)
|
||||||
.await
|
.set_builder_proposals(0, true)
|
||||||
.assert_enabled_validators_count(2)
|
.await
|
||||||
.assert_validators_count(2)
|
// Test setting builder proposals while the validator is disabled
|
||||||
.set_builder_proposals(0, true)
|
.set_validator_enabled(0, false)
|
||||||
.await
|
.await
|
||||||
// Test setting builder proposals while the validator is disabled
|
.assert_enabled_validators_count(1)
|
||||||
.set_validator_enabled(0, false)
|
.assert_validators_count(2)
|
||||||
.await
|
.set_builder_proposals(0, false)
|
||||||
.assert_enabled_validators_count(1)
|
.await
|
||||||
.assert_validators_count(2)
|
.set_validator_enabled(0, true)
|
||||||
.set_builder_proposals(0, false)
|
.await
|
||||||
.await
|
.assert_enabled_validators_count(2)
|
||||||
.set_validator_enabled(0, true)
|
.assert_builder_proposals(0, false)
|
||||||
.await
|
.await;
|
||||||
.assert_enabled_validators_count(2)
|
|
||||||
.assert_builder_proposals(0, false)
|
|
||||||
.await
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn keystore_validator_creation() {
|
async fn keystore_validator_creation() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.assert_enabled_validators_count(0)
|
||||||
ApiTester::new(weak_runtime)
|
.assert_validators_count(0)
|
||||||
.await
|
.create_keystore_validators(KeystoreValidatorScenario {
|
||||||
.assert_enabled_validators_count(0)
|
correct_password: true,
|
||||||
.assert_validators_count(0)
|
enabled: true,
|
||||||
.create_keystore_validators(KeystoreValidatorScenario {
|
})
|
||||||
correct_password: true,
|
.await
|
||||||
enabled: true,
|
.assert_enabled_validators_count(1)
|
||||||
})
|
.assert_validators_count(1)
|
||||||
.await
|
.create_keystore_validators(KeystoreValidatorScenario {
|
||||||
.assert_enabled_validators_count(1)
|
correct_password: false,
|
||||||
.assert_validators_count(1)
|
enabled: true,
|
||||||
.create_keystore_validators(KeystoreValidatorScenario {
|
})
|
||||||
correct_password: false,
|
.await
|
||||||
enabled: true,
|
.assert_enabled_validators_count(1)
|
||||||
})
|
.assert_validators_count(1)
|
||||||
.await
|
.create_keystore_validators(KeystoreValidatorScenario {
|
||||||
.assert_enabled_validators_count(1)
|
correct_password: true,
|
||||||
.assert_validators_count(1)
|
enabled: false,
|
||||||
.create_keystore_validators(KeystoreValidatorScenario {
|
})
|
||||||
correct_password: true,
|
.await
|
||||||
enabled: false,
|
.assert_enabled_validators_count(1)
|
||||||
})
|
.assert_validators_count(2);
|
||||||
.await
|
|
||||||
.assert_enabled_validators_count(1)
|
|
||||||
.assert_validators_count(2);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn web3signer_validator_creation() {
|
async fn web3signer_validator_creation() {
|
||||||
let runtime = build_runtime();
|
ApiTester::new()
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
.await
|
||||||
runtime.block_on(async {
|
.assert_enabled_validators_count(0)
|
||||||
ApiTester::new(weak_runtime)
|
.assert_validators_count(0)
|
||||||
.await
|
.create_web3signer_validators(Web3SignerValidatorScenario {
|
||||||
.assert_enabled_validators_count(0)
|
count: 1,
|
||||||
.assert_validators_count(0)
|
enabled: true,
|
||||||
.create_web3signer_validators(Web3SignerValidatorScenario {
|
})
|
||||||
count: 1,
|
.await
|
||||||
enabled: true,
|
.assert_enabled_validators_count(1)
|
||||||
})
|
.assert_validators_count(1);
|
||||||
.await
|
|
||||||
.assert_enabled_validators_count(1)
|
|
||||||
.assert_validators_count(1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ use itertools::Itertools;
|
|||||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||||
use slashing_protection::interchange::{Interchange, InterchangeMetadata};
|
use slashing_protection::interchange::{Interchange, InterchangeMetadata};
|
||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path};
|
||||||
|
use tokio::runtime::Handle;
|
||||||
use types::Address;
|
use types::Address;
|
||||||
|
|
||||||
fn new_keystore(password: ZeroizeString) -> Keystore {
|
fn new_keystore(password: ZeroizeString) -> Keystore {
|
||||||
@@ -64,31 +65,23 @@ fn remotekey_validator_with_pubkey(pubkey: PublicKey) -> SingleImportRemotekeysR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_test<F, V>(f: F)
|
async fn run_test<F, V>(f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(ApiTester) -> V,
|
F: FnOnce(ApiTester) -> V,
|
||||||
V: Future<Output = ()>,
|
V: Future<Output = ()>,
|
||||||
{
|
{
|
||||||
let runtime = build_runtime();
|
let tester = ApiTester::new().await;
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
f(tester).await
|
||||||
runtime.block_on(async {
|
|
||||||
let tester = ApiTester::new(weak_runtime).await;
|
|
||||||
f(tester).await
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_dual_vc_test<F, V>(f: F)
|
async fn run_dual_vc_test<F, V>(f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(ApiTester, ApiTester) -> V,
|
F: FnOnce(ApiTester, ApiTester) -> V,
|
||||||
V: Future<Output = ()>,
|
V: Future<Output = ()>,
|
||||||
{
|
{
|
||||||
let runtime = build_runtime();
|
let tester1 = ApiTester::new().await;
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
let tester2 = ApiTester::new().await;
|
||||||
runtime.block_on(async {
|
f(tester1, tester2).await
|
||||||
let tester1 = ApiTester::new(weak_runtime.clone()).await;
|
|
||||||
let tester2 = ApiTester::new(weak_runtime).await;
|
|
||||||
f(tester1, tester2).await
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keystore_pubkey(keystore: &Keystore) -> PublicKeyBytes {
|
fn keystore_pubkey(keystore: &Keystore) -> PublicKeyBytes {
|
||||||
@@ -199,8 +192,8 @@ fn check_remotekey_delete_response(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn get_auth_no_token() {
|
async fn get_auth_no_token() {
|
||||||
run_test(|mut tester| async move {
|
run_test(|mut tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
tester.client.send_authorization_header(false);
|
tester.client.send_authorization_header(false);
|
||||||
@@ -213,19 +206,21 @@ fn get_auth_no_token() {
|
|||||||
// The token should match the one that the client was originally initialised with.
|
// The token should match the one that the client was originally initialised with.
|
||||||
assert!(tester.client.api_token() == Some(&token));
|
assert!(tester.client.api_token() == Some(&token));
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn get_empty_keystores() {
|
async fn get_empty_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let res = tester.client.get_keystores().await.unwrap();
|
let res = tester.client.get_keystores().await.unwrap();
|
||||||
assert_eq!(res, ListKeystoresResponse { data: vec![] });
|
assert_eq!(res, ListKeystoresResponse { data: vec![] });
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_new_keystores() {
|
async fn import_new_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -250,10 +245,11 @@ fn import_new_keystores() {
|
|||||||
let get_res = tester.client.get_keystores().await.unwrap();
|
let get_res = tester.client.get_keystores().await.unwrap();
|
||||||
check_keystore_get_response(&get_res, &keystores);
|
check_keystore_get_response(&get_res, &keystores);
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_only_duplicate_keystores() {
|
async fn import_only_duplicate_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -279,10 +275,11 @@ fn import_only_duplicate_keystores() {
|
|||||||
let get_res = tester.client.get_keystores().await.unwrap();
|
let get_res = tester.client.get_keystores().await.unwrap();
|
||||||
check_keystore_get_response(&get_res, &keystores);
|
check_keystore_get_response(&get_res, &keystores);
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_some_duplicate_keystores() {
|
async fn import_some_duplicate_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -330,10 +327,11 @@ fn import_some_duplicate_keystores() {
|
|||||||
let import_res = tester.client.post_keystores(&req2).await.unwrap();
|
let import_res = tester.client.post_keystores(&req2).await.unwrap();
|
||||||
check_keystore_import_response(&import_res, expected);
|
check_keystore_import_response(&import_res, expected);
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_wrong_number_of_passwords() {
|
async fn import_wrong_number_of_passwords() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -352,10 +350,11 @@ fn import_wrong_number_of_passwords() {
|
|||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
assert_eq!(err.status().unwrap(), 400);
|
assert_eq!(err.status().unwrap(), 400);
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn get_web3_signer_keystores() {
|
async fn get_web3_signer_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_local = 3;
|
let num_local = 3;
|
||||||
@@ -412,10 +411,11 @@ fn get_web3_signer_keystores() {
|
|||||||
assert!(get_res.data.contains(&response), "{:?}", response);
|
assert!(get_res.data.contains(&response), "{:?}", response);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_and_delete_conflicting_web3_signer_keystores() {
|
async fn import_and_delete_conflicting_web3_signer_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_keystores = 3;
|
let num_keystores = 3;
|
||||||
@@ -477,10 +477,11 @@ fn import_and_delete_conflicting_web3_signer_keystores() {
|
|||||||
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
||||||
check_keystore_delete_response(&delete_res, all_delete_error(keystores.len()));
|
check_keystore_delete_response(&delete_res, all_delete_error(keystores.len()));
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_keystores_wrong_password() {
|
async fn import_keystores_wrong_password() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_keystores = 4;
|
let num_keystores = 4;
|
||||||
@@ -551,11 +552,12 @@ fn import_keystores_wrong_password() {
|
|||||||
&import_res,
|
&import_res,
|
||||||
(0..num_keystores).map(|_| ImportKeystoreStatus::Duplicate),
|
(0..num_keystores).map(|_| ImportKeystoreStatus::Duplicate),
|
||||||
);
|
);
|
||||||
});
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_invalid_slashing_protection() {
|
async fn import_invalid_slashing_protection() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -589,10 +591,11 @@ fn import_invalid_slashing_protection() {
|
|||||||
let get_res = tester.client.get_keystores().await.unwrap();
|
let get_res = tester.client.get_keystores().await.unwrap();
|
||||||
check_keystore_get_response(&get_res, &[]);
|
check_keystore_get_response(&get_res, &[]);
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn check_get_set_fee_recipient() {
|
async fn check_get_set_fee_recipient() {
|
||||||
run_test(|tester: ApiTester| async move {
|
run_test(|tester: ApiTester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -768,6 +771,7 @@ fn check_get_set_fee_recipient() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -949,8 +953,8 @@ fn all_indices(count: usize) -> Vec<usize> {
|
|||||||
(0..count).collect()
|
(0..count).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn migrate_all_with_slashing_protection() {
|
async fn migrate_all_with_slashing_protection() {
|
||||||
let n = 3;
|
let n = 3;
|
||||||
generic_migration_test(
|
generic_migration_test(
|
||||||
n,
|
n,
|
||||||
@@ -967,11 +971,12 @@ fn migrate_all_with_slashing_protection() {
|
|||||||
(1, make_attestation(2, 3), false),
|
(1, make_attestation(2, 3), false),
|
||||||
(2, make_attestation(1, 2), false),
|
(2, make_attestation(1, 2), false),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn migrate_some_with_slashing_protection() {
|
async fn migrate_some_with_slashing_protection() {
|
||||||
let n = 3;
|
let n = 3;
|
||||||
generic_migration_test(
|
generic_migration_test(
|
||||||
n,
|
n,
|
||||||
@@ -989,11 +994,12 @@ fn migrate_some_with_slashing_protection() {
|
|||||||
(0, make_attestation(2, 3), true),
|
(0, make_attestation(2, 3), true),
|
||||||
(1, make_attestation(3, 4), true),
|
(1, make_attestation(3, 4), true),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn migrate_some_missing_slashing_protection() {
|
async fn migrate_some_missing_slashing_protection() {
|
||||||
let n = 3;
|
let n = 3;
|
||||||
generic_migration_test(
|
generic_migration_test(
|
||||||
n,
|
n,
|
||||||
@@ -1010,11 +1016,12 @@ fn migrate_some_missing_slashing_protection() {
|
|||||||
(1, make_attestation(2, 3), true),
|
(1, make_attestation(2, 3), true),
|
||||||
(0, make_attestation(2, 3), true),
|
(0, make_attestation(2, 3), true),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn migrate_some_extra_slashing_protection() {
|
async fn migrate_some_extra_slashing_protection() {
|
||||||
let n = 3;
|
let n = 3;
|
||||||
generic_migration_test(
|
generic_migration_test(
|
||||||
n,
|
n,
|
||||||
@@ -1033,7 +1040,8 @@ fn migrate_some_extra_slashing_protection() {
|
|||||||
(1, make_attestation(3, 4), true),
|
(1, make_attestation(3, 4), true),
|
||||||
(2, make_attestation(2, 3), false),
|
(2, make_attestation(2, 3), false),
|
||||||
],
|
],
|
||||||
);
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a test that creates some validators on one VC, and then migrates them to a second VC.
|
/// Run a test that creates some validators on one VC, and then migrates them to a second VC.
|
||||||
@@ -1051,7 +1059,7 @@ fn migrate_some_extra_slashing_protection() {
|
|||||||
/// - `import_indices`: validators to transfer. It needn't be a subset of `delete_indices`.
|
/// - `import_indices`: validators to transfer. It needn't be a subset of `delete_indices`.
|
||||||
/// - `second_vc_attestations`: attestations to sign on the second VC after the transfer. The bool
|
/// - `second_vc_attestations`: attestations to sign on the second VC after the transfer. The bool
|
||||||
/// indicates whether the signing should be successful.
|
/// indicates whether the signing should be successful.
|
||||||
fn generic_migration_test(
|
async fn generic_migration_test(
|
||||||
num_validators: usize,
|
num_validators: usize,
|
||||||
first_vc_attestations: Vec<(usize, Attestation<E>)>,
|
first_vc_attestations: Vec<(usize, Attestation<E>)>,
|
||||||
delete_indices: Vec<usize>,
|
delete_indices: Vec<usize>,
|
||||||
@@ -1169,11 +1177,12 @@ fn generic_migration_test(
|
|||||||
Err(e) => assert!(!should_succeed, "{:?}", e),
|
Err(e) => assert!(!should_succeed, "{:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_keystores_twice() {
|
async fn delete_keystores_twice() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -1201,10 +1210,11 @@ fn delete_keystores_twice() {
|
|||||||
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
||||||
check_keystore_delete_response(&delete_res, all_not_active(keystores.len()));
|
check_keystore_delete_response(&delete_res, all_not_active(keystores.len()));
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_nonexistent_keystores() {
|
async fn delete_nonexistent_keystores() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -1219,6 +1229,7 @@ fn delete_nonexistent_keystores() {
|
|||||||
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
let delete_res = tester.client.delete_keystores(&delete_req).await.unwrap();
|
||||||
check_keystore_delete_response(&delete_res, all_not_found(keystores.len()));
|
check_keystore_delete_response(&delete_res, all_not_found(keystores.len()));
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_attestation(source_epoch: u64, target_epoch: u64) -> Attestation<E> {
|
fn make_attestation(source_epoch: u64, target_epoch: u64) -> Attestation<E> {
|
||||||
@@ -1242,9 +1253,9 @@ fn make_attestation(source_epoch: u64, target_epoch: u64) -> Attestation<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_concurrent_with_signing() {
|
async fn delete_concurrent_with_signing() {
|
||||||
let runtime = build_runtime();
|
let handle = Handle::try_current().unwrap();
|
||||||
let num_keys = 8;
|
let num_keys = 8;
|
||||||
let num_signing_threads = 8;
|
let num_signing_threads = 8;
|
||||||
let num_attestations = 100;
|
let num_attestations = 100;
|
||||||
@@ -1257,115 +1268,112 @@ fn delete_concurrent_with_signing() {
|
|||||||
"num_keys should be divisible by num threads for simplicity"
|
"num_keys should be divisible by num threads for simplicity"
|
||||||
);
|
);
|
||||||
|
|
||||||
let weak_runtime = Arc::downgrade(&runtime);
|
let tester = ApiTester::new().await;
|
||||||
runtime.block_on(async {
|
|
||||||
let tester = ApiTester::new(weak_runtime).await;
|
|
||||||
|
|
||||||
// Generate a lot of keys and import them.
|
// Generate a lot of keys and import them.
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
let keystores = (0..num_keys)
|
let keystores = (0..num_keys)
|
||||||
.map(|_| new_keystore(password.clone()))
|
.map(|_| new_keystore(password.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let all_pubkeys = keystores.iter().map(keystore_pubkey).collect::<Vec<_>>();
|
let all_pubkeys = keystores.iter().map(keystore_pubkey).collect::<Vec<_>>();
|
||||||
|
|
||||||
let import_res = tester
|
let import_res = tester
|
||||||
.client
|
.client
|
||||||
.post_keystores(&ImportKeystoresRequest {
|
.post_keystores(&ImportKeystoresRequest {
|
||||||
keystores: keystores.clone(),
|
keystores: keystores.clone(),
|
||||||
passwords: vec![password.clone(); keystores.len()],
|
passwords: vec![password.clone(); keystores.len()],
|
||||||
slashing_protection: None,
|
slashing_protection: None,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
check_keystore_import_response(&import_res, all_imported(keystores.len()));
|
check_keystore_import_response(&import_res, all_imported(keystores.len()));
|
||||||
|
|
||||||
// Start several threads signing attestations at sequential epochs.
|
// Start several threads signing attestations at sequential epochs.
|
||||||
let mut join_handles = vec![];
|
let mut join_handles = vec![];
|
||||||
|
|
||||||
for thread_index in 0..num_signing_threads {
|
for thread_index in 0..num_signing_threads {
|
||||||
let keys_per_thread = num_keys / num_signing_threads;
|
let keys_per_thread = num_keys / num_signing_threads;
|
||||||
let validator_store = tester.validator_store.clone();
|
let validator_store = tester.validator_store.clone();
|
||||||
let thread_pubkeys = all_pubkeys
|
let thread_pubkeys = all_pubkeys
|
||||||
[thread_index * keys_per_thread..(thread_index + 1) * keys_per_thread]
|
[thread_index * keys_per_thread..(thread_index + 1) * keys_per_thread]
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
let handle = runtime.spawn(async move {
|
let handle = handle.spawn(async move {
|
||||||
for j in 0..num_attestations {
|
for j in 0..num_attestations {
|
||||||
let mut att = make_attestation(j, j + 1);
|
let mut att = make_attestation(j, j + 1);
|
||||||
for (_validator_id, public_key) in thread_pubkeys.iter().enumerate() {
|
for (_validator_id, public_key) in thread_pubkeys.iter().enumerate() {
|
||||||
let _ = validator_store
|
let _ = validator_store
|
||||||
.sign_attestation(*public_key, 0, &mut att, Epoch::new(j + 1))
|
.sign_attestation(*public_key, 0, &mut att, Epoch::new(j + 1))
|
||||||
.await;
|
.await;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
join_handles.push(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concurrently, delete each validator one at a time. Store the slashing protection
|
|
||||||
// data so we can ensure it doesn't change after a key is exported.
|
|
||||||
let mut delete_handles = vec![];
|
|
||||||
for _ in 0..num_delete_threads {
|
|
||||||
let client = tester.client.clone();
|
|
||||||
let all_pubkeys = all_pubkeys.clone();
|
|
||||||
|
|
||||||
let handle = runtime.spawn(async move {
|
|
||||||
let mut rng = SmallRng::from_entropy();
|
|
||||||
|
|
||||||
let mut slashing_protection = vec![];
|
|
||||||
for _ in 0..num_delete_attempts {
|
|
||||||
let to_delete = all_pubkeys
|
|
||||||
.iter()
|
|
||||||
.filter(|_| rng.gen_bool(delete_prob))
|
|
||||||
.copied()
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
if !to_delete.is_empty() {
|
|
||||||
let delete_res = client
|
|
||||||
.delete_keystores(&DeleteKeystoresRequest { pubkeys: to_delete })
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for status in delete_res.data.iter() {
|
|
||||||
assert_ne!(status.status, DeleteKeystoreStatus::Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
slashing_protection.push(delete_res.slashing_protection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slashing_protection
|
|
||||||
});
|
|
||||||
|
|
||||||
delete_handles.push(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect slashing protection.
|
|
||||||
let mut slashing_protection_map = HashMap::new();
|
|
||||||
let collected_slashing_protection = futures::future::join_all(delete_handles).await;
|
|
||||||
|
|
||||||
for interchange in collected_slashing_protection
|
|
||||||
.into_iter()
|
|
||||||
.flat_map(Result::unwrap)
|
|
||||||
{
|
|
||||||
for validator_data in interchange.data {
|
|
||||||
slashing_protection_map
|
|
||||||
.entry(validator_data.pubkey)
|
|
||||||
.and_modify(|existing| {
|
|
||||||
assert_eq!(
|
|
||||||
*existing, validator_data,
|
|
||||||
"slashing protection data changed after first export"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.or_insert(validator_data);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
join_handles.push(handle);
|
||||||
|
}
|
||||||
|
|
||||||
futures::future::join_all(join_handles).await
|
// Concurrently, delete each validator one at a time. Store the slashing protection
|
||||||
});
|
// data so we can ensure it doesn't change after a key is exported.
|
||||||
|
let mut delete_handles = vec![];
|
||||||
|
for _ in 0..num_delete_threads {
|
||||||
|
let client = tester.client.clone();
|
||||||
|
let all_pubkeys = all_pubkeys.clone();
|
||||||
|
|
||||||
|
let handle = handle.spawn(async move {
|
||||||
|
let mut rng = SmallRng::from_entropy();
|
||||||
|
|
||||||
|
let mut slashing_protection = vec![];
|
||||||
|
for _ in 0..num_delete_attempts {
|
||||||
|
let to_delete = all_pubkeys
|
||||||
|
.iter()
|
||||||
|
.filter(|_| rng.gen_bool(delete_prob))
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !to_delete.is_empty() {
|
||||||
|
let delete_res = client
|
||||||
|
.delete_keystores(&DeleteKeystoresRequest { pubkeys: to_delete })
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for status in delete_res.data.iter() {
|
||||||
|
assert_ne!(status.status, DeleteKeystoreStatus::Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
slashing_protection.push(delete_res.slashing_protection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slashing_protection
|
||||||
|
});
|
||||||
|
|
||||||
|
delete_handles.push(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect slashing protection.
|
||||||
|
let mut slashing_protection_map = HashMap::new();
|
||||||
|
let collected_slashing_protection = futures::future::join_all(delete_handles).await;
|
||||||
|
|
||||||
|
for interchange in collected_slashing_protection
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(Result::unwrap)
|
||||||
|
{
|
||||||
|
for validator_data in interchange.data {
|
||||||
|
slashing_protection_map
|
||||||
|
.entry(validator_data.pubkey)
|
||||||
|
.and_modify(|existing| {
|
||||||
|
assert_eq!(
|
||||||
|
*existing, validator_data,
|
||||||
|
"slashing protection data changed after first export"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.or_insert(validator_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
futures::future::join_all(join_handles).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_then_reimport() {
|
async fn delete_then_reimport() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let password = random_password_string();
|
let password = random_password_string();
|
||||||
@@ -1396,19 +1404,21 @@ fn delete_then_reimport() {
|
|||||||
let import_res = tester.client.post_keystores(&import_req).await.unwrap();
|
let import_res = tester.client.post_keystores(&import_req).await.unwrap();
|
||||||
check_keystore_import_response(&import_res, all_imported(keystores.len()));
|
check_keystore_import_response(&import_res, all_imported(keystores.len()));
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn get_empty_remotekeys() {
|
async fn get_empty_remotekeys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let res = tester.client.get_remotekeys().await.unwrap();
|
let res = tester.client.get_remotekeys().await.unwrap();
|
||||||
assert_eq!(res, ListRemotekeysResponse { data: vec![] });
|
assert_eq!(res, ListRemotekeysResponse { data: vec![] });
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_new_remotekeys() {
|
async fn import_new_remotekeys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1443,10 +1453,11 @@ fn import_new_remotekeys() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_same_remotekey_different_url() {
|
async fn import_same_remotekey_different_url() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1485,10 +1496,11 @@ fn import_same_remotekey_different_url() {
|
|||||||
}],
|
}],
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_remotekey_then_reimport_different_url() {
|
async fn delete_remotekey_then_reimport_different_url() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1534,10 +1546,11 @@ fn delete_remotekey_then_reimport_different_url() {
|
|||||||
vec![ImportRemotekeyStatus::Imported].into_iter(),
|
vec![ImportRemotekeyStatus::Imported].into_iter(),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_only_duplicate_remotekeys() {
|
async fn import_only_duplicate_remotekeys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let remotekeys = (0..3)
|
let remotekeys = (0..3)
|
||||||
@@ -1582,10 +1595,11 @@ fn import_only_duplicate_remotekeys() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_some_duplicate_remotekeys() {
|
async fn import_some_duplicate_remotekeys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_remotekeys = 5;
|
let num_remotekeys = 5;
|
||||||
@@ -1649,10 +1663,11 @@ fn import_some_duplicate_remotekeys() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_remote_and_local_keys() {
|
async fn import_remote_and_local_keys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_local = 3;
|
let num_local = 3;
|
||||||
@@ -1714,10 +1729,11 @@ fn import_remote_and_local_keys() {
|
|||||||
assert!(get_res.data.contains(&response), "{:?}", response);
|
assert!(get_res.data.contains(&response), "{:?}", response);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_same_local_and_remote_keys() {
|
async fn import_same_local_and_remote_keys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_local = 3;
|
let num_local = 3;
|
||||||
@@ -1782,9 +1798,10 @@ fn import_same_local_and_remote_keys() {
|
|||||||
assert!(get_res.data.contains(&response), "{:?}", response);
|
assert!(get_res.data.contains(&response), "{:?}", response);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_same_remote_and_local_keys() {
|
async fn import_same_remote_and_local_keys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
let num_local = 3;
|
let num_local = 3;
|
||||||
@@ -1847,10 +1864,11 @@ fn import_same_remote_and_local_keys() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_remotekeys_twice() {
|
async fn delete_remotekeys_twice() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1893,10 +1911,11 @@ fn delete_remotekeys_twice() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, Vec::new());
|
check_remotekey_get_response(&get_res, Vec::new());
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_nonexistent_remotekey() {
|
async fn delete_nonexistent_remotekey() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1919,10 +1938,11 @@ fn delete_nonexistent_remotekey() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, Vec::new());
|
check_remotekey_get_response(&get_res, Vec::new());
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn delete_then_reimport_remotekeys() {
|
async fn delete_then_reimport_remotekeys() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -1984,10 +2004,11 @@ fn delete_then_reimport_remotekeys() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_remotekey_web3signer() {
|
async fn import_remotekey_web3signer() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -2043,10 +2064,11 @@ fn import_remotekey_web3signer() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_remotekey_web3signer_disabled() {
|
async fn import_remotekey_web3signer_disabled() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -2096,10 +2118,11 @@ fn import_remotekey_web3signer_disabled() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[tokio::test]
|
||||||
fn import_remotekey_web3signer_enabled() {
|
async fn import_remotekey_web3signer_enabled() {
|
||||||
run_test(|tester| async move {
|
run_test(|tester| async move {
|
||||||
let _ = &tester;
|
let _ = &tester;
|
||||||
|
|
||||||
@@ -2156,4 +2179,5 @@ fn import_remotekey_web3signer_enabled() {
|
|||||||
let get_res = tester.client.get_remotekeys().await.unwrap();
|
let get_res = tester.client.get_remotekeys().await.unwrap();
|
||||||
check_remotekey_get_response(&get_res, expected_responses);
|
check_remotekey_get_response(&get_res, expected_responses);
|
||||||
})
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user