Files
lighthouse/testing/execution_engine_integration/src/nethermind.rs
Daniel Knopik ee1b6bc81b Create network_utils crate (#7761)
Anchor currently depends on `lighthouse_network` for a few types and utilities that live within. As we use our own libp2p behaviours, we actually do not use the core logic in that crate. This makes us transitively depend on a bunch of unneeded crates (even a whole separate libp2p if the versions mismatch!)


  Move things we require into it's own lightweight crate.


Co-Authored-By: Daniel Knopik <daniel@dknopik.de>
2025-09-10 12:59:24 +00:00

132 lines
4.5 KiB
Rust

use crate::build_utils;
use crate::execution_engine::GenericExecutionEngine;
use crate::genesis_json::nethermind_genesis_json;
use network_utils::unused_port::unused_tcp4_port;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Output};
use tempfile::TempDir;
/// We've pinned the Nethermind version since our method of using the `master` branch to
/// find the latest tag isn't working. It appears Nethermind don't always tag on `master`.
/// We should fix this so we always pull the latest version of Nethermind.
const NETHERMIND_BRANCH: &str = "release/1.27.0";
const NETHERMIND_REPO_URL: &str = "https://github.com/NethermindEth/nethermind";
fn build_result(repo_dir: &Path) -> Output {
Command::new("dotnet")
.arg("build")
.arg("src/Nethermind/Nethermind.sln")
.arg("-c")
.arg("Release")
.current_dir(repo_dir)
.output()
.expect("failed to make nethermind")
}
pub fn build(execution_clients_dir: &Path) {
let repo_dir = execution_clients_dir.join("nethermind");
if !repo_dir.exists() {
// Clone the repo
build_utils::clone_repo(execution_clients_dir, NETHERMIND_REPO_URL).unwrap()
}
// Get the latest tag
let last_release = build_utils::get_latest_release(&repo_dir, NETHERMIND_BRANCH).unwrap();
build_utils::checkout(&repo_dir, dbg!(&last_release)).unwrap();
// Build nethermind
build_utils::check_command_output(build_result(&repo_dir), || {
format!("nethermind build failed using release {last_release}")
});
// Build nethermind a second time to enable Merge-related features.
// Not sure why this is necessary.
build_utils::check_command_output(build_result(&repo_dir), || {
format!("nethermind build failed using release {last_release}")
});
// Cleanup some disk space by removing nethermind's tests
let tests_dir = execution_clients_dir.join("nethermind/src/tests");
if let Err(e) = fs::remove_dir_all(tests_dir) {
eprintln!("Error while deleting folder: {}", e);
}
}
/*
* Nethermind-specific Implementation for GenericExecutionEngine
*/
#[derive(Clone)]
pub struct NethermindEngine;
impl NethermindEngine {
fn binary_path() -> PathBuf {
let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
manifest_dir
.join("execution_clients")
.join("nethermind")
.join("src")
.join("Nethermind")
.join("artifacts")
.join("bin")
.join("Nethermind.Runner")
.join("release")
.join("nethermind")
}
}
impl GenericExecutionEngine for NethermindEngine {
fn init_datadir() -> TempDir {
let datadir = TempDir::new().unwrap();
let genesis_json_path = datadir.path().join("genesis.json");
let mut file = fs::File::create(genesis_json_path).unwrap();
let json = nethermind_genesis_json();
serde_json::to_writer(&mut file, &json).unwrap();
datadir
}
fn start_client(
datadir: &TempDir,
http_port: u16,
http_auth_port: u16,
jwt_secret_path: PathBuf,
) -> Child {
let network_port = unused_tcp4_port().unwrap();
let genesis_json_path = datadir.path().join("genesis.json");
Command::new(Self::binary_path())
.arg("--datadir")
.arg(datadir.path().to_str().unwrap())
.arg("--config")
.arg("hive")
.arg("--Init.ChainSpecPath")
.arg(genesis_json_path.to_str().unwrap())
.arg("--Merge.TerminalTotalDifficulty")
.arg("0")
.arg("--JsonRpc.Enabled")
.arg("true")
.arg("--JsonRpc.EnabledModules")
.arg("net,eth,subscribe,web3,admin,personal")
.arg("--JsonRpc.Port")
.arg(http_port.to_string())
.arg("--JsonRpc.AdditionalRpcUrls")
.arg(format!(
"http://localhost:{}|http;ws|net;eth;subscribe;engine;web3;client",
http_auth_port
))
.arg("--Network.DiscoveryPort")
.arg(network_port.to_string())
.arg("--Network.P2PPort")
.arg(network_port.to_string())
.arg("--JsonRpc.JwtSecretFile")
.arg(jwt_secret_path.as_path().to_str().unwrap())
.stdout(build_utils::build_stdio())
.stderr(build_utils::build_stdio())
.spawn()
.expect("failed to start nethermind")
}
}