mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-03 21:04:28 +00:00
Add beacon_chain_sim
This commit is contained in:
@@ -37,6 +37,7 @@ members = [
|
|||||||
"beacon_node/eth1",
|
"beacon_node/eth1",
|
||||||
"beacon_node/beacon_chain",
|
"beacon_node/beacon_chain",
|
||||||
"beacon_node/websocket_server",
|
"beacon_node/websocket_server",
|
||||||
|
"tests/beacon_chain_sim",
|
||||||
"tests/ef_tests",
|
"tests/ef_tests",
|
||||||
"tests/eth1_test_rig",
|
"tests/eth1_test_rig",
|
||||||
"tests/node_test_rig",
|
"tests/node_test_rig",
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub mod builder;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use beacon_chain::BeaconChain;
|
use beacon_chain::BeaconChain;
|
||||||
|
use eth2_libp2p::{Enr, Multiaddr};
|
||||||
use exit_future::Signal;
|
use exit_future::Signal;
|
||||||
use network::Service as NetworkService;
|
use network::Service as NetworkService;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@@ -48,6 +49,16 @@ impl<T: BeaconChainTypes> Client<T> {
|
|||||||
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
pub fn libp2p_listen_port(&self) -> Option<u16> {
|
||||||
self.libp2p_network.as_ref().map(|n| n.listen_port())
|
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> {
|
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.
|
/// 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 {
|
RuntimeContext {
|
||||||
executor: self.runtime.executor(),
|
executor: self.runtime.executor(),
|
||||||
log: self.log.new(o!("service" => service_name)),
|
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::{
|
use beacon_node::{beacon_chain::BeaconChainTypes, Client, ClientGenesis, ProductionBeaconNode};
|
||||||
beacon_chain::BeaconChainTypes, Client, ClientConfig, ClientGenesis, ProductionBeaconNode,
|
|
||||||
ProductionClient,
|
|
||||||
};
|
|
||||||
use environment::RuntimeContext;
|
use environment::RuntimeContext;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use remote_beacon_node::RemoteBeaconNode;
|
use remote_beacon_node::RemoteBeaconNode;
|
||||||
|
use std::path::PathBuf;
|
||||||
use tempdir::TempDir;
|
use tempdir::TempDir;
|
||||||
use types::EthSpec;
|
use types::EthSpec;
|
||||||
|
|
||||||
|
pub use beacon_node::{ClientConfig, ProductionClient};
|
||||||
pub use environment;
|
pub use environment;
|
||||||
|
|
||||||
/// Provides a beacon node that is running in the current process. Useful for testing purposes.
|
/// 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>> {
|
impl<E: EthSpec> LocalBeaconNode<ProductionClient<E>> {
|
||||||
/// Starts a new, production beacon node.
|
/// Starts a new, production beacon node.
|
||||||
pub fn production(context: RuntimeContext<E>) -> Self {
|
pub fn production(context: RuntimeContext<E>, mut client_config: ClientConfig) -> Self {
|
||||||
let (client_config, datadir) = testing_client_config();
|
// 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)
|
let client = ProductionBeaconNode::new(context, client_config)
|
||||||
.wait()
|
.wait()
|
||||||
@@ -42,15 +46,9 @@ impl<T: BeaconChainTypes> LocalBeaconNode<Client<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_client_config() -> (ClientConfig, TempDir) {
|
pub fn testing_client_config() -> ClientConfig {
|
||||||
// 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");
|
|
||||||
|
|
||||||
let mut client_config = ClientConfig::default();
|
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.
|
// Setting ports to `0` means that the OS will choose some available port.
|
||||||
client_config.network.libp2p_port = 0;
|
client_config.network.libp2p_port = 0;
|
||||||
client_config.network.discovery_port = 0;
|
client_config.network.discovery_port = 0;
|
||||||
@@ -63,5 +61,5 @@ fn testing_client_config() -> (ClientConfig, TempDir) {
|
|||||||
genesis_time: 13_371_337,
|
genesis_time: 13_371_337,
|
||||||
};
|
};
|
||||||
|
|
||||||
(client_config, tempdir)
|
client_config
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user