mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 14:28:37 +00:00
Add merge support to simulator (#3292)
## Issue Addressed N/A ## Proposed Changes Make simulator merge compatible. Adds a `--post_merge` flag to the eth1 simulator that enables a ttd and simulates the merge transition. Uses the `MockServer` in the execution layer test utils to simulate a dummy execution node. Adds the merge transition simulation to CI.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
use node_test_rig::{
|
||||
environment::RuntimeContext,
|
||||
eth2::{types::StateId, BeaconNodeHttpClient},
|
||||
ClientConfig, LocalBeaconNode, LocalValidatorClient, ValidatorConfig, ValidatorFiles,
|
||||
ClientConfig, LocalBeaconNode, LocalExecutionNode, LocalValidatorClient, MockExecutionConfig,
|
||||
MockServerConfig, ValidatorConfig, ValidatorFiles,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use sensitive_url::SensitiveUrl;
|
||||
@@ -15,11 +16,17 @@ use types::{Epoch, EthSpec};
|
||||
const BOOTNODE_PORT: u16 = 42424;
|
||||
pub const INVALID_ADDRESS: &str = "http://127.0.0.1:42423";
|
||||
|
||||
pub const EXECUTION_PORT: u16 = 4000;
|
||||
|
||||
pub const TERMINAL_DIFFICULTY: u64 = 6400;
|
||||
pub const TERMINAL_BLOCK: u64 = 64;
|
||||
|
||||
/// Helper struct to reduce `Arc` usage.
|
||||
pub struct Inner<E: EthSpec> {
|
||||
pub context: RuntimeContext<E>,
|
||||
pub beacon_nodes: RwLock<Vec<LocalBeaconNode<E>>>,
|
||||
pub validator_clients: RwLock<Vec<LocalValidatorClient<E>>>,
|
||||
pub execution_nodes: RwLock<Vec<LocalExecutionNode<E>>>,
|
||||
}
|
||||
|
||||
/// Represents a set of interconnected `LocalBeaconNode` and `LocalValidatorClient`.
|
||||
@@ -46,7 +53,7 @@ impl<E: EthSpec> Deref for LocalNetwork<E> {
|
||||
}
|
||||
|
||||
impl<E: EthSpec> LocalNetwork<E> {
|
||||
/// Creates a new network with a single `BeaconNode`.
|
||||
/// Creates a new network with a single `BeaconNode` and a connected `ExecutionNode`.
|
||||
pub async fn new(
|
||||
context: RuntimeContext<E>,
|
||||
mut beacon_config: ClientConfig,
|
||||
@@ -56,6 +63,30 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT);
|
||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT);
|
||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||
|
||||
let execution_node = if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||
let mock_execution_config = MockExecutionConfig {
|
||||
server_config: MockServerConfig {
|
||||
listen_port: EXECUTION_PORT,
|
||||
..Default::default()
|
||||
},
|
||||
terminal_block: TERMINAL_BLOCK,
|
||||
terminal_difficulty: TERMINAL_DIFFICULTY.into(),
|
||||
..Default::default()
|
||||
};
|
||||
let execution_node = LocalExecutionNode::new(
|
||||
context.service_context("boot_node_el".into()),
|
||||
mock_execution_config,
|
||||
);
|
||||
el_config.default_datadir = execution_node.datadir.path().to_path_buf();
|
||||
el_config.secret_files = vec![execution_node.datadir.path().join("jwt.hex")];
|
||||
el_config.execution_endpoints =
|
||||
vec![SensitiveUrl::parse(&execution_node.server.url()).unwrap()];
|
||||
vec![execution_node]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let beacon_node =
|
||||
LocalBeaconNode::production(context.service_context("boot_node".into()), beacon_config)
|
||||
.await?;
|
||||
@@ -63,6 +94,7 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
inner: Arc::new(Inner {
|
||||
context,
|
||||
beacon_nodes: RwLock::new(vec![beacon_node]),
|
||||
execution_nodes: RwLock::new(execution_node),
|
||||
validator_clients: RwLock::new(vec![]),
|
||||
}),
|
||||
})
|
||||
@@ -87,6 +119,7 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
/// Adds a beacon node to the network, connecting to the 0'th beacon node via ENR.
|
||||
pub async fn add_beacon_node(&self, mut beacon_config: ClientConfig) -> Result<(), String> {
|
||||
let self_1 = self.clone();
|
||||
let count = self.beacon_node_count() as u16;
|
||||
println!("Adding beacon node..");
|
||||
{
|
||||
let read_lock = self.beacon_nodes.read();
|
||||
@@ -99,20 +132,38 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
.enr()
|
||||
.expect("bootnode must have a network"),
|
||||
);
|
||||
let count = self.beacon_node_count() as u16;
|
||||
beacon_config.network.discovery_port = BOOTNODE_PORT + count;
|
||||
beacon_config.network.libp2p_port = BOOTNODE_PORT + count;
|
||||
beacon_config.network.enr_udp_port = Some(BOOTNODE_PORT + count);
|
||||
beacon_config.network.enr_tcp_port = Some(BOOTNODE_PORT + count);
|
||||
beacon_config.network.discv5_config.table_filter = |_| true;
|
||||
}
|
||||
if let Some(el_config) = &mut beacon_config.execution_layer {
|
||||
let config = MockExecutionConfig {
|
||||
server_config: MockServerConfig {
|
||||
listen_port: EXECUTION_PORT + count,
|
||||
..Default::default()
|
||||
},
|
||||
terminal_block: TERMINAL_BLOCK,
|
||||
terminal_difficulty: TERMINAL_DIFFICULTY.into(),
|
||||
..Default::default()
|
||||
};
|
||||
let execution_node = LocalExecutionNode::new(
|
||||
self.context.service_context(format!("node_{}_el", count)),
|
||||
config,
|
||||
);
|
||||
el_config.default_datadir = execution_node.datadir.path().to_path_buf();
|
||||
el_config.secret_files = vec![execution_node.datadir.path().join("jwt.hex")];
|
||||
el_config.execution_endpoints =
|
||||
vec![SensitiveUrl::parse(&execution_node.server.url()).unwrap()];
|
||||
self.execution_nodes.write().push(execution_node);
|
||||
}
|
||||
|
||||
// We create the beacon node without holding the lock, so that the lock isn't held
|
||||
// across the await. This is only correct if this function never runs in parallel
|
||||
// with itself (which at the time of writing, it does not).
|
||||
let index = self_1.beacon_nodes.read().len();
|
||||
let beacon_node = LocalBeaconNode::production(
|
||||
self.context.service_context(format!("node_{}", index)),
|
||||
self.context.service_context(format!("node_{}", count)),
|
||||
beacon_config,
|
||||
)
|
||||
.await?;
|
||||
@@ -184,6 +235,16 @@ impl<E: EthSpec> LocalNetwork<E> {
|
||||
.map(|body| body.unwrap().data.finalized.epoch)
|
||||
}
|
||||
|
||||
pub fn mine_pow_blocks(&self, block_number: u64) -> Result<(), String> {
|
||||
let execution_nodes = self.execution_nodes.read();
|
||||
for execution_node in execution_nodes.iter() {
|
||||
let mut block_gen = execution_node.server.ctx.execution_block_generator.write();
|
||||
block_gen.insert_pow_block(block_number)?;
|
||||
println!("Mined pow block {}", block_number);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn duration_to_genesis(&self) -> Duration {
|
||||
let nodes = self.remote_nodes().expect("Failed to get remote nodes");
|
||||
let bootnode = nodes.first().expect("Should contain bootnode");
|
||||
|
||||
Reference in New Issue
Block a user