Add Nethermind integration tests (#3100)
## Proposed Changes Extend the current Geth merge integration tests to support Nethermind.
This commit is contained in:
parent
788b6af3c4
commit
3c675a9dfc
3
.github/workflows/test-suite.yml
vendored
3
.github/workflows/test-suite.yml
vendored
@ -213,6 +213,9 @@ jobs:
|
|||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.17'
|
go-version: '1.17'
|
||||||
|
- uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: '6.0.201'
|
||||||
- name: Get latest version of stable Rust
|
- name: Get latest version of stable Rust
|
||||||
run: rustup update stable
|
run: rustup update stable
|
||||||
- name: Run exec engine integration tests in release
|
- name: Run exec engine integration tests in release
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
use std::env;
|
|
||||||
use std::fs;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
const GETH_BRANCH: &str = "merge-kiln-v2";
|
|
||||||
const GETH_REPO_URL: &str = "https://github.com/MariusVanDerWijden/go-ethereum";
|
|
||||||
|
|
||||||
pub fn build() {
|
|
||||||
let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
|
|
||||||
let execution_clients_dir = manifest_dir.join("execution_clients");
|
|
||||||
|
|
||||||
if !execution_clients_dir.exists() {
|
|
||||||
fs::create_dir(&execution_clients_dir).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
build_geth(&execution_clients_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_geth(execution_clients_dir: &Path) {
|
|
||||||
let repo_dir = execution_clients_dir.join("go-ethereum");
|
|
||||||
|
|
||||||
if !repo_dir.exists() {
|
|
||||||
// Clone the repo
|
|
||||||
assert!(Command::new("git")
|
|
||||||
.arg("clone")
|
|
||||||
.arg(GETH_REPO_URL)
|
|
||||||
.current_dir(&execution_clients_dir)
|
|
||||||
.output()
|
|
||||||
.expect("failed to clone geth repo")
|
|
||||||
.status
|
|
||||||
.success());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checkout the correct branch
|
|
||||||
assert!(Command::new("git")
|
|
||||||
.arg("checkout")
|
|
||||||
.arg(GETH_BRANCH)
|
|
||||||
.current_dir(&repo_dir)
|
|
||||||
.output()
|
|
||||||
.expect("failed to checkout geth branch")
|
|
||||||
.status
|
|
||||||
.success());
|
|
||||||
|
|
||||||
// Update the branch
|
|
||||||
assert!(Command::new("git")
|
|
||||||
.arg("pull")
|
|
||||||
.current_dir(&repo_dir)
|
|
||||||
.output()
|
|
||||||
.expect("failed to update geth branch")
|
|
||||||
.status
|
|
||||||
.success());
|
|
||||||
|
|
||||||
// Build geth
|
|
||||||
let make_result = Command::new("make")
|
|
||||||
.arg("geth")
|
|
||||||
.current_dir(&repo_dir)
|
|
||||||
.output()
|
|
||||||
.expect("failed to make geth");
|
|
||||||
|
|
||||||
if !make_result.status.success() {
|
|
||||||
dbg!(String::from_utf8_lossy(&make_result.stdout));
|
|
||||||
dbg!(String::from_utf8_lossy(&make_result.stderr));
|
|
||||||
panic!("make failed");
|
|
||||||
}
|
|
||||||
}
|
|
73
testing/execution_engine_integration/src/build_utils.rs
Normal file
73
testing/execution_engine_integration/src/build_utils.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
use crate::SUPPRESS_LOGS;
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Command, Output, Stdio};
|
||||||
|
|
||||||
|
pub fn prepare_dir() -> PathBuf {
|
||||||
|
let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
|
||||||
|
let execution_clients_dir = manifest_dir.join("execution_clients");
|
||||||
|
|
||||||
|
if !execution_clients_dir.exists() {
|
||||||
|
fs::create_dir(&execution_clients_dir).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
execution_clients_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clone_repo(repo_dir: &Path, repo_url: &str) -> bool {
|
||||||
|
Command::new("git")
|
||||||
|
.arg("clone")
|
||||||
|
.arg(repo_url)
|
||||||
|
.arg("--recursive")
|
||||||
|
.current_dir(repo_dir)
|
||||||
|
.output()
|
||||||
|
.unwrap_or_else(|_| panic!("failed to clone repo at {}", repo_url))
|
||||||
|
.status
|
||||||
|
.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn checkout_branch(repo_dir: &Path, branch_name: &str) -> bool {
|
||||||
|
Command::new("git")
|
||||||
|
.arg("checkout")
|
||||||
|
.arg(branch_name)
|
||||||
|
.current_dir(repo_dir)
|
||||||
|
.output()
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
panic!(
|
||||||
|
"failed to checkout branch at {:?}/{}",
|
||||||
|
repo_dir, branch_name,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.status
|
||||||
|
.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_branch(repo_dir: &Path, branch_name: &str) -> bool {
|
||||||
|
Command::new("git")
|
||||||
|
.arg("pull")
|
||||||
|
.current_dir(repo_dir)
|
||||||
|
.output()
|
||||||
|
.unwrap_or_else(|_| panic!("failed to update branch at {:?}/{}", repo_dir, branch_name))
|
||||||
|
.status
|
||||||
|
.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_command_output(output: Output, failure_msg: &'static str) {
|
||||||
|
if !output.status.success() {
|
||||||
|
if !SUPPRESS_LOGS {
|
||||||
|
dbg!(String::from_utf8_lossy(&output.stdout));
|
||||||
|
dbg!(String::from_utf8_lossy(&output.stderr));
|
||||||
|
}
|
||||||
|
panic!("{}", failure_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds the stdout/stderr handler for commands which might output to the terminal.
|
||||||
|
pub fn build_stdio() -> Stdio {
|
||||||
|
if SUPPRESS_LOGS {
|
||||||
|
Stdio::null()
|
||||||
|
} else {
|
||||||
|
Stdio::inherit()
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
use crate::{genesis_json::geth_genesis_json, SUPPRESS_LOGS};
|
|
||||||
use execution_layer::DEFAULT_JWT_FILE;
|
use execution_layer::DEFAULT_JWT_FILE;
|
||||||
use sensitive_url::SensitiveUrl;
|
use sensitive_url::SensitiveUrl;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{Child, Command, Output, Stdio};
|
use std::process::Child;
|
||||||
use std::{env, fs::File};
|
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use unused_port::unused_tcp_port;
|
use unused_port::unused_tcp_port;
|
||||||
|
|
||||||
@ -66,93 +64,3 @@ impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|||||||
self.datadir.path().to_path_buf()
|
self.datadir.path().to_path_buf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Geth-specific Implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Geth;
|
|
||||||
|
|
||||||
impl Geth {
|
|
||||||
fn binary_path() -> PathBuf {
|
|
||||||
let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
|
|
||||||
manifest_dir
|
|
||||||
.join("execution_clients")
|
|
||||||
.join("go-ethereum")
|
|
||||||
.join("build")
|
|
||||||
.join("bin")
|
|
||||||
.join("geth")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GenericExecutionEngine for Geth {
|
|
||||||
fn init_datadir() -> TempDir {
|
|
||||||
let datadir = TempDir::new().unwrap();
|
|
||||||
|
|
||||||
let genesis_json_path = datadir.path().join("genesis.json");
|
|
||||||
let mut file = File::create(&genesis_json_path).unwrap();
|
|
||||||
let json = geth_genesis_json();
|
|
||||||
serde_json::to_writer(&mut file, &json).unwrap();
|
|
||||||
|
|
||||||
let output = Command::new(Self::binary_path())
|
|
||||||
.arg("--datadir")
|
|
||||||
.arg(datadir.path().to_str().unwrap())
|
|
||||||
.arg("init")
|
|
||||||
.arg(genesis_json_path.to_str().unwrap())
|
|
||||||
.output()
|
|
||||||
.expect("failed to init geth");
|
|
||||||
|
|
||||||
check_command_output(output, "geth init failed");
|
|
||||||
|
|
||||||
datadir
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_client(
|
|
||||||
datadir: &TempDir,
|
|
||||||
http_port: u16,
|
|
||||||
http_auth_port: u16,
|
|
||||||
jwt_secret_path: PathBuf,
|
|
||||||
) -> Child {
|
|
||||||
let network_port = unused_tcp_port().unwrap();
|
|
||||||
|
|
||||||
Command::new(Self::binary_path())
|
|
||||||
.arg("--datadir")
|
|
||||||
.arg(datadir.path().to_str().unwrap())
|
|
||||||
.arg("--http")
|
|
||||||
.arg("--http.api")
|
|
||||||
.arg("engine,eth")
|
|
||||||
.arg("--http.port")
|
|
||||||
.arg(http_port.to_string())
|
|
||||||
.arg("--authrpc.port")
|
|
||||||
.arg(http_auth_port.to_string())
|
|
||||||
.arg("--port")
|
|
||||||
.arg(network_port.to_string())
|
|
||||||
.arg("--authrpc.jwtsecret")
|
|
||||||
.arg(jwt_secret_path.as_path().to_str().unwrap())
|
|
||||||
.stdout(build_stdio())
|
|
||||||
.stderr(build_stdio())
|
|
||||||
.spawn()
|
|
||||||
.expect("failed to start beacon node")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_command_output(output: Output, failure_msg: &'static str) {
|
|
||||||
if !output.status.success() {
|
|
||||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
|
||||||
|
|
||||||
dbg!(stdout);
|
|
||||||
dbg!(stderr);
|
|
||||||
panic!("{}", failure_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the stdout/stderr handler for commands which might output to the terminal.
|
|
||||||
fn build_stdio() -> Stdio {
|
|
||||||
if SUPPRESS_LOGS {
|
|
||||||
Stdio::null()
|
|
||||||
} else {
|
|
||||||
Stdio::inherit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -40,3 +40,77 @@ pub fn geth_genesis_json() -> Value {
|
|||||||
"baseFeePerGas":"0x7"
|
"baseFeePerGas":"0x7"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sourced from:
|
||||||
|
///
|
||||||
|
/// https://github.com/NethermindEth/nethermind/blob/themerge_kintsugi/src/Nethermind/Chains/themerge_kintsugi_m2.json
|
||||||
|
pub fn nethermind_genesis_json() -> Value {
|
||||||
|
json!({
|
||||||
|
"name": "TheMerge_Devnet",
|
||||||
|
"engine": {
|
||||||
|
"clique": {
|
||||||
|
"params": {
|
||||||
|
"period": 5,
|
||||||
|
"epoch": 30000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x400",
|
||||||
|
"accountStartNonce": "0x0",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID": 1,
|
||||||
|
"eip150Transition": "0x0",
|
||||||
|
"eip155Transition": "0x0",
|
||||||
|
"eip158Transition": "0x0",
|
||||||
|
"eip160Transition": "0x0",
|
||||||
|
"eip161abcTransition": "0x0",
|
||||||
|
"eip161dTransition": "0x0",
|
||||||
|
"eip140Transition": "0x0",
|
||||||
|
"eip211Transition": "0x0",
|
||||||
|
"eip214Transition": "0x0",
|
||||||
|
"eip658Transition": "0x0",
|
||||||
|
"eip145Transition": "0x0",
|
||||||
|
"eip1014Transition": "0x0",
|
||||||
|
"eip1052Transition": "0x0",
|
||||||
|
"eip1283Transition": "0x0",
|
||||||
|
"eip1283DisableTransition": "0x0",
|
||||||
|
"eip152Transition": "0x0",
|
||||||
|
"eip1108Transition": "0x0",
|
||||||
|
"eip1344Transition": "0x0",
|
||||||
|
"eip1884Transition": "0x0",
|
||||||
|
"eip2028Transition": "0x0",
|
||||||
|
"eip2200Transition": "0x0",
|
||||||
|
"eip2565Transition": "0x0",
|
||||||
|
"eip2929Transition": "0x0",
|
||||||
|
"eip2930Transition": "0x0",
|
||||||
|
"eip1559Transition": "0x0",
|
||||||
|
"eip3198Transition": "0x0",
|
||||||
|
"eip3529Transition": "0x0",
|
||||||
|
"eip3541Transition": "0x0"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x42",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x000000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x0",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData":"0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"gasLimit":"0x1C9C380",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"baseFeePerGas":"0x7"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||||
|
"balance":"0x6d6172697573766477000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
110
testing/execution_engine_integration/src/geth.rs
Normal file
110
testing/execution_engine_integration/src/geth.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use crate::build_utils;
|
||||||
|
use crate::execution_engine::GenericExecutionEngine;
|
||||||
|
use crate::genesis_json::geth_genesis_json;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Child, Command, Output};
|
||||||
|
use std::{env, fs::File};
|
||||||
|
use tempfile::TempDir;
|
||||||
|
use unused_port::unused_tcp_port;
|
||||||
|
|
||||||
|
const GETH_BRANCH: &str = "merge-kiln-v2";
|
||||||
|
const GETH_REPO_URL: &str = "https://github.com/MariusVanDerWijden/go-ethereum";
|
||||||
|
|
||||||
|
pub fn build_result(repo_dir: &Path) -> Output {
|
||||||
|
Command::new("make")
|
||||||
|
.arg("geth")
|
||||||
|
.current_dir(&repo_dir)
|
||||||
|
.output()
|
||||||
|
.expect("failed to make geth")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(execution_clients_dir: &Path) {
|
||||||
|
let repo_dir = execution_clients_dir.join("go-ethereum");
|
||||||
|
|
||||||
|
if !repo_dir.exists() {
|
||||||
|
// Clone the repo
|
||||||
|
assert!(build_utils::clone_repo(
|
||||||
|
execution_clients_dir,
|
||||||
|
GETH_REPO_URL
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checkout the correct branch
|
||||||
|
assert!(build_utils::checkout_branch(&repo_dir, GETH_BRANCH));
|
||||||
|
|
||||||
|
// Update the branch
|
||||||
|
assert!(build_utils::update_branch(&repo_dir, GETH_BRANCH));
|
||||||
|
|
||||||
|
// Build geth
|
||||||
|
build_utils::check_command_output(build_result(&repo_dir), "make failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Geth-specific Implementation for GenericExecutionEngine
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GethEngine;
|
||||||
|
|
||||||
|
impl GethEngine {
|
||||||
|
fn binary_path() -> PathBuf {
|
||||||
|
let manifest_dir: PathBuf = env::var("CARGO_MANIFEST_DIR").unwrap().into();
|
||||||
|
manifest_dir
|
||||||
|
.join("execution_clients")
|
||||||
|
.join("go-ethereum")
|
||||||
|
.join("build")
|
||||||
|
.join("bin")
|
||||||
|
.join("geth")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenericExecutionEngine for GethEngine {
|
||||||
|
fn init_datadir() -> TempDir {
|
||||||
|
let datadir = TempDir::new().unwrap();
|
||||||
|
|
||||||
|
let genesis_json_path = datadir.path().join("genesis.json");
|
||||||
|
let mut file = File::create(&genesis_json_path).unwrap();
|
||||||
|
let json = geth_genesis_json();
|
||||||
|
serde_json::to_writer(&mut file, &json).unwrap();
|
||||||
|
|
||||||
|
let output = Command::new(Self::binary_path())
|
||||||
|
.arg("--datadir")
|
||||||
|
.arg(datadir.path().to_str().unwrap())
|
||||||
|
.arg("init")
|
||||||
|
.arg(genesis_json_path.to_str().unwrap())
|
||||||
|
.output()
|
||||||
|
.expect("failed to init geth");
|
||||||
|
|
||||||
|
build_utils::check_command_output(output, "geth init failed");
|
||||||
|
|
||||||
|
datadir
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_client(
|
||||||
|
datadir: &TempDir,
|
||||||
|
http_port: u16,
|
||||||
|
http_auth_port: u16,
|
||||||
|
jwt_secret_path: PathBuf,
|
||||||
|
) -> Child {
|
||||||
|
let network_port = unused_tcp_port().unwrap();
|
||||||
|
|
||||||
|
Command::new(Self::binary_path())
|
||||||
|
.arg("--datadir")
|
||||||
|
.arg(datadir.path().to_str().unwrap())
|
||||||
|
.arg("--http")
|
||||||
|
.arg("--http.api")
|
||||||
|
.arg("engine,eth")
|
||||||
|
.arg("--http.port")
|
||||||
|
.arg(http_port.to_string())
|
||||||
|
.arg("--authrpc.port")
|
||||||
|
.arg(http_auth_port.to_string())
|
||||||
|
.arg("--port")
|
||||||
|
.arg(network_port.to_string())
|
||||||
|
.arg("--authrpc.jwtsecret")
|
||||||
|
.arg(jwt_secret_path.as_path().to_str().unwrap())
|
||||||
|
.stdout(build_utils::build_stdio())
|
||||||
|
.stderr(build_utils::build_stdio())
|
||||||
|
.spawn()
|
||||||
|
.expect("failed to start geth")
|
||||||
|
}
|
||||||
|
}
|
@ -3,26 +3,37 @@
|
|||||||
/// It will first attempt to build any supported integration clients, then it will run tests.
|
/// It will first attempt to build any supported integration clients, then it will run tests.
|
||||||
///
|
///
|
||||||
/// A return code of `0` indicates the tests succeeded.
|
/// A return code of `0` indicates the tests succeeded.
|
||||||
mod build_geth;
|
mod build_utils;
|
||||||
mod execution_engine;
|
mod execution_engine;
|
||||||
mod genesis_json;
|
mod genesis_json;
|
||||||
|
mod geth;
|
||||||
|
mod nethermind;
|
||||||
mod test_rig;
|
mod test_rig;
|
||||||
|
|
||||||
use execution_engine::Geth;
|
use geth::GethEngine;
|
||||||
|
use nethermind::NethermindEngine;
|
||||||
use test_rig::TestRig;
|
use test_rig::TestRig;
|
||||||
|
|
||||||
/// Set to `false` to send logs to the console during tests. Logs are useful when debugging.
|
/// Set to `false` to send logs to the console during tests. Logs are useful when debugging.
|
||||||
const SUPPRESS_LOGS: bool = false;
|
const SUPPRESS_LOGS: bool = true;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
panic!("windows is not supported, only linux");
|
panic!("windows is not supported, only linux");
|
||||||
}
|
}
|
||||||
|
|
||||||
test_geth()
|
test_geth();
|
||||||
|
test_nethermind();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_geth() {
|
fn test_geth() {
|
||||||
build_geth::build();
|
let test_dir = build_utils::prepare_dir();
|
||||||
TestRig::new(Geth).perform_tests_blocking();
|
geth::build(&test_dir);
|
||||||
|
TestRig::new(GethEngine).perform_tests_blocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_nethermind() {
|
||||||
|
let test_dir = build_utils::prepare_dir();
|
||||||
|
nethermind::build(&test_dir);
|
||||||
|
TestRig::new(NethermindEngine).perform_tests_blocking();
|
||||||
}
|
}
|
||||||
|
117
testing/execution_engine_integration/src/nethermind.rs
Normal file
117
testing/execution_engine_integration/src/nethermind.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
use crate::build_utils;
|
||||||
|
use crate::execution_engine::GenericExecutionEngine;
|
||||||
|
use crate::genesis_json::nethermind_genesis_json;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::{Child, Command, Output};
|
||||||
|
use std::{env, fs::File};
|
||||||
|
use tempfile::TempDir;
|
||||||
|
use unused_port::unused_tcp_port;
|
||||||
|
|
||||||
|
const NETHERMIND_BRANCH: &str = "kiln";
|
||||||
|
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
|
||||||
|
assert!(build_utils::clone_repo(
|
||||||
|
execution_clients_dir,
|
||||||
|
NETHERMIND_REPO_URL
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checkout the correct branch
|
||||||
|
assert!(build_utils::checkout_branch(&repo_dir, NETHERMIND_BRANCH));
|
||||||
|
|
||||||
|
// Update the branch
|
||||||
|
assert!(build_utils::update_branch(&repo_dir, NETHERMIND_BRANCH));
|
||||||
|
|
||||||
|
// Build nethermind
|
||||||
|
build_utils::check_command_output(build_result(&repo_dir), "dotnet build failed");
|
||||||
|
|
||||||
|
// 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), "dotnet build failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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("Nethermind.Runner")
|
||||||
|
.join("bin")
|
||||||
|
.join("Release")
|
||||||
|
.join("net6.0")
|
||||||
|
.join("Nethermind.Runner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = 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_tcp_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("themerge_kiln_testvectors")
|
||||||
|
.arg("--Init.ChainSpecPath")
|
||||||
|
.arg(genesis_json_path.to_str().unwrap())
|
||||||
|
.arg("--JsonRpc.AdditionalRpcUrls")
|
||||||
|
.arg(format!("http://localhost:{}|http;ws|net;eth;subscribe;engine;web3;client|no-auth,http://localhost:{}|http;ws|net;eth;subscribe;engine;web3;client", http_port, http_auth_port))
|
||||||
|
.arg("--JsonRpc.EnabledModules")
|
||||||
|
.arg("net,eth,subscribe,web3,admin,engine")
|
||||||
|
.arg("--JsonRpc.Port")
|
||||||
|
.arg(http_port.to_string())
|
||||||
|
.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")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user