mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 03:12:41 +00:00
Add beacon_chain_sim
This commit is contained in:
@@ -37,6 +37,7 @@ members = [
|
||||
"beacon_node/eth1",
|
||||
"beacon_node/beacon_chain",
|
||||
"beacon_node/websocket_server",
|
||||
"tests/beacon_chain_sim",
|
||||
"tests/ef_tests",
|
||||
"tests/eth1_test_rig",
|
||||
"tests/node_test_rig",
|
||||
|
||||
@@ -6,6 +6,7 @@ pub mod builder;
|
||||
pub mod error;
|
||||
|
||||
use beacon_chain::BeaconChain;
|
||||
use eth2_libp2p::{Enr, Multiaddr};
|
||||
use exit_future::Signal;
|
||||
use network::Service as NetworkService;
|
||||
use std::net::SocketAddr;
|
||||
@@ -48,6 +49,16 @@ impl<T: BeaconChainTypes> Client<T> {
|
||||
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
||||
self.libp2p_network.as_ref().map(|n| n.listen_port())
|
||||
}
|
||||
|
||||
/// Returns the list of libp2p addresses the client is listening to.
|
||||
pub fn libp2p_listen_addresses(&self) -> Option<Vec<Multiaddr>> {
|
||||
self.libp2p_network.as_ref().map(|n| n.listen_multiaddrs())
|
||||
}
|
||||
|
||||
/// Returns the local libp2p ENR of this node, for network discovery.
|
||||
pub fn enr(&self) -> Option<Enr> {
|
||||
self.libp2p_network.as_ref().map(|n| n.local_enr())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> Drop for Client<T> {
|
||||
|
||||
@@ -193,7 +193,7 @@ impl<E: EthSpec> Environment<E> {
|
||||
}
|
||||
|
||||
/// Returns a `Context` where the `service_name` is added to the logger output.
|
||||
pub fn service_context(&mut self, service_name: &'static str) -> RuntimeContext<E> {
|
||||
pub fn service_context(&mut self, service_name: String) -> RuntimeContext<E> {
|
||||
RuntimeContext {
|
||||
executor: self.runtime.executor(),
|
||||
log: self.log.new(o!("service" => service_name)),
|
||||
|
||||
11
tests/beacon_chain_sim/Cargo.toml
Normal file
11
tests/beacon_chain_sim/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "beacon_chain_sim"
|
||||
version = "0.1.0"
|
||||
authors = ["Paul Hauner <paul@paulhauner.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
node_test_rig = { path = "../node_test_rig" }
|
||||
types = { path = "../../eth2/types" }
|
||||
77
tests/beacon_chain_sim/src/main.rs
Normal file
77
tests/beacon_chain_sim/src/main.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use node_test_rig::{
|
||||
environment::{EnvironmentBuilder, RuntimeContext},
|
||||
testing_client_config, ClientConfig, LocalBeaconNode, ProductionClient,
|
||||
};
|
||||
use types::EthSpec;
|
||||
|
||||
pub type BeaconNode<E> = LocalBeaconNode<ProductionClient<E>>;
|
||||
|
||||
fn main() {
|
||||
match simulation(4) {
|
||||
Ok(()) => println!("Simulation exited successfully"),
|
||||
Err(e) => println!("Simulation exited with error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn simulation(num_nodes: usize) -> Result<(), String> {
|
||||
if num_nodes < 1 {
|
||||
return Err("Must have at least one node".into());
|
||||
}
|
||||
|
||||
let mut env = EnvironmentBuilder::minimal()
|
||||
.async_logger("debug")?
|
||||
.multi_threaded_tokio_runtime()?
|
||||
.build()?;
|
||||
|
||||
let base_config = testing_client_config();
|
||||
|
||||
let boot_node =
|
||||
BeaconNode::production(env.service_context("boot_node".into()), base_config.clone());
|
||||
|
||||
let nodes = (1..num_nodes)
|
||||
.map(|i| {
|
||||
let context = env.service_context(format!("node_{}", i));
|
||||
new_with_bootnode_via_enr(context, &boot_node, base_config.clone())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
env.block_until_ctrl_c()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TODO: this function does not result in nodes connecting to each other. Age to investigate?
|
||||
fn new_with_bootnode_via_enr<E: EthSpec>(
|
||||
context: RuntimeContext<E>,
|
||||
boot_node: &BeaconNode<E>,
|
||||
base_config: ClientConfig,
|
||||
) -> BeaconNode<E> {
|
||||
let mut config = base_config;
|
||||
config.network.boot_nodes.push(
|
||||
boot_node
|
||||
.client
|
||||
.enr()
|
||||
.expect("bootnode must have a network"),
|
||||
);
|
||||
|
||||
BeaconNode::production(context, config)
|
||||
}
|
||||
|
||||
fn new_with_bootnode_via_multiaddr<E: EthSpec>(
|
||||
context: RuntimeContext<E>,
|
||||
boot_node: &BeaconNode<E>,
|
||||
base_config: ClientConfig,
|
||||
) -> BeaconNode<E> {
|
||||
let mut config = base_config;
|
||||
config.network.libp2p_nodes.push(
|
||||
boot_node
|
||||
.client
|
||||
.libp2p_listen_addresses()
|
||||
.expect("bootnode must have a network")
|
||||
.first()
|
||||
.expect("bootnode must have at least one listen addr")
|
||||
.clone(),
|
||||
);
|
||||
|
||||
BeaconNode::production(context, config)
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
use beacon_node::{
|
||||
beacon_chain::BeaconChainTypes, Client, ClientConfig, ClientGenesis, ProductionBeaconNode,
|
||||
ProductionClient,
|
||||
};
|
||||
use beacon_node::{beacon_chain::BeaconChainTypes, Client, ClientGenesis, ProductionBeaconNode};
|
||||
use environment::RuntimeContext;
|
||||
use futures::Future;
|
||||
use remote_beacon_node::RemoteBeaconNode;
|
||||
use std::path::PathBuf;
|
||||
use tempdir::TempDir;
|
||||
use types::EthSpec;
|
||||
|
||||
pub use beacon_node::{ClientConfig, ProductionClient};
|
||||
pub use environment;
|
||||
|
||||
/// Provides a beacon node that is running in the current process. Useful for testing purposes.
|
||||
@@ -18,8 +17,13 @@ pub struct LocalBeaconNode<T> {
|
||||
|
||||
impl<E: EthSpec> LocalBeaconNode<ProductionClient<E>> {
|
||||
/// Starts a new, production beacon node.
|
||||
pub fn production(context: RuntimeContext<E>) -> Self {
|
||||
let (client_config, datadir) = testing_client_config();
|
||||
pub fn production(context: RuntimeContext<E>, mut client_config: ClientConfig) -> Self {
|
||||
// Creates a temporary directory that will be deleted once this `TempDir` is dropped.
|
||||
let datadir = TempDir::new("lighthouse_node_test_rig")
|
||||
.expect("should create temp directory for client datadir");
|
||||
|
||||
client_config.data_dir = datadir.path().into();
|
||||
client_config.network.network_dir = PathBuf::from(datadir.path()).join("network");
|
||||
|
||||
let client = ProductionBeaconNode::new(context, client_config)
|
||||
.wait()
|
||||
@@ -42,15 +46,9 @@ impl<T: BeaconChainTypes> LocalBeaconNode<Client<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
fn testing_client_config() -> (ClientConfig, TempDir) {
|
||||
// Creates a temporary directory that will be deleted once this `TempDir` is dropped.
|
||||
let tempdir = TempDir::new("lighthouse_node_test_rig")
|
||||
.expect("should create temp directory for client datadir");
|
||||
|
||||
pub fn testing_client_config() -> ClientConfig {
|
||||
let mut client_config = ClientConfig::default();
|
||||
|
||||
client_config.data_dir = tempdir.path().into();
|
||||
|
||||
// Setting ports to `0` means that the OS will choose some available port.
|
||||
client_config.network.libp2p_port = 0;
|
||||
client_config.network.discovery_port = 0;
|
||||
@@ -63,5 +61,5 @@ fn testing_client_config() -> (ClientConfig, TempDir) {
|
||||
genesis_time: 13_371_337,
|
||||
};
|
||||
|
||||
(client_config, tempdir)
|
||||
client_config
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user