2022-07-18 01:51:36 +00:00
|
|
|
use ethers_providers::{Http, Provider};
|
2022-03-08 06:46:24 +00:00
|
|
|
use execution_layer::DEFAULT_JWT_FILE;
|
2022-02-17 21:47:06 +00:00
|
|
|
use sensitive_url::SensitiveUrl;
|
|
|
|
use std::path::PathBuf;
|
2022-03-24 00:04:48 +00:00
|
|
|
use std::process::Child;
|
2022-02-17 21:47:06 +00:00
|
|
|
use tempfile::TempDir;
|
2023-03-14 01:13:34 +00:00
|
|
|
use unused_port::unused_tcp4_port;
|
2022-02-17 21:47:06 +00:00
|
|
|
|
2022-07-18 01:51:36 +00:00
|
|
|
pub const KEYSTORE_PASSWORD: &str = "testpwd";
|
|
|
|
pub const ACCOUNT1: &str = "7b8C3a386C0eea54693fFB0DA17373ffC9228139";
|
|
|
|
pub const ACCOUNT2: &str = "dA2DD7560DB7e212B945fC72cEB54B7D8C886D77";
|
|
|
|
pub const PRIVATE_KEYS: [&str; 2] = [
|
|
|
|
"115fe42a60e5ef45f5490e599add1f03c73aeaca129c2c41451eca6cf8ff9e04",
|
|
|
|
"6a692e710077d9000be1326acbe32f777b403902ac8779b19eb1398b849c99c3",
|
|
|
|
];
|
|
|
|
|
2022-02-17 21:47:06 +00:00
|
|
|
/// Defined for each EE type (e.g., Geth, Nethermind, etc).
|
|
|
|
pub trait GenericExecutionEngine: Clone {
|
|
|
|
fn init_datadir() -> TempDir;
|
2022-03-08 06:46:24 +00:00
|
|
|
fn start_client(
|
|
|
|
datadir: &TempDir,
|
|
|
|
http_port: u16,
|
|
|
|
http_auth_port: u16,
|
|
|
|
jwt_secret_path: PathBuf,
|
|
|
|
) -> Child;
|
2022-02-17 21:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Holds handle to a running EE process, plus some other metadata.
|
|
|
|
pub struct ExecutionEngine<E> {
|
|
|
|
#[allow(dead_code)]
|
|
|
|
engine: E,
|
|
|
|
#[allow(dead_code)]
|
|
|
|
datadir: TempDir,
|
2022-07-18 01:51:36 +00:00
|
|
|
http_port: u16,
|
2022-03-03 02:10:57 +00:00
|
|
|
http_auth_port: u16,
|
2022-02-17 21:47:06 +00:00
|
|
|
child: Child,
|
2022-07-18 01:51:36 +00:00
|
|
|
pub provider: Provider<Http>,
|
2022-02-17 21:47:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<E> Drop for ExecutionEngine<E> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
// Ensure the EE process is killed on drop.
|
|
|
|
if let Err(e) = self.child.kill() {
|
|
|
|
eprintln!("failed to kill child: {:?}", e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<E: GenericExecutionEngine> ExecutionEngine<E> {
|
|
|
|
pub fn new(engine: E) -> Self {
|
|
|
|
let datadir = E::init_datadir();
|
2022-03-08 06:46:24 +00:00
|
|
|
let jwt_secret_path = datadir.path().join(DEFAULT_JWT_FILE);
|
2023-03-14 01:13:34 +00:00
|
|
|
let http_port = unused_tcp4_port().unwrap();
|
|
|
|
let http_auth_port = unused_tcp4_port().unwrap();
|
2022-03-08 06:46:24 +00:00
|
|
|
let child = E::start_client(&datadir, http_port, http_auth_port, jwt_secret_path);
|
2022-07-18 01:51:36 +00:00
|
|
|
let provider = Provider::<Http>::try_from(format!("http://localhost:{}", http_port))
|
|
|
|
.expect("failed to instantiate ethers provider");
|
2022-02-17 21:47:06 +00:00
|
|
|
Self {
|
|
|
|
engine,
|
|
|
|
datadir,
|
2022-07-18 01:51:36 +00:00
|
|
|
http_port,
|
2022-03-03 02:10:57 +00:00
|
|
|
http_auth_port,
|
2022-02-17 21:47:06 +00:00
|
|
|
child,
|
2022-07-18 01:51:36 +00:00
|
|
|
provider,
|
2022-02-17 21:47:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-08 06:46:24 +00:00
|
|
|
pub fn http_auth_url(&self) -> SensitiveUrl {
|
2022-03-03 02:10:57 +00:00
|
|
|
SensitiveUrl::parse(&format!("http://127.0.0.1:{}", self.http_auth_port)).unwrap()
|
|
|
|
}
|
2022-03-08 06:46:24 +00:00
|
|
|
|
2022-07-18 01:51:36 +00:00
|
|
|
pub fn http_url(&self) -> SensitiveUrl {
|
|
|
|
SensitiveUrl::parse(&format!("http://127.0.0.1:{}", self.http_port)).unwrap()
|
|
|
|
}
|
|
|
|
|
2022-03-08 06:46:24 +00:00
|
|
|
pub fn datadir(&self) -> PathBuf {
|
|
|
|
self.datadir.path().to_path_buf()
|
|
|
|
}
|
2022-02-17 21:47:06 +00:00
|
|
|
}
|