mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-09 11:25:55 +00:00
Tidy sim, fix broken rest_api tests
This commit is contained in:
@@ -26,6 +26,16 @@ fn build_env() -> Environment<E> {
|
|||||||
.expect("environment should build")
|
.expect("environment should build")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn build_node<E: EthSpec>(env: &mut Environment<E>) -> LocalBeaconNode<E> {
|
||||||
|
let context = env.core_context();
|
||||||
|
env.runtime()
|
||||||
|
.block_on(LocalBeaconNode::production(
|
||||||
|
context,
|
||||||
|
testing_client_config(),
|
||||||
|
))
|
||||||
|
.expect("should block until node created")
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the randao reveal for the given slot (assuming the given `beacon_chain` uses
|
/// Returns the randao reveal for the given slot (assuming the given `beacon_chain` uses
|
||||||
/// deterministic keypairs).
|
/// deterministic keypairs).
|
||||||
fn get_randao_reveal<T: BeaconChainTypes>(
|
fn get_randao_reveal<T: BeaconChainTypes>(
|
||||||
@@ -64,7 +74,7 @@ fn validator_produce_attestation() {
|
|||||||
|
|
||||||
let spec = &E::default_spec();
|
let spec = &E::default_spec();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let beacon_chain = node
|
let beacon_chain = node
|
||||||
@@ -160,7 +170,7 @@ fn validator_duties_bulk() {
|
|||||||
|
|
||||||
let spec = &E::default_spec();
|
let spec = &E::default_spec();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let beacon_chain = node
|
let beacon_chain = node
|
||||||
@@ -197,7 +207,7 @@ fn validator_duties() {
|
|||||||
|
|
||||||
let spec = &E::default_spec();
|
let spec = &E::default_spec();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let beacon_chain = node
|
let beacon_chain = node
|
||||||
@@ -321,7 +331,7 @@ fn validator_block_post() {
|
|||||||
genesis_time: 13_371_337,
|
genesis_time: 13_371_337,
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), config);
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let beacon_chain = node
|
let beacon_chain = node
|
||||||
@@ -387,7 +397,7 @@ fn validator_block_get() {
|
|||||||
|
|
||||||
let spec = &E::default_spec();
|
let spec = &E::default_spec();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let beacon_chain = node
|
let beacon_chain = node
|
||||||
@@ -425,7 +435,7 @@ fn validator_block_get() {
|
|||||||
fn beacon_state() {
|
fn beacon_state() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let (state_by_slot, root) = env
|
let (state_by_slot, root) = env
|
||||||
@@ -469,7 +479,7 @@ fn beacon_state() {
|
|||||||
fn beacon_block() {
|
fn beacon_block() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let (block_by_slot, root) = env
|
let (block_by_slot, root) = env
|
||||||
@@ -513,7 +523,7 @@ fn beacon_block() {
|
|||||||
fn genesis_time() {
|
fn genesis_time() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let genesis_time = env
|
let genesis_time = env
|
||||||
@@ -537,7 +547,7 @@ fn genesis_time() {
|
|||||||
fn fork() {
|
fn fork() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let fork = env
|
let fork = env
|
||||||
@@ -561,7 +571,7 @@ fn fork() {
|
|||||||
fn eth2_config() {
|
fn eth2_config() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let eth2_config = env
|
let eth2_config = env
|
||||||
@@ -585,7 +595,7 @@ fn eth2_config() {
|
|||||||
fn get_version() {
|
fn get_version() {
|
||||||
let mut env = build_env();
|
let mut env = build_env();
|
||||||
|
|
||||||
let node = LocalBeaconNode::production(env.core_context(), testing_client_config());
|
let node = build_node(&mut env);
|
||||||
let remote_node = node.remote_node().expect("should produce remote node");
|
let remote_node = node.remote_node().expect("should produce remote node");
|
||||||
|
|
||||||
let version = env
|
let version = env
|
||||||
|
|||||||
@@ -2,15 +2,31 @@ use crate::local_network::LocalNetwork;
|
|||||||
use futures::{stream, Future, IntoFuture, Stream};
|
use futures::{stream, Future, IntoFuture, Stream};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::timer::Delay;
|
use tokio::timer::Delay;
|
||||||
use types::{Epoch, EthSpec, Slot};
|
use types::{Epoch, EthSpec, Slot, Unsigned};
|
||||||
|
|
||||||
|
/// Checks that all of the validators have on-boarded by the start of the second eth1 voting
|
||||||
|
/// period.
|
||||||
|
pub fn verify_initial_validator_count<E: EthSpec>(
|
||||||
|
network: LocalNetwork<E>,
|
||||||
|
slot_duration: Duration,
|
||||||
|
initial_validator_count: usize,
|
||||||
|
) -> impl Future<Item = (), Error = String> {
|
||||||
|
slot_delay(Slot::new(1), slot_duration)
|
||||||
|
.and_then(move |()| verify_validator_count(network, initial_validator_count))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks that all of the validators have on-boarded by the start of the second eth1 voting
|
||||||
|
/// period.
|
||||||
pub fn verify_validator_onboarding<E: EthSpec>(
|
pub fn verify_validator_onboarding<E: EthSpec>(
|
||||||
network: LocalNetwork<E>,
|
network: LocalNetwork<E>,
|
||||||
slot_duration: Duration,
|
slot_duration: Duration,
|
||||||
expected_validator_count: usize,
|
expected_validator_count: usize,
|
||||||
) -> impl Future<Item = (), Error = String> {
|
) -> impl Future<Item = (), Error = String> {
|
||||||
slot_delay(Slot::new(32), slot_duration)
|
slot_delay(
|
||||||
.and_then(move |()| verify_validator_count(network, expected_validator_count))
|
Slot::new(E::SlotsPerEth1VotingPeriod::to_u64()),
|
||||||
|
slot_duration,
|
||||||
|
)
|
||||||
|
.and_then(move |()| verify_validator_count(network, expected_validator_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that the chain has made the first possible finalization.
|
/// Checks that the chain has made the first possible finalization.
|
||||||
@@ -42,6 +58,8 @@ fn slot_delay(slots: Slot, slot_duration: Duration) -> impl Future<Item = (), Er
|
|||||||
Delay::new(Instant::now() + duration).map_err(|e| format!("Epoch delay failed: {:?}", e))
|
Delay::new(Instant::now() + duration).map_err(|e| format!("Epoch delay failed: {:?}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifies that all beacon nodes in the given network have a head state that has a finalized
|
||||||
|
/// epoch of `epoch`.
|
||||||
fn verify_all_finalized_at<E: EthSpec>(
|
fn verify_all_finalized_at<E: EthSpec>(
|
||||||
network: LocalNetwork<E>,
|
network: LocalNetwork<E>,
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
@@ -75,6 +93,8 @@ fn verify_all_finalized_at<E: EthSpec>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Verifies that all beacon nodes in the given `network` have a head state that contains
|
||||||
|
/// `expected_count` validators.
|
||||||
fn verify_validator_count<E: EthSpec>(
|
fn verify_validator_count<E: EthSpec>(
|
||||||
network: LocalNetwork<E>,
|
network: LocalNetwork<E>,
|
||||||
expected_count: usize,
|
expected_count: usize,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use crate::{BeaconNode, ValidatorClient};
|
|
||||||
use futures::{Future, IntoFuture};
|
use futures::{Future, IntoFuture};
|
||||||
use node_test_rig::{
|
use node_test_rig::{
|
||||||
environment::RuntimeContext, ClientConfig, LocalValidatorClient, RemoteBeaconNode,
|
environment::RuntimeContext, ClientConfig, LocalBeaconNode, LocalValidatorClient,
|
||||||
ValidatorConfig,
|
RemoteBeaconNode, ValidatorConfig,
|
||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@@ -11,8 +10,8 @@ use types::EthSpec;
|
|||||||
|
|
||||||
pub struct Inner<E: EthSpec> {
|
pub struct Inner<E: EthSpec> {
|
||||||
context: RuntimeContext<E>,
|
context: RuntimeContext<E>,
|
||||||
beacon_nodes: RwLock<Vec<BeaconNode<E>>>,
|
beacon_nodes: RwLock<Vec<LocalBeaconNode<E>>>,
|
||||||
validator_clients: RwLock<Vec<ValidatorClient<E>>>,
|
validator_clients: RwLock<Vec<LocalValidatorClient<E>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LocalNetwork<E: EthSpec> {
|
pub struct LocalNetwork<E: EthSpec> {
|
||||||
@@ -41,7 +40,7 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
context: RuntimeContext<E>,
|
context: RuntimeContext<E>,
|
||||||
beacon_config: ClientConfig,
|
beacon_config: ClientConfig,
|
||||||
) -> impl Future<Item = Self, Error = String> {
|
) -> impl Future<Item = Self, Error = String> {
|
||||||
BeaconNode::production(context.service_context("boot_node".into()), beacon_config).map(
|
LocalBeaconNode::production(context.service_context("boot_node".into()), beacon_config).map(
|
||||||
|beacon_node| Self {
|
|beacon_node| Self {
|
||||||
inner: Arc::new(Inner {
|
inner: Arc::new(Inner {
|
||||||
context,
|
context,
|
||||||
@@ -81,7 +80,7 @@ impl<E: EthSpec> LocalNetwork<E> {
|
|||||||
|
|
||||||
let index = self.beacon_nodes.read().len();
|
let index = self.beacon_nodes.read().len();
|
||||||
|
|
||||||
BeaconNode::production(
|
LocalBeaconNode::production(
|
||||||
self.context.service_context(format!("node_{}", index)),
|
self.context.service_context(format!("node_{}", index)),
|
||||||
beacon_config,
|
beacon_config,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,28 +1,57 @@
|
|||||||
|
//! This crate provides a simluation that creates `n` beacon node and validator clients, each with
|
||||||
|
//! `v` validators. A deposit contract is deployed at the start of the simulation using a local
|
||||||
|
//! `ganache-cli` instance (you must have `ganache-cli` installed and avaliable on your path). All
|
||||||
|
//! beacon nodes independently listen for genesis from the deposit contract, then start operating.
|
||||||
|
//!
|
||||||
|
//! As the simulation runs, there are checks made to ensure that all components are running
|
||||||
|
//! correctly. If any of these checks fail, the simulation will exit immediately.
|
||||||
|
//!
|
||||||
|
//! By default, the simulation will end as soon as all checks have finished. It may be configured
|
||||||
|
//! to run indefinitely by setting `end_after_checks = false`.
|
||||||
|
//!
|
||||||
|
//! ## Future works
|
||||||
|
//!
|
||||||
|
//! Presently all the beacon nodes and validator clients all log to stdout. Additionally, the
|
||||||
|
//! simulation uses `println` to communicate some info. It might be nice if the nodes logged to
|
||||||
|
//! easy-to-find files and stdout only contained info from the simulation.
|
||||||
|
//!
|
||||||
|
//! It would also be nice to add a CLI using `clap` so that the variables in `main()` can be
|
||||||
|
//! changed without a recompile.
|
||||||
|
|
||||||
mod checks;
|
mod checks;
|
||||||
mod local_network;
|
mod local_network;
|
||||||
|
|
||||||
use eth1_test_rig::GanacheEth1Instance;
|
use eth1_test_rig::GanacheEth1Instance;
|
||||||
use futures::{stream, Future, Stream};
|
use futures::{future, stream, Future, Stream};
|
||||||
use local_network::LocalNetwork;
|
use local_network::LocalNetwork;
|
||||||
use node_test_rig::{
|
use node_test_rig::{
|
||||||
environment::EnvironmentBuilder, testing_client_config, ClientGenesis, LocalBeaconNode,
|
environment::EnvironmentBuilder, testing_client_config, ClientGenesis, ValidatorConfig,
|
||||||
LocalValidatorClient, ProductionClient, ValidatorConfig,
|
|
||||||
};
|
};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::timer::Interval;
|
use tokio::timer::Interval;
|
||||||
use types::MinimalEthSpec;
|
use types::MinimalEthSpec;
|
||||||
|
|
||||||
pub type E = MinimalEthSpec;
|
pub type E = MinimalEthSpec;
|
||||||
pub type BeaconNode<E> = LocalBeaconNode<ProductionClient<E>>;
|
|
||||||
pub type ValidatorClient<E> = LocalValidatorClient<E>;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let nodes = 4;
|
let nodes = 4;
|
||||||
let validators_per_node = 20;
|
let validators_per_node = 20;
|
||||||
|
let log_level = "debug";
|
||||||
|
let speed_up_factor = 4;
|
||||||
|
let end_after_checks = true;
|
||||||
|
|
||||||
match async_sim(nodes, validators_per_node, 4) {
|
match async_sim(
|
||||||
|
nodes,
|
||||||
|
validators_per_node,
|
||||||
|
speed_up_factor,
|
||||||
|
log_level,
|
||||||
|
end_after_checks,
|
||||||
|
) {
|
||||||
Ok(()) => println!("Simulation exited successfully"),
|
Ok(()) => println!("Simulation exited successfully"),
|
||||||
Err(e) => eprintln!("Simulation exited with error: {}", e),
|
Err(e) => {
|
||||||
|
eprintln!("Simulation exited with error: {}", e);
|
||||||
|
std::process::exit(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,9 +59,11 @@ fn async_sim(
|
|||||||
node_count: usize,
|
node_count: usize,
|
||||||
validators_per_node: usize,
|
validators_per_node: usize,
|
||||||
speed_up_factor: u64,
|
speed_up_factor: u64,
|
||||||
|
log_level: &str,
|
||||||
|
end_after_checks: bool,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let mut env = EnvironmentBuilder::minimal()
|
let mut env = EnvironmentBuilder::minimal()
|
||||||
.async_logger("debug")?
|
.async_logger(log_level)?
|
||||||
.multi_threaded_tokio_runtime()?
|
.multi_threaded_tokio_runtime()?
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
@@ -47,13 +78,18 @@ fn async_sim(
|
|||||||
spec.min_genesis_active_validator_count = 64;
|
spec.min_genesis_active_validator_count = 64;
|
||||||
|
|
||||||
let slot_duration = Duration::from_millis(spec.milliseconds_per_slot);
|
let slot_duration = Duration::from_millis(spec.milliseconds_per_slot);
|
||||||
let validator_count = validators_per_node * node_count;
|
let initial_validator_count = spec.min_genesis_active_validator_count as usize;
|
||||||
|
let total_validator_count = validators_per_node * node_count;
|
||||||
let deposit_amount = env.eth2_config.spec.max_effective_balance;
|
let deposit_amount = env.eth2_config.spec.max_effective_balance;
|
||||||
|
|
||||||
let context = env.core_context();
|
let context = env.core_context();
|
||||||
let executor = context.executor.clone();
|
let executor = context.executor.clone();
|
||||||
|
|
||||||
let future = GanacheEth1Instance::new()
|
let future = GanacheEth1Instance::new()
|
||||||
|
/*
|
||||||
|
* Deploy the deposit contract, spawn tasks to keep creating new blocks and deposit
|
||||||
|
* validators.
|
||||||
|
*/
|
||||||
.map(move |ganache_eth1_instance| {
|
.map(move |ganache_eth1_instance| {
|
||||||
let deposit_contract = ganache_eth1_instance.deposit_contract;
|
let deposit_contract = ganache_eth1_instance.deposit_contract;
|
||||||
let ganache = ganache_eth1_instance.ganache;
|
let ganache = ganache_eth1_instance.ganache;
|
||||||
@@ -71,7 +107,7 @@ fn async_sim(
|
|||||||
|
|
||||||
// Submit deposits to the deposit contract.
|
// Submit deposits to the deposit contract.
|
||||||
executor.spawn(
|
executor.spawn(
|
||||||
stream::unfold(0..validator_count, move |mut iter| {
|
stream::unfold(0..total_validator_count, move |mut iter| {
|
||||||
iter.next().map(|i| {
|
iter.next().map(|i| {
|
||||||
println!("Submitting deposit for validator {}...", i);
|
println!("Submitting deposit for validator {}...", i);
|
||||||
deposit_contract
|
deposit_contract
|
||||||
@@ -84,9 +120,6 @@ fn async_sim(
|
|||||||
.map_err(|e| eprintln!("Error submitting deposit: {}", e)),
|
.map_err(|e| eprintln!("Error submitting deposit: {}", e)),
|
||||||
);
|
);
|
||||||
|
|
||||||
(deposit_contract_address, eth1_endpoint)
|
|
||||||
})
|
|
||||||
.map(move |(deposit_contract_address, eth1_endpoint)| {
|
|
||||||
let mut beacon_config = testing_client_config();
|
let mut beacon_config = testing_client_config();
|
||||||
|
|
||||||
beacon_config.genesis = ClientGenesis::DepositContract;
|
beacon_config.genesis = ClientGenesis::DepositContract;
|
||||||
@@ -100,10 +133,16 @@ fn async_sim(
|
|||||||
|
|
||||||
beacon_config
|
beacon_config
|
||||||
})
|
})
|
||||||
|
/*
|
||||||
|
* Create a new `LocalNetwork` with one beacon node.
|
||||||
|
*/
|
||||||
.and_then(move |beacon_config| {
|
.and_then(move |beacon_config| {
|
||||||
LocalNetwork::new(context, beacon_config.clone())
|
LocalNetwork::new(context, beacon_config.clone())
|
||||||
.map(|network| (network, beacon_config))
|
.map(|network| (network, beacon_config))
|
||||||
})
|
})
|
||||||
|
/*
|
||||||
|
* One by one, add beacon nodes to the network.
|
||||||
|
*/
|
||||||
.and_then(move |(network, beacon_config)| {
|
.and_then(move |(network, beacon_config)| {
|
||||||
let network_1 = network.clone();
|
let network_1 = network.clone();
|
||||||
|
|
||||||
@@ -117,9 +156,20 @@ fn async_sim(
|
|||||||
.collect()
|
.collect()
|
||||||
.map(|_| network)
|
.map(|_| network)
|
||||||
})
|
})
|
||||||
|
/*
|
||||||
|
* One by one, add validator clients to the network. Each validator client is attached to
|
||||||
|
* a single corresponding beacon node.
|
||||||
|
*/
|
||||||
.and_then(move |network| {
|
.and_then(move |network| {
|
||||||
let network_1 = network.clone();
|
let network_1 = network.clone();
|
||||||
|
|
||||||
|
// Note: presently the validator client future will only resolve once genesis time
|
||||||
|
// occurs. This is great for this scenario, but likely to change in the future.
|
||||||
|
//
|
||||||
|
// If the validator client future behaviour changes, we would need to add a new future
|
||||||
|
// that delays until genesis. Otherwise, all of the checks that start in the next
|
||||||
|
// future will start too early.
|
||||||
|
|
||||||
stream::unfold(0..node_count, move |mut iter| {
|
stream::unfold(0..node_count, move |mut iter| {
|
||||||
iter.next().map(|i| {
|
iter.next().map(|i| {
|
||||||
let indices = (i * validators_per_node..(i + 1) * validators_per_node)
|
let indices = (i * validators_per_node..(i + 1) * validators_per_node)
|
||||||
@@ -133,15 +183,46 @@ fn async_sim(
|
|||||||
.collect()
|
.collect()
|
||||||
.map(|_| network)
|
.map(|_| network)
|
||||||
})
|
})
|
||||||
|
/*
|
||||||
|
* Start the processes that will run checks on the network as it runs.
|
||||||
|
*/
|
||||||
.and_then(move |network| {
|
.and_then(move |network| {
|
||||||
checks::verify_first_finalization(network.clone(), slot_duration)
|
// The `final_future` either completes immediately or never completes, depending on the value
|
||||||
|
// of `end_after_checks`.
|
||||||
|
let final_future: Box<dyn Future<Item = (), Error = String> + Send> =
|
||||||
|
if end_after_checks {
|
||||||
|
Box::new(future::ok(()).map_err(|()| "".to_string()))
|
||||||
|
} else {
|
||||||
|
Box::new(future::empty().map_err(|()| "".to_string()))
|
||||||
|
};
|
||||||
|
|
||||||
|
future::ok(())
|
||||||
|
// Check that the chain finalizes at the first given opportunity.
|
||||||
|
.join(checks::verify_first_finalization(
|
||||||
|
network.clone(),
|
||||||
|
slot_duration,
|
||||||
|
))
|
||||||
|
// Check that the chain starts with the expected validator count.
|
||||||
|
.join(checks::verify_initial_validator_count(
|
||||||
|
network.clone(),
|
||||||
|
slot_duration,
|
||||||
|
initial_validator_count,
|
||||||
|
))
|
||||||
|
// Check that validators greater than `spec.min_genesis_active_validator_count` are
|
||||||
|
// onboarded at the first possible opportunity.
|
||||||
.join(checks::verify_validator_onboarding(
|
.join(checks::verify_validator_onboarding(
|
||||||
network.clone(),
|
network.clone(),
|
||||||
slot_duration,
|
slot_duration,
|
||||||
validator_count,
|
total_validator_count,
|
||||||
))
|
))
|
||||||
|
// End now or run forever, depending on the `end_after_checks` flag.
|
||||||
|
.join(final_future)
|
||||||
.map(|_| network)
|
.map(|_| network)
|
||||||
})
|
})
|
||||||
|
/*
|
||||||
|
* End the simulation by dropping the network. This will kill all running beacon nodes and
|
||||||
|
* validator clients.
|
||||||
|
*/
|
||||||
.map(|network| {
|
.map(|network| {
|
||||||
println!(
|
println!(
|
||||||
"Simulation complete. Finished with {} beacon nodes and {} validator clients",
|
"Simulation complete. Finished with {} beacon nodes and {} validator clients",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Intended to be used for testing and simulation purposes. Not for production.
|
//! Intended to be used for testing and simulation purposes. Not for production.
|
||||||
|
|
||||||
use beacon_node::{beacon_chain::BeaconChainTypes, Client, ProductionBeaconNode};
|
use beacon_node::ProductionBeaconNode;
|
||||||
use environment::RuntimeContext;
|
use environment::RuntimeContext;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -20,12 +20,12 @@ pub use validator_client::Config as ValidatorConfig;
|
|||||||
/// is _local_ to this process).
|
/// is _local_ to this process).
|
||||||
///
|
///
|
||||||
/// Intended for use in testing and simulation. Not for production.
|
/// Intended for use in testing and simulation. Not for production.
|
||||||
pub struct LocalBeaconNode<T> {
|
pub struct LocalBeaconNode<E: EthSpec> {
|
||||||
pub client: T,
|
pub client: ProductionClient<E>,
|
||||||
pub datadir: TempDir,
|
pub datadir: TempDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> LocalBeaconNode<ProductionClient<E>> {
|
impl<E: EthSpec> LocalBeaconNode<E> {
|
||||||
/// Starts a new, production beacon node on the tokio runtime in the given `context`.
|
/// Starts a new, production beacon node on the tokio runtime in the given `context`.
|
||||||
///
|
///
|
||||||
/// The node created is using the same types as the node we use in production.
|
/// The node created is using the same types as the node we use in production.
|
||||||
@@ -47,10 +47,10 @@ impl<E: EthSpec> LocalBeaconNode<ProductionClient<E>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> LocalBeaconNode<Client<T>> {
|
impl<E: EthSpec> LocalBeaconNode<E> {
|
||||||
/// Returns a `RemoteBeaconNode` that can connect to `self`. Useful for testing the node as if
|
/// Returns a `RemoteBeaconNode` that can connect to `self`. Useful for testing the node as if
|
||||||
/// it were external this process.
|
/// it were external this process.
|
||||||
pub fn remote_node(&self) -> Result<RemoteBeaconNode<T::EthSpec>, String> {
|
pub fn remote_node(&self) -> Result<RemoteBeaconNode<E>, String> {
|
||||||
let socket_addr = self
|
let socket_addr = self
|
||||||
.client
|
.client
|
||||||
.http_listen_addr()
|
.http_listen_addr()
|
||||||
|
|||||||
Reference in New Issue
Block a user